Răsfoiți Sursa

feat: configurable repo root via the usm-web config section (argument > env > config > default)

clanker 1 săptămână în urmă
părinte
comite
a531602513
3 a modificat fișierele cu 38 adăugiri și 9 ștergeri
  1. 4 2
      README.md
  2. 30 5
      src/UsmWebConfig.vala
  3. 4 2
      src/main.vala

+ 4 - 2
README.md

@@ -29,6 +29,7 @@ carries the static Statum keys plus an optional `"usm-web"` section:
 {
   "statum": { "…": "static keys from spry keys / statum-genkeys" },
   "usm-web": {
+    "repo": "/repo",
     "installer": { "path": "install-usm.sh" },
     "base_url": "https://repo.example.com/",
     "name": "My repository"
@@ -38,6 +39,7 @@ carries the static Statum keys plus an optional `"usm-web"` section:
 
 | Key | Meaning |
 |---|---|
+| `repo` | USM repository root (the directory holding the `.usmr` and `public/`); relative paths resolve against the config file's directory |
 | `installer.url` | External installer location; the homepage links out and shows `curl -fsSL <url> \| sh` |
 | `installer.path` | Installer script this app serves at `/install-usm.sh`; relative paths resolve against the config file's directory |
 | `base_url` | Optional override of the request-derived repository base (normalised to a trailing slash) |
@@ -48,8 +50,8 @@ when the block should appear) is a configuration error. Omit the section
 entirely to hide the install-USM card.
 
 The repository root is selected by (in order) the `--repo <dir>` argument,
-the `USM_WEB_REPO_DIR` environment variable, or the `/repo` default, and is
-expected to look like a published repository:
+the `USM_WEB_REPO_DIR` environment variable, the config's `repo` key, or the
+`/repo` default, and is expected to look like a published repository:
 
 ```
 /repo

+ 30 - 5
src/UsmWebConfig.vala

@@ -39,6 +39,7 @@ namespace UsmWeb {
      * ```json
      * {
      *   "usm-web": {
+     *     "repo": "/repo",
      *     "installer": { "path": "install-usm.sh" },
      *     "base_url": "https://repo.example.com/",
      *     "name": "My repository"
@@ -46,6 +47,12 @@ namespace UsmWeb {
      * }
      * ```
      *
+     * `repo` is the USM repository root (the directory containing the
+     * `.usmr` and `public/`); a relative value resolves against the
+     * directory of the config file that declared it. It applies only when
+     * neither the `--repo` argument nor `USM_WEB_REPO_DIR` is given
+     * (precedence: argument > environment > config > `/repo`).
+     *
      * `installer` carries exactly one of `url` (an external location the
      * homepage links to) or `path` (a file the app serves itself at
      * {@link InstallerScriptEndpoint}); a relative `path` resolves against
@@ -71,20 +78,23 @@ namespace UsmWeb {
         public string? display_name { get; private set; }
 
         /** The USM repository root (contains the `.usmr` and `public/`). */
-        public string repo_dir { get; private set; }
+        public string repo_dir { get; private set; default = "/repo"; }
 
         /**
          * Reads the section from the loaded {@link WebConfig}, re-parsing the
          * contributing files with json-glib so the nested `installer` object
-         * is readable and a relative `path` resolves against the config file
-         * that declared it (later files win, mirroring WebConfig layering).
+         * is readable and a relative `path`/`repo` resolves against the
+         * config file that declared it (later files win, mirroring WebConfig
+         * layering). {@link repo_dir} wins when given; otherwise the config's
+         * `repo` applies, falling back to `/repo`.
          */
-        public static UsmWebConfig load(WebConfig config, string repo_dir) throws Error {
+        public static UsmWebConfig load(WebConfig config, string? repo_dir = null) throws Error {
             var result = new UsmWebConfig();
-            result.repo_dir = repo_dir;
 
             string? declared_path = null;
             string declaring_dir = Environment.get_current_dir();
+            string? declared_repo = null;
+            string repo_declaring_dir = declaring_dir;
             foreach (var file in config.get_loaded_files()) {
                 var section = read_section(file);
                 if (section == null) {
@@ -99,6 +109,12 @@ namespace UsmWeb {
                     result.base_url = normalise_base((!)base_url);
                 }
 
+                var repo = read_string_member(obj, "repo");
+                if (repo != null) {
+                    declared_repo = repo;
+                    repo_declaring_dir = GLib.Path.get_dirname((!)file);
+                }
+
                 result.installer_url = read_string_member(obj, "installer", "url") ?? result.installer_url;
                 declared_path = read_string_member(obj, "installer", "path") ?? declared_path;
                 if (declared_path != null) {
@@ -106,6 +122,15 @@ namespace UsmWeb {
                 }
             }
 
+            if (repo_dir != null) {
+                result.repo_dir = (!)repo_dir;
+            }
+            else if (declared_repo != null) {
+                var repo = (!)declared_repo;
+                result.repo_dir = GLib.Path.is_absolute(repo)
+                    ? repo : GLib.Path.build_filename(repo_declaring_dir, repo);
+            }
+
             if (result.installer_url != null && declared_path != null) {
                 throw new UsmWebError.INVALID_CONFIGURATION(
                     "usm-web.installer: provide exactly one of \"url\" or \"path\", not both");

+ 4 - 2
src/main.vala

@@ -20,7 +20,7 @@ int main(string[] args) {
         }
     }
 
-    repo_dir = repo_dir ?? Environment.get_variable("USM_WEB_REPO_DIR") ?? "/repo";
+    repo_dir = repo_dir ?? Environment.get_variable("USM_WEB_REPO_DIR");
 
     try {
         var application = new WebApplication(port);
@@ -28,7 +28,9 @@ int main(string[] args) {
         application.add_module<StatumModule>();
 
         var web_config = application.container.create_transient_scope().resolve<WebConfig>();
-        var config = UsmWebConfig.load(web_config, (!)repo_dir);
+        // Precedence: --repo argument > USM_WEB_REPO_DIR > the "usm-web"
+        // section's "repo" key (UsmWebConfig.load) > /repo
+        var config = UsmWebConfig.load(web_config, repo_dir);
         application.add_singleton<UsmWebConfig>(() => config);
         application.add_singleton<RepositoryService>();