Skip to content

feat(cli): call namespace entry points with -m - #1100

Merged
mparrett merged 5 commits into
mainfrom
codex/cli-main-1096
Oct 28, 2026
Merged

mparrett merged 5 commits into
mainfrom
codex/cli-main-1096

Conversation

@mparrett

@mparrett mparrett commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1096. Replaces #1097 with the branch hosted directly in nooga/let-go.

lg can load a namespace's file but cannot call its -main from the command line. Programs need a launcher or manual -e call, which also prints the return value and treats the first program argument as a script.

Adds lg [-source-paths …] -m ns [args…], with --main as an alias and ns/fn to 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.

-m is terminal, so lg options precede it and flag-shaped arguments or a literal -- afterward belong to the program. An -e expression runs first and keeps its usual printed result; initialization failure prevents the entry call. -r retains the post-execution REPL behavior. Combining -m with -c, -b, or -w is 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-id still 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:

  • Full make quality before/after runs (1,053 tracked files, fixed --since 2026-04-29): erosion 0.585 → 0.584, callables over CC 10 535 → 534.
  • Quality-driven refactor: runMain CC 73 → 55 (upstream base: 58); parseRunFlags 13 → 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.
  • PR-delta report over 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.
  • CLI main/argument regressions and CLI/resolver unit tests pass.
  • Storage regression cases fail before the fix and pass afterward: underscore .clj, nested .cljc, literal hyphens, competing extension/name candidates, load-time storage reads, isolation, and explicit IDs.
  • Bootstrap CLI/resolver tests and main-entry regressions pass.
  • make generate and make check-generated pass, including Go-lowered runtime compilation and native dispatch.
  • Repository commit and pre-push checks run before publication; formatting, test locations, scoped comment review, and manifest freshness are checked.

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.

mparrett and others added 4 commits October 24, 2026 10:41
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>
@mparrett
mparrett requested review from nnunley and nooga October 25, 2026 15:56

@nnunley nnunley left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nesting looks a little deep in the code. arethe erosion metrics running? Otherwise, looks like it's ok.

Comment thread pkg/cli/cli.go Outdated
@mparrett

Copy link
Copy Markdown
Collaborator Author

@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.

@mparrett
mparrett requested a review from nnunley October 26, 2026 18:02
@mparrett

Copy link
Copy Markdown
Collaborator Author

cc: @dharmatech

@dharmatech

Copy link
Copy Markdown
Contributor

cc: @dharmatech

Love it!
Thanks guys! 🫡

CC: @gavr123456789

@nooga nooga left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@mparrett
mparrett merged commit 829738d into main Oct 28, 2026
21 checks passed
@mparrett
mparrett deleted the codex/cli-main-1096 branch October 28, 2026 05:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI: add -m ns to call a namespace's -main, as clojure -m and bb -m do

4 participants