std/cli: optional, repeatable and pass-through arguments (first step of #124) #492

Closed
opened 2026-10-26 01:34:39 +00:00 by orion · 6 comments
Collaborator

Context

torb cannot move to std/cli (#124) while the package cannot say what the compiler's commands say. Read off compiler/src/main.trb and the option readers it calls, three things are missing:

  • an optional option: --output <file>, --target, --template may be left out and have no default (today an option without default is required);
  • a repeatable option: torb test --filter a --filter b, torb repl --environment p --environment q, --modules;
  • pass-through: in torb run [path] [...] everything behind the path is the program's own Process.arguments(), flags included (torb run tool.trb --emit-c hands --emit-c on).

Source

  • CLI.md slice 2 (the first step of #124)
  • std/cli/src/command.trb (CommandBuilder, Command.parse, Command.settle), std/cli/src/input.trb

Design (decided by the loop, internal API shape)

  • option<T>(name, help:, default:) keeps its meaning. New CommandBuilder.optional<T>(name, help:): may be left out, read as input.optional<T>("name"): T? (None if absent); help row (optional).
  • New CommandBuilder.repeatable<T>(name, help:): may be given any number of times (also --name=v), read as input.repeated<T>("name"): List<T> in the order of the line, empty if absent; every value is checked like an option's.
  • arguments(name, help:, passthrough: Bool = false): with passthrough the first positional argument ends option parsing, and it and everything behind it (flags too) go into the list; --help/-h are still honoured before that point only.
  • Errors keep using CliError; no new case is needed (a missing value / invalid value reuse MissingValue, InvalidValue).

Acceptance criteria

  • optional, repeatable and passthrough as above, in std/cli/src/command.trb and input.trb, exported from std/cli.
  • Tests in std/cli/tests/cli.test.trb with argument lists: absent / present / = form / invalid value for optional and repeatable; order of repeated values; pass-through keeps --emit-c-style tokens behind the first positional, -- still works, --help in front of the path still wins.
  • Help text shows (optional), (repeatable) and the pass-through arguments; covered by a test.
  • docs/standard-library/cli.md documents the three; skills/ regenerated where the docs gate asks.

Seed

Does not touch the seed: std source only, no syntax, no native, no driver flag, no looked-up name. std/cli is already in the newest published seed (it landed before it), and the seed compiles std from the checkout.

Size

One PR, one or two Conventional Commits (feat(std/cli): optional, repeatable and pass-through arguments, docs(cli): ...). Tier A in forge CI only.

Dependencies

None open (#123 is closed). Blocks the next step of #124.

Part of #124 (the PR says Refs #124, not Closes).

## Context `torb` cannot move to `std/cli` (#124) while the package cannot say what the compiler's commands say. Read off `compiler/src/main.trb` and the option readers it calls, three things are missing: - an **optional option**: `--output <file>`, `--target`, `--template` may be left out and have no default (today an option without default is *required*); - a **repeatable option**: `torb test --filter a --filter b`, `torb repl --environment p --environment q`, `--modules`; - **pass-through**: in `torb run [path] [...]` everything behind the path is the program's own `Process.arguments()`, flags included (`torb run tool.trb --emit-c` hands `--emit-c` on). ## Source - [CLI.md slice 2](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/CLI.md) (the first step of #124) - `std/cli/src/command.trb` (`CommandBuilder`, `Command.parse`, `Command.settle`), `std/cli/src/input.trb` ## Design (decided by the loop, internal API shape) - `option<T>(name, help:, default:)` keeps its meaning. New `CommandBuilder.optional<T>(name, help:)`: may be left out, read as `input.optional<T>("name"): T?` (`None` if absent); help row `(optional)`. - New `CommandBuilder.repeatable<T>(name, help:)`: may be given any number of times (also `--name=v`), read as `input.repeated<T>("name"): List<T>` in the order of the line, empty if absent; every value is checked like an option's. - `arguments(name, help:, passthrough: Bool = false)`: with `passthrough` the first positional argument ends option parsing, and it and everything behind it (flags too) go into the list; `--help`/`-h` are still honoured before that point only. - Errors keep using `CliError`; no new case is needed (a missing value / invalid value reuse `MissingValue`, `InvalidValue`). ## Acceptance criteria - [ ] `optional`, `repeatable` and `passthrough` as above, in `std/cli/src/command.trb` and `input.trb`, exported from `std/cli`. - [ ] Tests in `std/cli/tests/cli.test.trb` with argument lists: absent / present / `=` form / invalid value for `optional` and `repeatable`; order of repeated values; pass-through keeps `--emit-c`-style tokens behind the first positional, `--` still works, `--help` in front of the path still wins. - [ ] Help text shows `(optional)`, `(repeatable)` and the pass-through arguments; covered by a test. - [ ] `docs/standard-library/cli.md` documents the three; `skills/` regenerated where the docs gate asks. ## Seed Does **not** touch the seed: std source only, no syntax, no native, no driver flag, no looked-up name. `std/cli` is already in the newest published seed (it landed before it), and the seed compiles std from the checkout. ## Size One PR, one or two Conventional Commits (`feat(std/cli): optional, repeatable and pass-through arguments`, `docs(cli): ...`). Tier A in forge CI only. ## Dependencies None open (#123 is closed). Blocks the next step of #124. Part of #124 (the PR says `Refs #124`, not `Closes`).
Author
Collaborator

[loop:torbscript] refine: ready. The PR says Closes #492 and Refs #124 (the epic stays open). Two-commit rule: not applicable, see the Seed section. Worker: sonnet/medium (std/ package).

[loop:torbscript] decided by the loop: the optional/repeatable/pass-through shapes above are internal API choices that follow the existing option/arguments builder style; no owner question.

next: implement

[loop:torbscript] refine: ready. The PR says `Closes #492` and `Refs #124` (the epic stays open). Two-commit rule: not applicable, see the Seed section. Worker: sonnet/medium (std/ package). [loop:torbscript] decided by the loop: the optional/repeatable/pass-through shapes above are internal API choices that follow the existing `option`/`arguments` builder style; no owner question. next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261026 until 2026-10-26T08:00:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261026 until 2026-10-26T08:00:00Z
Author
Collaborator

[loop:torbscript] implement: optional<T>/input.optional, repeatable<T>/input.repeated, arguments(..., passthrough:) in std/cli with tests in std/cli/tests/cli.test.trb and docs (docs/standard-library/cli.md, skills/ mirror patched by hand), PR #493 (argus review requested), next: waiting (forge CI of the PR was still queued 10 min after push, nothing ran yet)

Remainder: read forge CI of PR 493 with ci-wait.sh. Not run locally, so unverified: the new tests, torb format --check on the touched .trb files, and the docs/skills gate. Likeliest failures: (1) skills/ differs from a regenerated copy (torb docs skill docs skills), (2) the torb:declaration blocks in cli.md differ from the generated ones, (3) .trb syntax or typing in the new command.trb/input.trb code (generic closure helper checked<T>(), for loop with read<T>). On failure fix on the same branch loop/492-cli-optional-args. Worktree removed (branch pushed).

[loop:torbscript] implement: `optional<T>`/`input.optional`, `repeatable<T>`/`input.repeated`, `arguments(..., passthrough:)` in std/cli with tests in `std/cli/tests/cli.test.trb` and docs (`docs/standard-library/cli.md`, `skills/` mirror patched by hand), PR https://git.torb.dev/torbscript/language/pulls/493 (argus review requested), next: waiting (forge CI of the PR was still queued 10 min after push, nothing ran yet) Remainder: read forge CI of PR 493 with `ci-wait.sh`. Not run locally, so unverified: the new tests, `torb format --check` on the touched `.trb` files, and the docs/skills gate. Likeliest failures: (1) `skills/` differs from a regenerated copy (`torb docs skill docs skills`), (2) the `torb:declaration` blocks in `cli.md` differ from the generated ones, (3) `.trb` syntax or typing in the new `command.trb`/`input.trb` code (generic closure helper `checked<T>()`, `for` loop with `read<T>`). On failure fix on the same branch `loop/492-cli-optional-args`. Worktree removed (branch pushed).
Author
Collaborator

[loop:torbscript] ci-fix: tier A of run 1819 (task 8843) failed on 9 lanes, all consequences of 4 errors in the new code (OptionSpec ctor missing optional/repeatable, repeatedValues.get key and [argumentsRow spec] not parsing, assert capturing Parsed; the compiler-tests failure was only types.test.trb "every type position ... nothing is reported" tripping on them, docs check cli.md:46/94 follows from the broken option body). Fixed in 0dbccaec on loop/492-cli-optional-args, PR #493. Checked with the nightly-20261025 linux-x64 binary (no local build): torb check std/cli no problems, torb doc --check --no-run std no problems, torb format --check std/cli clean (format also rewrapped 2 lines). Not run locally: native docs check, docs declarations --check, test lanes, compiler tests; skills/ mirror unchanged by the fix (docs untouched).

next: waiting on forge CI of 0dbccaec (all 4 statuses still pending/queued at last check). If red: read the log on the host (ssh host, sudo zstdcat .../actions_log/torbscript/language/<taskid%256 hex>/<taskid>.log.zst), fix on the same branch. Worktree code/wt/torbscript-language-492-ci-fix still exists (push: git -c http.extraHeader="Authorization: Basic base64(orion:torbdev-token)"); remove with ws wt rm once green.

[loop:torbscript] ci-fix: tier A of run 1819 (task 8843) failed on 9 lanes, all consequences of 4 errors in the new code (OptionSpec ctor missing `optional`/`repeatable`, `repeatedValues.get key` and `[argumentsRow spec]` not parsing, `assert` capturing `Parsed`; the compiler-tests failure was only `types.test.trb` "every type position ... nothing is reported" tripping on them, docs check cli.md:46/94 follows from the broken `option` body). Fixed in `0dbccaec` on `loop/492-cli-optional-args`, PR #493. Checked with the nightly-20261025 linux-x64 binary (no local build): `torb check std/cli` no problems, `torb doc --check --no-run std` no problems, `torb format --check std/cli` clean (format also rewrapped 2 lines). Not run locally: native `docs check`, `docs declarations --check`, `test` lanes, compiler tests; `skills/` mirror unchanged by the fix (docs untouched). next: waiting on forge CI of `0dbccaec` (all 4 statuses still pending/queued at last check). If red: read the log on the host (`ssh host`, `sudo zstdcat .../actions_log/torbscript/language/<taskid%256 hex>/<taskid>.log.zst`), fix on the same branch. Worktree `code/wt/torbscript-language-492-ci-fix` still exists (push: `git -c http.extraHeader="Authorization: Basic base64(orion:torbdev-token)"`); remove with `ws wt rm` once green.
Author
Collaborator

[loop:torbscript] claim fix by session:loop-torbscript-20261026-0724 until 2026-10-26T15:00:00Z (PR 493: tier A red on 0dbccaec)

[loop:torbscript] claim fix by session:loop-torbscript-20261026-0724 until 2026-10-26T15:00:00Z (PR 493: tier A red on 0dbccaec)
Author
Collaborator

[loop:torbscript] fix: run 1839 tier A was red on one test only: help > the command help lists subcommands and flags (native and VM lane of "std/example packages") expected the command list without the new test and run commands that the PR added to the test fixture; the expected help text now lists them (d946ed40). Everything else of tier A passed in that run (compiler tests, docs checks, format --check, 15575 of 15576 std tests). Branch rebased onto current main (358fb6ce, linear, tools/check-commits.sh clean); locally checked with the nightly-20261025 binary: torb format --check std clean, torb test std/cli 48 passed, 0 failed. New head d946ed40490c03cf175231d52baad38629ee2942, PR #493, argus review re-requested. CI of the new head (run 1858): commit messages, change scope, runners, bootstrap, pdisc green; tier A, release-sync, same-C and playground have been queued for a runner for 30+ min, gates/pack/archives blocked behind them.

next: waiting (forge CI queue, tier A not started yet; tokens used by this fix worker: ~95k)

[loop:torbscript] fix: run 1839 tier A was red on one test only: `help > the command help lists subcommands and flags` (native and VM lane of "std/example packages") expected the command list without the new `test` and `run` commands that the PR added to the test fixture; the expected help text now lists them (`d946ed40`). Everything else of tier A passed in that run (compiler tests, docs checks, `format --check`, 15575 of 15576 std tests). Branch rebased onto current main (358fb6ce, linear, `tools/check-commits.sh` clean); locally checked with the nightly-20261025 binary: `torb format --check std` clean, `torb test std/cli` 48 passed, 0 failed. New head `d946ed40490c03cf175231d52baad38629ee2942`, PR https://git.torb.dev/torbscript/language/pulls/493, argus review re-requested. CI of the new head (run 1858): commit messages, change scope, runners, bootstrap, pdisc green; tier A, release-sync, same-C and playground have been queued for a runner for 30+ min, gates/pack/archives blocked behind them. next: waiting (forge CI queue, tier A not started yet; tokens used by this fix worker: ~95k)
argus closed this issue 2026-10-26 11:03:31 +00:00
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#492
No description provided.