|

cli: cmd_profile dispatch for list/install/diff/remove/show; update print_usage

Author: Chris Tusa <chris.tusa@leafscale.com>
Date: May 09, 2026 00:37
Node: 1e6f78b99de6e69f8e09456af720837d34907c83
Branch: default

Changed files:

Diff

diff -r 75833286fdd0 -r 1e6f78b99de6 src/cli.reef
--- a/src/cli.reef	Sat May 09 00:34:55 2026 +0000
+++ b/src/cli.reef	Sat May 09 00:37:08 2026 +0000
@@ -12,6 +12,7 @@
 import sys.process as p
 import config
 import incus
+import profile
 import setup
 import sync
 import paths
@@ -19,6 +20,7 @@
 
 export
     fn cmd_new(argv: [string]): int
+    fn cmd_profile(argv: [string]): int
     fn cmd_setup(argv: [string]): int
     fn cmd_sync(argv: [string]): int
     fn cmd_list(argv: [string]): int
@@ -775,6 +777,154 @@
     return setup.cmd_setup(argv)
 end cmd_setup
 
+fn cmd_profile(argv: [string]): int
+    if argv.length() == 0
+        console.printErr("repoman: error: 'profile' requires a subcommand: list | install | diff | remove | show")
+        return 2
+    end if
+    let verb: string = argv[0]
+    // Slice argv[1..] for the verb's own parser
+    let n: int = argv.length()
+    mut rest: [string] = new [string](n - 1)
+    mut i: int = 0
+    while i < n - 1
+        rest[i] = argv[i + 1]
+        i = i + 1
+    end while
+
+    if verb == "list"
+        return cmd_profile_list(rest)
+    end if
+    if verb == "install"
+        return cmd_profile_install(rest)
+    end if
+    if verb == "diff"
+        return cmd_profile_diff(rest)
+    end if
+    if verb == "remove"
+        return cmd_profile_remove(rest)
+    end if
+    if verb == "show"
+        return cmd_profile_show(rest)
+    end if
+    console.printErr("repoman: error: unknown profile subcommand: " + verb)
+    return 2
+end cmd_profile
+
+fn build_host_facts(): profile.HostFacts
+    let home: string = env.get_env_or("HOME", "")
+    let user: string = env.get_env_or("USER", "")
+    let reg_r = config.load_or_init(home)
+    mut lan_ip: string = ""
+    if rg.is_ok(reg_r)
+        lan_ip = rg.unwrap_ok(reg_r).host.lan_ip
+    end if
+    return profile.HostFacts {
+        lan_ip: lan_ip,
+        user:   user,
+        home:   home
+    }
+end build_host_facts
+
+fn cmd_profile_list(argv: [string]): int
+    let home: string = env.get_env_or("HOME", "")
+    let entries = profile.list_all(home)
+    println("NAME              SOURCE                  INSTALLED")
+    let n: int = entries.length()
+    mut i: int = 0
+    while i < n
+        let e = entries[i]
+        mut inst: string = "no"
+        if e.installed
+            inst = "yes"
+        end if
+        println(e.name + "    " + e.source + "    " + inst)
+        i = i + 1
+    end while
+    return 0
+end cmd_profile_list
+
+fn cmd_profile_install(argv: [string]): int
+    let host = build_host_facts()
+    let home: string = host.home
+    if argv.length() == 0
+        console.printErr("repoman: error: 'profile install' requires <name> or --all")
+        return 2
+    end if
+    if argv[0] == "--all"
+        let entries = profile.list_all(home)
+        let n: int = entries.length()
+        mut i: int = 0
+        mut errs: int = 0
+        while i < n
+            let e = entries[i]
+            println("==> install " + e.name + " (source: " + e.source + ")")
+            let r = profile.install(e.name, home, host)
+            if rg.is_err(r)
+                console.printErr("  error: " + rg.unwrap_err(r))
+                errs = errs + 1
+            end if
+            i = i + 1
+        end while
+        if errs > 0
+            return 1
+        end if
+        return 0
+    end if
+    let name: string = argv[0]
+    let r = profile.install(name, home, host)
+    if rg.is_err(r)
+        console.printErr("repoman: error: " + rg.unwrap_err(r))
+        return 1
+    end if
+    println("==> installed " + name)
+    return 0
+end cmd_profile_install
+
+fn cmd_profile_diff(argv: [string]): int
+    if argv.length() == 0
+        console.printErr("repoman: error: 'profile diff' requires <name>")
+        return 2
+    end if
+    let host = build_host_facts()
+    let r = profile.diff(argv[0], host.home, host)
+    if rg.is_err(r)
+        console.printErr("repoman: error: " + rg.unwrap_err(r))
+        return 3
+    end if
+    println(rg.unwrap_ok(r))
+    return 0
+end cmd_profile_diff
+
+fn cmd_profile_remove(argv: [string]): int
+    if argv.length() == 0
+        console.printErr("repoman: error: 'profile remove' requires <name>")
+        return 2
+    end if
+    let r = profile.remove_profile(argv[0])
+    if rg.is_err(r)
+        console.printErr("repoman: error: " + rg.unwrap_err(r))
+        return 1
+    end if
+    println("==> removed " + argv[0] + " from incus")
+    return 0
+end cmd_profile_remove
+
+fn cmd_profile_show(argv: [string]): int
+    if argv.length() == 0
+        console.printErr("repoman: error: 'profile show' requires <name>")
+        return 2
+    end if
+    let host = build_host_facts()
+    let r = profile.show(argv[0], host.home, host)
+    if rg.is_err(r)
+        console.printErr("repoman: error: " + rg.unwrap_err(r))
+        return 3
+    end if
+    println(rg.unwrap_ok(r))
+    return 0
+end cmd_profile_show
+
 fn version_string(): string
     return "repoman 0.3.0"
 end version_string
@@ -789,6 +939,9 @@
     console.printErr("  new <name> [--repo <dirname>] [--image <image>]")
     console.printErr("      Launch a container in the 'repoman' Incus project; bind ~/repos/<dirname>.")
     console.printErr("")
+    console.printErr("  profile {list|install|diff|remove|show} [<name>] [--all]")
+    console.printErr("      Manage Incus profiles from the repoman library.")
+    console.printErr("")
     console.printErr("  sync [name] [--no-delete] [--dry-run]")
     console.printErr("      Mirror local repos to NFS backup (rsync --delete by default).")
     console.printErr("")
@@ -841,6 +994,9 @@
     if sub == "new"
         return cmd_new(rest)
     end if
+    if sub == "profile"
+        return cmd_profile(rest)
+    end if
     if sub == "remove"
         return cmd_remove(rest)
     end if