cli: torb check, build, run and test parse their command line with std/cli (step 2 of #124) #502
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Step 2 of #124 (
torbparses its command line withstd/cli). Step 1 (#492, PR #493) landed:std/clihasoptional,repeatableand pass-througharguments. This step puts the skeleton incompiler/src/main.trband moves the four commands that matter most; the rest of the commands follow in later steps.Source
extendfor program types)std/cli/src/command.trb,docs/standard-library/cli.mdcompiler/src/main.trb(thematch argumentsat the bottom),compiler/src/cli/{check,build,run,test,usage}.trbDesign (decided by the loop, internal)
compiler/src/cli/declaration.trb: the command tree (programtorb, description) with the commandscheck,build,run,test.--versionstays a special case inmain.trb;--colorstays stripped before parsing (colorArguments).main.trbparses withCommand.parseand onematch parsed.path(noCommand.runhandlers: the commands use?onResultand top-levelTasks). It does so only when the first argument names one of the four migrated commands; every other line goes through the oldmatchunchanged, so no later command is touched here. The top-leveltorb --help/helpand the usage block of unmigrated commands stay oncli/usage.trbuntil step 5; the usage blocks of the four commands are removed from it, andtorb --helpkeeps listing them (text may be shorter only if every flag stays listed in the per-command help).CheckOptions,BuildOptions,RunOptions,TestOptionsrecords stay; the new code fills them fromInput.checkOptionsOf,buildOptionsOf,runOptionsOf,testOptionsOfand their private helpers are deleted once nothing reads them.runuses the pass-through arguments of #492 (torb run tool.trb --emit-cstill hands--emit-con). Repeatable--filteroftest, optional--output/--targetofbuilduserepeatable/optional.Argumentinstances viaextendin the compiler (CLI.md section 2 item 1), no stringly checks left in the readers.CliError); wording may change where the new one names both.Acceptance criteria
torb check,build,run,testparse their command line withstd/clithrough one declaration incompiler/src/cli/declaration.trb; every flag and option each has today is still accepted with the same meaning and listed intorb <command> --help.torb run <path> ...still passes everything behind the path on, flags included;--and--colorbehave as before.new,repl,format,docs ...,add, ...) behaves byte-identically: same help, same errors (existing tests untouched and green).compiler/tests/with argument lists per migrated command: parsed options,--help, wrong lines; the tests that asserted the old usage/option errors of these four commands move with them.cli/{check,build,run,test,usage}.trbandmain.trb; no dead code left behind.Seed
Does not touch the seed (see the refine comment on #124): no syntax, native, driver flag or looked-up name;
std/cliis in the newest published seed. If the seed cannot compile the import in CI, stop and comment on this issue, do not force it.Size
One PR, two Conventional Commits at most:
feat(compiler): torb check, build, run and test parse their command line with std/cliand, if needed,docs(cli): ...(CLI.md status line for step 2,docs/standard-library/cli.mdcross-link). Checks:torb format --checkon touched files, tier A in forge CI viaci-wait.sh; no local bootstrap.Dependencies
None open (#492 landed). Blocks the next step of #124.
Part of #124 (the PR says
Refs #124, notCloses).torbparses its command line withstd/cli(CLI slice 2) #124torbparses its command line withstd/cli(CLI slice 2) #124[loop:torbscript] decided by the loop: only four commands move in this step and the old match serves the rest, because one PR over ~30 commands would exceed one worker and review; no seed refresh needed (std/cli is in the newest seed). next: implement
torbparses its command line withstd/cli(CLI slice 2) #124[loop:torbscript] claim implement by session:loop-torbscript-20261026-1044 until 2026-10-26T22:05:01Z
[loop:torbscript] implement: checkpoint, no code written yet (context guard), nothing pushed, no PR. Worktree
code/wt/torbscript-language-502-cli-declarationonloop/502-cli-declaration(from main0e91170e, clean). Done: read issue, LOOP.md,std/cli(command.trb,docs/standard-library/cli.md),main.trbreaders (profileChoiceOf,buildOptionsOf,testOptionsOf,runOptionsOf),cli/check.trb,cli/usage.trb,cli/test.trb. next: implement (a fresh worker continues from the findings below).Findings for the implementation:
Command.parsetakes the line without the program name;path[0]istorb. Flags are looked up per command;-xshort flags are anUnknownFlag;helpas a word is only a help request where the command has subcommands.--help/-hfor the four commands now come fromparsed.helpRequested(parsed.help()), sohelpAskedOf/commandUsageTextat the top ofmain.trbmust skip check/build/run/test;["test","help"]branch is dropped (helpbecomes a path; note it in the PR). RemovetestUsageand the four blocks inusage.trbonly wheretorb --helpstill lists them (keep one block each there if the top-level text is not generated, as the issue says).check:--statistics --timings --every-target --partial --deny deprecated+ paths (default.).--deny->optional<Deny>with anArgumentextend (onlydeprecated).compiler/tests/deprecation.test.trb(l.13, 106-108, 545-558) anddriver.test.trb(l.10, 95:usageOf) read the old readers: they move to the declaration tests.build:--profile dev|release/--release(default release),--emit-c --embed-vm --timings --explain-copies --debug,--output <file>,--target <os>-<arch>(targetNamed,everyTarget), positional: paths vs one program name (isPathArgument; two names is an error, message "builds every program or one of them"). Default paths["."].test:--native --vm --profile/--release --shard k/n (testShardNamed) --shards n (>=1) --filter (repeatable) --report json --jobs N (ignored), default pathdefaultTestPath(). Cross checks to keep:--report jsonwith--shards>1,--shardwith--shards,--shards>1needs--native.usesMachine= default true;--nativefalse, a profile/--releasemeans native when not--vm... (checktestOptionsOf:usesMachine = choice.rest.length() == arguments.length(), i.e. a profile flag means native,--vm/--nativelast one wins).runtime/test.c, and the VM fortorb testdefault) reads--shard,--filter,--reportoff the process's own command line as two arguments.std/clialso accepts--filter=a, which the runtime would then ignore silently. Keep the old refusal of--filter=,--shard=,--report=with the old messages (small pre-check on thetestline, stop at--), exit 2.run: flags only in front of the path (--vm --native --release --profile <p> --timings),--profile/--releaseimply native unless--vm/--nativewas said (chosen), path or program name (isPathArgument), default.; usearguments "program", passthrough: true(--emit-cbehind the path passes on). The first positional is the path/name,restthe program's arguments.Profile/BuildTargetgetextend ... with Argumentin the compiler (argumentName,fromArgument;profileNamed,targetNamedexist), sooption<Profile>("profile", default: Profile.Release)etc.;--releasestays a flag.compiler/tests/cli-declaration.test.trbwithcli.parse([...])per command (options,--help, wrong lines);tests/command-line/arguments.expectedhas exact-wording lines fortorb check|build --frobnicateetc. (gatetools/command-line.sh, tier A): update the wording of the migrated ones (torb check: unknown flag '--frobnicate'), do not touch the others. Seed: not touched;std/cliis in the seed; if CI cannot compile the import, stop and comment.torb --helptext must keep listing the four commands fromusage.trbblocks (issue says yes);torb format --checkneeds a torb binary (not available here).[loop:torbscript] release implement: lease of session:loop-torbscript-20261026-1044 expired after the checkpoint, no worker alive, nothing pushed. next: implement (fresh worker from the checkpoint)
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T05:02:34Z
[loop:torbscript] implement: checkpoint 2, no code written yet (context guard hit again after reading), nothing pushed, no PR, tokens used ~110k. Worktree
code/wt/torbscript-language-502-cli-declaration(recreated viaws wt new, branchloop/502-cli-declaration, clean on main0e91170e). Claim released. next: implement (a fresh worker continues; it should NOT re-read std/cli, main.trb or the usage blocks in full: the facts below are enough to start writing).Additional findings on top of checkpoint 1:
std/cliAPI as used here:command "torb" { description ...; command "check" { description ...; flag "x", help: ...; option<T>("n", help:, default:); optional<T>("n", help:); repeatable<T>("n", help:); arguments "paths", help:, passthrough: true; run { input => ... } } }(runhandler is required orparseanswersMissingCommand; use a no-oprun { _ => }).Command.parse(args)returnsResult<Parsed, CliError>;Parsedhaspath,command,input,helpRequested,help(). Reads:input.flag("x"),input.option<T>("n"),input.optional<T>("n")(aT?),input.repeated<T>("n"),input.arguments("paths").CliError.show()readstorb check: unknown flag '--x',torb build: option '--target': 'x' is <reason>,... needs a value,... unexpected argument.Argumentneedsstatic fn argumentName(): Stringandstatic fn fromArgument(text: String): Result<Self, String>(error is the reason, e.g. "not a profile: dev or release");Showis required (a default is written withshow()).-h/--helpis honoured anywhere before--(and before the first positional withpassthrough),-xshort flags areUnknownFlag, a token--ends options.Command.help(path)generates the page;colorUsageLines()(fromcli/usage.trb) can be appended after a blank line so--colorstays documented per command.usage.trbblocks of check/build/run/test are only used fortorb --help(printUsage,commandUsages) andcommandUsageText->usageOffor--help;compiler/tests/driver.test.trbl.95 readsusageOf(command)for the four commands (check what it asserts and move it).helpAskedOf(usage.trb) must skip check/build/run/test so the generated help is used.colorArguments(color.trb l.291 comment mentionsrunOptionsOf, update the comment).main.trbProfileChoice,profileChoiceOf,buildOptionsOf,testOptionsOf,runOptionsOf;isPathArgumentstays (build/run still need it to tell path from program name);reportUnknownFlagstays for the other commands (refuseUnknownFlag); incli/check.trbcheckOptionsOf; incli/test.trbtestUsage(testShardNamedstays,--shardvalue is typed via anArgumentextend or checked after parse).CheckOptions,BuildOptions,RunOptions,TestOptions,TestShard,TestReportstay.--vm/--nativelast-one-wins in the old readers; flags are booleans in std/cli and lose their order, so decide (recorded as the loop's decision): both given together is a wrong line, exit 2,torb test: --vm and --native contradict each other(same for run); say so in the PR. A profile flag (--profile,--release) means native unless--vm/--nativewas said (run) / unless--vm(test).--releaseafter--profile devwins (release): with an optionalprofileoption plus areleaseflag, the flag wins.--jobs Nof test is accepted and ignored (option<Int>,--jobs=Ntoo).--shardsneeds>= 1(anArgumenttype or a check after parse).main.trb: aftercolorArgumentsand before the oldhelpAskedOf,if arguments.first() is one of check|build|run|test->cli.parse(arguments.skip(1)); onFail(problem)printprintErrorMessage problem.show()andProcess.exit 2; onhelpRequestedprintparsed.help()(+ color lines) and exit 0; else amatch parsed.pathover["torb", "check"]etc. building the existing option records and calling the existing run functions. The oldmatcharms for the four commands are removed (the old["test", "help"]arm too:torb test helpbecomes the pathhelp, note in the PR).declaration.trbexports the tree and theArgumentextends.tests/command-line/arguments.expectedlines for the four commands change wording; the rest stays. Tests: newcompiler/tests/cli-declaration.test.trbplus moving thecheckOptionsOftests ofdeprecation.test.trb(l.13, 106-108, 545-558) and theusageOfuse ofdriver.test.trb.torbbinary in the worker's environment:torb format --checkis not possible locally; write the layout by hand per the canon (120 columns, command calls) and let tier A's format gate decide.CONTINUE: torbscript/language#502
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T05:13Z
[loop:torbscript] implement: checkpoint 3,
compiler/src/cli/declaration.trbwritten and pushed (commit99a04745onloop/502-cli-declaration, unchecked: no torb binary), nothing else edited yet, no PR, tokens used ~110k. Claim released. next: implement (continue; do NOT re-read the issue's earlier checkpoints' sources, read onlydeclaration.trb(about 300 lines) and the hunks below).Written in
declaration.trb(public):Deny,CountplusArgumentextends forDeny,Count,Profile,BuildTarget,TestShard,TestReport;declaredCommands(),declaredUsageLines()(one line per command fortorb --help),torbCommand()(tree with check/build/run/test, no-oprun { _ => }),attachedValueIn(arguments): String?(refuses--filter=,--report=,--shard=with the old messages, the runtime reads them as two arguments),checkOptionsFrom/buildOptionsFrom/runOptionsFrom/testOptionsFrom(input)(the last threeResult<_, String>, messages starttorb <command>:).isPathArgumentwas MOVED there as a private fn.Left (in this order):
main.trb:use ... from "./cli/declaration"; deleteProfileChoice,profileChoiceOf,isPathArgument(l.446-496),buildOptionsOf,testOptionsOf,runOptionsOf(l.498-811), the importscheckOptionsOf,testUsage,profileNamed,TestShard,TestReport,testShardNamed,BuildTarget/everyTarget/targetNamed/Profileif unused (check with grep before). Replace the four old arms (["check"..]l.946, build, run,["test","help"], test, l.946-994) by one arm[first, ...more] if declaredCommands().contains first => { ... }placed before thenewarm: ifattachedValueIn(more)is Some ->printErrorMessage+ exit 2;torbCommand().parse(arguments.skip(1)...)— NOTECommand.parsetakes the line WITHOUT the program name (cli.parse(["check", "--jobs=8"])), so pass the wholeargumentsandparsed.pathis["torb", "check"]; onFail(problem)->printErrorMessage problem.show(), exit 2; onparsed.helpRequested->print parsed.help()then a blank line andcolorUsageLines(), exit 0; elsematch parsed.path: check ->endWith checkProjects(checkOptionsFrom(parsed.input)), countsProblems: true; build ->buildEmbedded/buildParsedAheadas today; run ->runProgram; test ->runTests;Fail(message)of the readers ->printErrorMessage message, exit 2.helpAskedOffor declared commands (makehelpAskedOfreturn None whendeclaredCommands()contains the command, or guard in main) so the generated help is used.cli/usage.trb: remove the fourCommandUsageblocks (l.18-66);printUsagein main.trb l.86-102: printdeclaredUsageLines()first, thencommandUsages()(sotorb --helpstill lists the four). Fix the doc comment of usage.trb (mentionstestpage).cli/check.trb: deletecheckOptionsOf, keepCheckOptions(update doc comment[checkOptionsOf]).cli/test.trb: deletetestUsage(l.33-56), update the module doc if it mentions it;main.trb commandUsageTextloses the"test" => testUsage()arm.cli/color.trbl.291 comment:runOptionsOf->runOptionsFrom.docs/standard-library/cli.mdcross-link anddocs/design/CLI.mdstatus line (second commitdocs(cli): ..., regenerateskills/per CLAUDE.md if docs change).compiler/tests/cli-declaration.test.trb(argument lists per command viatorbCommand().parse(...): parsed options through the...Fromreaders,--help, wrong lines incl.--vm --native,--shards 0,--releasebeats--profile dev,run tool.trb --emit-cpasses it on,--filterrepeated); move thecheckOptionsOftests ofcompiler/tests/deprecation.test.trb(l.13, 106-108, 545-558, 567) ontocheckOptionsFrom;compiler/tests/driver.test.trbl.93-98 assertsusageOf(command)lists--explain-copies:only for build: rewrite againsttorbCommand().help([...])text (onlybuildmentions--explain-copies).tests/command-line/arguments.expected: new wordingtorb <cmd>: unknown flag '--frobnicate'(exit 2) for the 8 lines of check/build/run/test (run --frobnicate,run --native --frobnicate tests/test-report/suite, ...); the--helplines keepthe usage of torb <cmd>check intools/command-line.sh(look at how it greps the help, l.120-end, and adapt to the generated help which starts with the description).tests/test-report/arguments.expectedlines 1-17:--filter=/--report=keep their wording (handled byattachedValueIn),--report xmlbecomestorb test: option '--report': 'xml' is not a report: ..., missing values becometorb test: option '--filter' needs a value; runtools/test-report.sh --updateis impossible locally (no torb): edit by hand and let CI decide.declaration.trbthe longFail "torb build: ... \n ..."line and theoptional<Deny>("deny", help: ...)line may exceed 120 columns, break them.tools/check-commits.sh, push, open PR (Refs #124, mention #502, note the--vm+--nativedecision and thattorb test helpis now a path),ci-wait.sh, fix tier A gates, write-back comment.Unverified risks to look at first when CI answers:
extendof types from other modules withArgument(orphan rule?),.takeWhile/.find({ a => ... })?inattachedValueIn,input.optional<Count>("shards")?.value,tree.subcommand(name).map({ _.summary }) ?? ""(Option.mapwith a field closure),run { _ => }as an empty handler.CONTINUE: torbscript/language#502
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T05:37Z
[loop:torbscript] implement: checkpoint 4, steps 1-3 and half of 4 done and pushed (commit
ab2a6e7fonloop/502-cli-declaration, worktreecode/wt/torbscript-language-502-cli-declaration, still no torb binary so unchecked), no PR yet, worker tokens ~150k. Claim released. next: implement (continue).Done:
main.trb: old readers (ProfileChoice,profileChoiceOf,isPathArgument,buildOptionsOf,testOptionsOf,runOptionsOf) deleted, imports trimmed, the four arms replaced by ONE arm[first, ...more] if declaredCommands().contains first(attached-value refusal,torbCommand().parse(arguments), generated help +colorUsageLines(), thenmatch parsed.pathcheck/build/run/test);printUsageprintsdeclaredUsageLines()first.cli/usage.trb: the four CommandUsage blocks removed (sousageOf("check")isNoneandhelpAskedOffalls through to the generated help; no change needed inhelpAskedOf); module doc updated.cli/check.trb:checkOptionsOfremoved.cli/test.trb:testUsageremoved.cli/color.trbcomment fixed.compiler/tests/deprecation.test.trbported totorbCommand().parse(["check", ...])+checkOptionsFrom(new local helperscheckOptionsOf,refusalOf;--deny=deprecatedis now accepted, wordingtorb check: unknown flag '--bogus','warnings'in single quotes).Left (in this order):
4b.
compiler/tests/driver.test.trbl.93-98 (usageOf(command)lists--explain-copies:only for build;usageOfno longer has check/build/run/test,.expectwould panic): rewrite againsttorbCommand().help(["torb", command])oftorbCommand().subcommand(command); text--explain-copiesonly in build; drop theuse usageOfimport there.4c. New
compiler/tests/cli-declaration.test.trb(argument lists per command viatorbCommand().parse(...): options through the...Fromreaders,--help,--vm --nativerefused,--shards 0,--releasebeats--profile dev,run tool.trb --emit-cpasses it on,--filterrepeated,attachedValueIn).5.
tests/command-line/arguments.expected(8 lines: new wordingerror: torb <cmd>: unknown flag '--frobnicate'; thetorb test --explain-copiesetc likewise) andtests/test-report/arguments.expectedl.1-17 (--report xml->error: torb test: option '--report': 'xml' is not a report: ..., missing values ->torb test: option '--filter' needs a value,--report json --native --shards 2->torb test: ...prefix); check howtools/command-line.shgreps--helpoutput.6. 120 col format of
declaration.trb(theFail "torb build: ..."line l.230 andoptional<Deny>("deny", ...)l.133).7. docs (
docs/standard-library/cli.mdcross link,docs/design/CLI.mdstatus line,skills/regenerate per CLAUDE.md) as 2nd commitdocs(cli): ...;tools/check-commits.sh(the branch has 2 commits now, the first is the declaration; commit messages carryRefs #124, #502); push; PR;ci-wait.sh; fix gates; write-back.Risks still unverified (CI will say):
extendof types from other modules withArgument(types getShowgenerated),.takeWhile/.find({ a => ... })?inattachedValueIn,input.optional<Count>("shards")?.value,tree.subcommand(name).map({ _.summary }) ?? "",run { _ => }as empty handler (std/cli tests userun { input => print ... }; if it does not parse userun { _ => print "" }is wrong: use a handler that does nothing e.g.run { input => input.path }is not Void either; check the grammar), the trailing_ => {}arm ofmatch parsed.path.CONTINUE: torbscript/language#502
[loop:torbscript] implement: collected worker result of checkpoint 4 (commit
ab2a6e7fverified in the comment above, no PR yet). Three Sonnet continuations are used (delegation 3 cap), and no worker slot is free this tick. next: implement (the next tick with a free slot starts ONE fresh worker on Opus/high per delegation 2 escalation, brief = checkpoint 4, steps 4b-7, and it must not re-read earlier checkpoints or sources beyond declaration.trb and the named hunks).[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T05:47Z
[loop:torbscript] implement: checkpoint 5, step 5 done and pushed (commit
c4266120onloop/502-cli-declaration, amended into the second feat commit, force-pushed with lease; still no torb binary or C compiler in the worker, so unchecked), no PR yet, worker tokens ~120k (Opus continuation, stopped by the context guard). Claim released. next: implement (continue).Done this round:
main.trb: the attached-value refusal (--filter=,--report=,--shard=) runs only fortorb test, as before; aCliErrornow printserror: <show()>, see--help``, so every wrong line names command and argument and points at the command's own help.declaration.trb: the threeattachedValueInmessages start withtorb test:.tests/command-line/arguments.expected: the 12 lines of check/build/run/test now readerror: torb <cmd>: unknown flag '--x', seetorb --help``; the other commands untouched.--help/-hof the four still pass the grep (Usage: torb <cmd> ...on stdout, nothing on stderr).tests/test-report/arguments.expected: new wording for alltorb testrefusals (option '--report': 'xml' is not a report: ...,option '--filter' needs a value,torb test:prefix) and thetorb test --helpblock replaced by the generated help (summary,Usage: torb test [options] [paths...], Arguments, Flags, Options with(optional)/(repeatable), then a blank line andcolorUsageLines()), computed by hand fromCommand.help: CI will tell whether the padding is exact.Checked by reading std/cli:
{ _ => }is a closure with an empty block (parser accepts zero statements);extendof the compiler's own types withArgumentis coherent (same package);Argument with Showrelies on the generatedShow.Left (in this order):
4b.
compiler/tests/driver.test.trbl.93-98:usageOf(command)no longer has check/build/run/test; rewrite againsttorbCommand().subcommand(command)?.help(["torb", command]),--explain-copiesonly in build; drop theusageOfimport.4c. New
compiler/tests/cli-declaration.test.trb(per checkpoint 4).6. 120-column format of
declaration.trb(l.230Fail "torb build: ...", l.133optional<Deny>(...), l.234/258/278 theconst profile = if ...lines).7. docs commit
docs(cli): ...(docs/standard-library/cli.mdcross link,docs/design/CLI.mdstatus line, regenerateskills/),tools/check-commits.sh(2 commits now; squash the declaration commit into the feat commit with the issue's title as subject so the docs commit is the second), push, PR (Refs #124,Closes #502),ci-wait.sh, fix red gates, write-back.CONTINUE: torbscript/language#502
[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:00Z
torb check,build,runandtestparse their command line withstd/cli#521[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T06:58Z
[loop:torbscript] implement: PR #521 is open (all steps of checkpoint 5 done by an earlier worker); tier A of the first CI run was red on 3 gates (one test, one colored line of tests/command-line/arguments.expected, format of declaration.trb). Fixed in
84bd6d14(test asserts the MissingValue wording, escape codes in the expected line, attachedValueIn and one Fail message simplified to avoid formatter ambiguity); CI re-running onb8bd779c.[loop:torbscript] claim implement (fix round, red tier A on PR #521 head
b8bd779c) by session:loop-torbscript-20261027 until 2026-10-27T08:30Z[loop:torbscript] release implement: lease expired (08:30Z) with no live worker and no result lost. PR #521 (head
7d9b6459) has review requested from argus; forge CI is queued behind the saturated runner pool. next: waiting (CI on PR #521)ir,manifest,parse,tokens,ast,highlightandnativesparse withstd/cli(step 3 of #124) #550torbparses its command line withstd/cli(CLI slice 2) #124torbparses its command line withstd/cli(CLI slice 2) #124new,initandupgradeparse withstd/cli(step 4 of #124) #568torbparses its command line withstd/cli(CLI slice 2) #124