// epm/src/epm.el — El Package Manager entry point // // epm manages vessels: versioned El source packages backed by Gitea releases. // Each vessel corresponds to a Gitea repository under a shared org. Versions // are Gitea release tags; source archives are attached as release assets named // "-.tar.gz". // // Vessels are installed to ~/.el/packages///. // The installed registry lives at ~/.el/packages/installed.json. // // Usage: // epm publish # publish current project to registry // epm install # install all dependencies from manifest.el // epm install # install a specific vessel (latest) // epm install @ # install a specific vessel at a version // epm list # list installed vessels // epm info # show metadata for a vessel // epm info # show metadata for a specific version // epm update # update all installed vessels // epm update # update a specific vessel // epm check # check for available updates (no install) // // Configuration (environment): // EPM_GITEA_API — Gitea API base URL (default: https://git.neuralplatform.ai/api/v1) // EPM_REGISTRY_ORG — org hosting vessel repos (default: neuron-technologies) // EPM_TOKEN — Gitea personal access token (required for publish) // // Import order: manifest.el, registry.el, install.el, update.el must be // compiled first. This file imports all four and is the build entry point. import "manifest.el" import "registry.el" import "install.el" import "update.el" // ── Subcommand handlers ─────────────────────────────────────────────────────── // cmd_publish reads manifest.el from the current directory and publishes // the vessel to the Gitea registry as a release. fn cmd_publish() -> Void { let src: String = fs_read("manifest.el") if str_eq(src, "") { println("epm: no manifest.el found in current directory") exit(1) } let name: String = manifest_name(src) if str_eq(name, "") { println("epm: manifest.el has no 'vessel' or 'package' declaration") exit(1) } let version: String = manifest_version(src) if str_eq(version, "") { println("epm: manifest.el has no 'version' declaration") exit(1) } let description: String = manifest_description(src) let entry: String = manifest_entry(src) let deps_json: String = manifest_deps(src) println("epm: publishing " + name + " " + version + " ...") let release_id: String = registry_publish(name, version, description, entry, deps_json) if str_eq(release_id, "") { println("epm: publish failed") exit(1) } println("epm: published " + name + " " + version + " (release: " + release_id + ")") } // cmd_install_named installs a specific vessel by name (with optional version). // Expects: install or install @ fn cmd_install_named(spec: String) -> Void { // spec may be "el-auth" or "el-auth@0.1.0" let at: Int = str_index_of(spec, "@") let vname: String = spec let vver: String = "" if at > 0 { let vname = str_slice(spec, 0, at) let vver = str_slice(spec, at + 1, str_len(spec)) } println("epm: installing " + vname + " ...") let ok: Bool = install_vessel(vname, vver) if !ok { println("epm: install failed") exit(1) } // Notify about other available updates after a successful install let outdated: Int = check_updates() if outdated > 0 { println("") println(" note: " + native_int_to_str(outdated) + " vessel(s) have newer versions available — run 'epm update' to upgrade") } } // cmd_list prints all locally installed vessels. fn cmd_list() -> Void { let installed: String = read_installed() if str_eq(installed, "") { println("epm: no vessels installed") return } if str_eq(installed, "{}") { println("epm: no vessels installed") return } let inner_len: Int = str_len(installed) if inner_len < 2 { println("epm: no vessels installed") return } let body: String = str_slice(installed, 1, inner_len - 1) let body_trimmed: String = str_trim(body) if str_eq(body_trimmed, "") { println("epm: no vessels installed") return } println("epm: installed vessels:") println("") let pairs: [String] = str_split(body_trimmed, ",") let pair_count: Int = native_list_len(pairs) let i: Int = 0 while i < pair_count { let pair: String = str_trim(native_list_get(pairs, i)) let colon: Int = str_index_of(pair, ":") if colon > 0 { let raw_key: String = str_trim(str_slice(pair, 0, colon)) let raw_val: String = str_trim(str_slice(pair, colon + 1, str_len(pair))) let key_len: Int = str_len(raw_key) let val_len: Int = str_len(raw_val) let vname2: String = raw_key let vver2: String = raw_val if str_starts_with(raw_key, "\"") { let vname2 = str_slice(raw_key, 1, key_len - 1) } if str_starts_with(raw_val, "\"") { let vver2 = str_slice(raw_val, 1, val_len - 1) } println(" " + vname2 + " " + vver2) } let i = i + 1 } } // cmd_info prints detailed metadata for a specific vessel from the registry. // argv is the full args list; idx is the position of the vessel name. fn cmd_info(argv: [String], idx: Int) -> Void { let argc: Int = native_list_len(argv) if idx >= argc { println("epm: usage: epm info [version]") exit(1) } let vname: String = native_list_get(argv, idx) let vver: String = "" if idx + 1 < argc { let vver = native_list_get(argv, idx + 1) } let content: String = registry_find(vname, vver) if str_eq(content, "") { println("epm: vessel '" + vname + "' not found in registry") exit(1) } let name: String = json_get_string(content, "name") let ver: String = json_get_string(content, "version") let desc: String = json_get_string(content, "description") let dl_url: String = json_get_string(content, "download_url") println("name: " + name) println("version: " + ver) println("description: " + desc) println("download: " + dl_url) let local_ver: String = installed_version(name) if !str_eq(local_ver, "") { println("installed: " + local_ver) } else { println("installed: (not installed)") } } // ── Main ────────────────────────────────────────────────────────────────────── fn main() -> Void { let argv: [String] = args() let argc: Int = native_list_len(argv) // argv[0] is the program name; subcommand is argv[1] if argc < 2 { println("epm — El Package Manager") println("") println("usage:") println(" epm publish publish current project to registry") println(" epm install install all dependencies (from manifest.el)") println(" epm install install a specific vessel (latest version)") println(" epm install @ install a specific vessel at a version") println(" epm list list installed vessels") println(" epm info show vessel metadata from registry") println(" epm info show metadata for a specific version") println(" epm update update all installed vessels") println(" epm update update a specific vessel") println(" epm check check for available updates (no install)") println("") println("configuration:") println(" EPM_GITEA_API Gitea API base URL (default: https://git.neuralplatform.ai/api/v1)") println(" EPM_REGISTRY_ORG org hosting vessel repos (default: neuron-technologies)") println(" EPM_TOKEN Gitea personal access token (required for publish)") exit(0) } let sub: String = native_list_get(argv, 1) if str_eq(sub, "publish") { cmd_publish() return } if str_eq(sub, "install") { if argc >= 3 { let spec: String = native_list_get(argv, 2) cmd_install_named(spec) } else { cmd_install() // Notify about other available updates after a successful install let outdated: Int = check_updates() if outdated > 0 { println("") println(" note: " + native_int_to_str(outdated) + " vessel(s) have newer versions available — run 'epm update' to upgrade") } } return } if str_eq(sub, "list") { cmd_list() return } if str_eq(sub, "info") { cmd_info(argv, 2) return } if str_eq(sub, "update") { if argc >= 3 { let vessel_arg: String = native_list_get(argv, 2) cmd_update(vessel_arg) } else { cmd_update("") } return } if str_eq(sub, "check") { println("epm: checking for updates ...") let outdated: Int = check_updates() if outdated == 0 { println("epm: all installed vessels are up to date") } else { println("") println("epm: " + native_int_to_str(outdated) + " vessel(s) have newer versions available — run 'epm update' to upgrade") } return } println("epm: unknown subcommand '" + sub + "'") println("run 'epm' with no arguments for usage") exit(1) }