From 68718c951cc8e97f5a8289b68a8595c9f86030d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= <felix@piedallu.me>
Date: Sun, 28 Jan 2024 20:37:19 +0100
Subject: [PATCH 1/2] Rework a bit default_install_args.py, make a proper
 python script, use typing, split into 2 functions

---
 lib/default_install_args.py | 87 ++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 34 deletions(-)
 mode change 100644 => 100755 lib/default_install_args.py

diff --git a/lib/default_install_args.py b/lib/default_install_args.py
old mode 100644
new mode 100755
index 5f83373..84daf69
--- a/lib/default_install_args.py
+++ b/lib/default_install_args.py
@@ -1,56 +1,75 @@
 #!/usr/bin/python3
 
-import sys
+import argparse
 import json
+from pathlib import Path
+
 import toml
 
-def get_default_values_for_questions(manifest, raise_if_no_default=True):
 
+def get_default_value(app_name: str, name: str, question: dict, raise_if_no_default: bool = True) -> str:
     base_default_value_per_arg_type = {
         ("domain", "domain"): "domain.tld",
-        ("path", "path"): "/" + manifest["id"],
+        ("path", "path"): "/" + app_name,
         ("user", "admin"): "package_checker",
         ("group", "init_main_permission"): "visitors",
         ("group", "init_admin_permission"): "admins",
         ("password", "password"): "MySuperComplexPassword"
     }
 
+    type_and_name = (question["type"], name)
+
+    if value := base_default_value_per_arg_type.get(type_and_name):
+        return value
+
+    if value := question.get("default"):
+        if isinstance(value, bool):
+            # Convert bool to "0", "1"
+            value = str(int(value))
+        return value
+
+    if question["type"] == "boolean":
+        return "1"
+
+    if question["type"] == "password":
+        return "SomeSuperStrongPassword1234"
+
+    if choices := question.get("choices"):
+        return list(choices)[0]
+
+    if raise_if_no_default:
+        raise RuntimeError("No default value could be computed for arg " + name)
+    return ""
+
+
+def get_default_values_for_questions(manifest: dict, raise_if_no_default=True) -> dict[str, str]:
+    app_name = manifest["id"]
+
     if manifest.get("packaging_format", 1) <= 1:
-        questions = {q["name"]:q for q in manifest["arguments"]["install"]}
+        questions = {q["name"]: q for q in manifest["arguments"]["install"]}
     else:
         questions = manifest["install"]
 
-    for name, question in questions.items():
-        type_and_name = (question["type"], name)
-        base_default = base_default_value_per_arg_type.get(type_and_name)
-        if base_default:
-            yield (name, base_default)
-        elif question.get("default"):
-            if isinstance(question.get("default"), bool):
-                yield (name, str(int(question.get("default"))))
-            else:
-                yield (name, str(question.get("default")))
-        elif question["type"] == "boolean":
-            yield (name, "1")
-        elif question["type"] == "password":
-            yield (name, "SomeSuperStrongPassword1234")
-        elif question.get("choices"):
-            if isinstance(question["choices"], list):
-                choices = question["choices"]
-            else:
-                choices = list(question["choices"].keys())
-            yield (name, choices[0])
-        else:
-            if raise_if_no_default:
-                raise Exception("No default value could be computed for arg " + name)
+    args = {
+        name: get_default_value(app_name, name, question, raise_if_no_default)
+        for name, question in questions.items()
+    }
+    return args
 
-if __name__ == '__main__':
-    manifest_path = sys.argv[1:][0]
 
-    if manifest_path.endswith(".json"):
-        manifest = json.load(open(manifest_path, "r"))
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument("manifest_path", type=Path, help="Path to the app directory")
+    args = parser.parse_args()
+
+    if args.manifest_path.name.endswith(".json"):
+        manifest = json.load(args.manifest_path.open())
     else:
-        manifest = toml.load(open(manifest_path, "r"))
+        manifest = toml.load(args.manifest_path.open())
 
-    querystring = '&'.join([k + "=" + v for k, v in get_default_values_for_questions(manifest)])
-    print(querystring)
+    query_string = "&".join([f"{name}={value}" for name, value in get_default_values_for_questions(manifest).items()])
+    print(query_string)
+
+
+if __name__ == "__main__":
+    main()

From a2e27999e61c646b5cab25cd95f9b75f5c62e9a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= <felix@piedallu.me>
Date: Sun, 28 Jan 2024 20:43:41 +0100
Subject: [PATCH 2/2] parse_tests_toml: make a proper python script (chmod,
 shebang, argparse), use a bit typing

---
 lib/parse_tests_toml.py | 61 ++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/lib/parse_tests_toml.py b/lib/parse_tests_toml.py
index d2347c6..8522a63 100644
--- a/lib/parse_tests_toml.py
+++ b/lib/parse_tests_toml.py
@@ -1,11 +1,19 @@
-import sys
-import os
-import toml
+#!/usr/bin/env python3
+
+from typing import Any
+import argparse
 import copy
 import json
+import os
+import sys
+from pathlib import Path
+
+import toml
+
+from default_install_args import get_default_values_for_questions
 
 
-def generate_test_list_base(test_manifest, default_install_args, is_webapp, is_multi_instance):
+def generate_test_list_base(test_manifest: dict, default_install_args: dict, is_webapp: bool, is_multi_instance: bool):
 
     assert test_manifest["test_format"] == 1.0, "Only test_format 1.0 is supported for now"
 
@@ -128,42 +136,39 @@ def dump_for_package_check(test_list, package_check_tests_dir):
             json.dump(J, open(package_check_tests_dir + f"/{test_file_id}.json", "w"))
 
 
-def build_test_list(basedir):
+def build_test_list(basedir: Path) -> dict[str, dict[str, Any]]:
+    test_manifest = toml.load((basedir / "tests.toml").open("r"))
 
-    test_manifest = toml.load(open(basedir + "/tests.toml", "r"))
-
-    if os.path.exists(basedir + "/manifest.json"):
-        manifest = json.load(open(basedir + "/manifest.json", "r"))
+    if (basedir / "manifest.json").exists():
+        manifest = json.load((basedir / "manifest.json").open("r"))
         is_multi_instance = manifest.get("multi_instance") is True
     else:
-        manifest = toml.load(open(basedir + "/manifest.toml", "r"))
+        manifest = json.load((basedir / "manifest.toml").open("r"))
         is_multi_instance = manifest.get("integration").get("multi_instance") is True
 
-    is_webapp = os.system(f"grep -q '^ynh_add_nginx_config' '{basedir}/scripts/install'") == 0
+    is_webapp = os.system(f"grep -q '^ynh_add_nginx_config' '{str(basedir)}/scripts/install'") == 0
 
-    from default_install_args import get_default_values_for_questions
-    default_install_args = {k: v for k, v in get_default_values_for_questions(manifest, raise_if_no_default=False)}
+    default_install_args = get_default_values_for_questions(manifest, raise_if_no_default=False)
 
     base_test_list = list(generate_test_list_base(test_manifest, default_install_args, is_webapp, is_multi_instance))
-    test_list = {test_suite_id: tests for test_suite_id, tests in filter_test_list(test_manifest, base_test_list)}
+    test_list = dict(filter_test_list(test_manifest, base_test_list))
 
     return test_list
 
-if __name__ == '__main__':
 
-    test_list = build_test_list(sys.argv[1])
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument("app", type=Path, help="Path to the app directory")
+    parser.add_argument("-d", "--dump-to", type=Path, required=False, help="Dump the result to the package check directory")
+    args = parser.parse_args()
 
-    if len(sys.argv) <= 1 or sys.argv[1] in ["-h", "--help"]:
-        print("""Usage:
+    test_list = build_test_list(args.app)
 
-Display generated test list:
-    python3 parse_tests_toml.py /path/to/app/folder/ | jq
-
-Dump the list (only relevant from inside package_checker's code ...)
-    python3 parse_tests_toml.py /path/to/app/folder/ /tmp/dir/for/package/check/....
-
-""")
-    elif len(sys.argv) == 2:
-        print(json.dumps(test_list, indent=4))
+    if args.dump_to:
+        dump_for_package_check(test_list, args.dump_to)
     else:
-        dump_for_package_check(test_list, sys.argv[2])
+        print(json.dumps(test_list, indent=4))
+
+
+if __name__ == "__main__":
+    main()