Repository navigation
feat(cli): call namespace entry points with -m - #1100
Conversation
With -m there is no script argument, so the storage id fell through to the executable's basename: every -m program shared the "lg" store with the REPL, and a program launched as `lg app.lg` lost its data when launched as `lg -m app`. Derive the id from the namespace's file path instead, so `lg -m app.core` uses the same store as `lg src/app/core.lg`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
runNamespaceMain passed rt.InvokeProgramEntry's errors through, so users saw "InvokeProgramEntry: app/-main not found". Look up and check the entry in the namespace RequireNS returns and report "-m: app/-main not found". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nnunley
left a comment
There was a problem hiding this comment.
The nesting looks a little deep in the code. arethe erosion metrics running? Otherwise, looks like it's ok.
|
@nnunley Thanks for the review. Ran the full erosion/quality report and refactored the nested CLI logic into helpers in 4370bfe. runMain complexity dropped from 73 to 55 (upstream: 58), the flag parser from 13 to 10, and full-project erosion from 0.585 to 0.584. Regression tests and all pre-push checks passed; the PR description has the measurements. |
|
cc: @dharmatech |
Love it! CC: @gavr123456789 |
nooga
left a comment
There was a problem hiding this comment.
Approving. Read the CLI diff: parseRunFlags makes -m terminal so flags and -- after it reach the program, validateMainMode rejects -c/-b/-w, and SourcePath is shared with the loader so storage id and namespace lookup agree. nnunley's nesting nit is addressed. As project owner I'm fine with the new -m/--main flag.
Fixes #1096. Replaces #1097 with the branch hosted directly in
nooga/let-go.lgcan load a namespace's file but cannot call its-mainfrom the command line. Programs need a launcher or manual-ecall, which also prints the return value and treats the first program argument as a script.Adds
lg [-source-paths …] -m ns [args…], with--mainas an alias andns/fnto select another callable var. The namespace is required, all following arguments are passed unchanged and bound to*command-line-args*before initialization or loading, and the entry's return value is discarded. Loading and invocation errors exit nonzero; missing or non-callable entries report the CLI target.-mis terminal, so lg options precede it and flag-shaped arguments or a literal--afterward belong to the program. An-eexpression runs first and keeps its usual printed result; initialization failure prevents the entry call.-rretains the post-execution REPL behavior. Combining-mwith-c,-b, or-wis a usage error.Persistent storage uses the selected source filename, matching script mode even when namespace hyphens map to filename underscores. The CLI and loader share the same source-path search, preserving root, extension, and filename precedence. Selection does not execute source, so storage is installed before namespace initialization. Explicit
-storage-idstill wins; namespaces without a filesystem source retain the namespace-derived fallback.Compiler paths: the entry uses the existing namespace loader and VM execution context. Source selection is shared by the default, bootstrap, and Go-lowered builds; compiler/IR semantics are unchanged. Regenerated manifest and sums accompany the resolver refactor.
Validation:
make qualitybefore/after runs (1,053 tracked files, fixed--since 2026-04-29): erosion 0.585 → 0.584, callables over CC 10 535 → 534.runMainCC 73 → 55 (upstream base: 58);parseRunFlags13 → 10. Main-option validation, storage-source selection, and program execution are separate helpers; all new helpers are at CC 10 or below, and main-entry failure handling uses early returns.pkg/cli,pkg/resolver, and the new main-flag tests: erosion 0.581 → 0.514 after the refactor (upstream baseline for that same scope: 0.533). Scoped aggregate debt 0.405 → 0.376; remaining findings include pre-existing complexity and history-derived terms, not a claim that the whole corpus is clean..clj, nested.cljc, literal hyphens, competing extension/name candidates, load-time storage reads, isolation, and explicit IDs.make generateandmake check-generatedpass, including Go-lowered runtime compilation and native dispatch.Local lint limitation: the pinned linter cannot read local Go 1.27.3's export-data format (
internal/goarch, version 5 versus supported version 4). Only that commit hook is skipped; CI remains the lint check.