Repair completion and reporting examples

This commit is contained in:
2026-11-07 15:43:59 +00:00
parent 4346b840db
commit 7c7d1df13f
5 changed files with 27 additions and 9 deletions

View File

@@ -32,9 +32,9 @@ func TestCompletionConsumerInShells(t *testing.T) {
directory bool directory bool
}{ }{
{"canonical command", "probe ru", []string{"run"}, false}, {"canonical command", "probe ru", []string{"run"}, false},
{"entered alias", "probe shortcut --format=ya", []string{"shortcut", "--format=yaml"}, false}, {"entered alias", "probe shortcut --choice=ya", []string{"shortcut", "--choice=yaml"}, false},
{"choice", "probe run --format=te", []string{"run", "--format=text"}, false}, {"choice", "probe run --choice=te", []string{"run", "--choice=text"}, false},
{"no file fallback", `probe run --format=./partial\ f`, []string{"run", "--format=./partial f"}, false}, {"no file fallback", `probe run --choice=./partial\ f`, []string{"run", "--choice=./partial f"}, false},
{"separated file", `probe run --config ./partial\ f`, []string{"run", "--config", "./partial file"}, false}, {"separated file", `probe run --config ./partial\ f`, []string{"run", "--config", "./partial file"}, false},
{"attached file", `probe run --config=./partial\ f`, []string{"run", "--config=./partial file"}, false}, {"attached file", `probe run --config=./partial\ f`, []string{"run", "--config=./partial file"}, false},
{"short attached file", `probe run -c./partial\ f`, []string{"run", "-c./partial file"}, false}, {"short attached file", `probe run -c./partial\ f`, []string{"run", "-c./partial file"}, false},
@@ -42,7 +42,7 @@ func TestCompletionConsumerInShells(t *testing.T) {
{"separated directory", "probe run --directory ./partial", []string{"run", "--directory", "./partial dir"}, true}, {"separated directory", "probe run --directory ./partial", []string{"run", "--directory", "./partial dir"}, true},
{"attached directory", "probe run --directory=./partial", []string{"run", "--directory=./partial dir"}, true}, {"attached directory", "probe run --directory=./partial", []string{"run", "--directory=./partial dir"}, true},
{"empty operand", "probe run ", []string{"run", "alpha"}, false}, {"empty operand", "probe run ", []string{"run", "alpha"}, false},
{"leading dash", "probe run --for", []string{"run", "--format"}, false}, {"leading dash", "probe run --cho", []string{"run", "--choice"}, false},
} }
for _, shell := range []string{"bash", "zsh", "fish"} { for _, shell := range []string{"bash", "zsh", "fish"} {
generator := exec.Command(app, "completion", shell) generator := exec.Command(app, "completion", shell)
@@ -82,7 +82,7 @@ func TestCompletionConsumerInShells(t *testing.T) {
}) })
} }
t.Run(shell+"/descriptions", func(t *testing.T) { t.Run(shell+"/descriptions", func(t *testing.T) {
terminal := exec.Command("python3", "internal/cobra/testdata/completion_terminal.py", shell, scriptPath, "probe run --format=") terminal := exec.Command("python3", "internal/cobra/testdata/completion_terminal.py", shell, scriptPath, "probe run --choice=")
terminal.Env = append(os.Environ(), "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH"), "HOME="+dir, "TERM=xterm", "PROBE_LOG="+filepath.Join(dir, "log"), "PROBE_DIR="+dir, "PROBE_LIST=1") terminal.Env = append(os.Environ(), "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH"), "HOME="+dir, "TERM=xterm", "PROBE_LOG="+filepath.Join(dir, "log"), "PROBE_DIR="+dir, "PROBE_LIST=1")
output, err := terminal.CombinedOutput() output, err := terminal.CombinedOutput()
if err != nil || !strings.Contains(string(output), "Readable text") || !strings.Contains(string(output), "YAML output") { if err != nil || !strings.Contains(string(output), "Readable text") || !strings.Contains(string(output), "YAML output") {

View File

@@ -1,6 +1,6 @@
# Consolidated audit catalog # Consolidated audit catalog
Status: **22 distinct open findings: 22 P3**, consolidated from 30 Status: **20 distinct open findings: 20 P3**, consolidated from 30
numbered entries in seven audit documents. Reviewed audit state: numbered entries in seven audit documents. Reviewed audit state:
`db732e3a1de55c844f77870e1c6db683c2685d5d`. `db732e3a1de55c844f77870e1c6db683c2685d5d`.
@@ -142,6 +142,10 @@ Also noted in the [documentation cross-references](13-documentation.md#previousl
## F06 — P3: The optional interactive completion consumer fails before shell validation ## F06 — P3: The optional interactive completion consumer fails before shell validation
**Complete.** The renamed application-owned choice flag permits script
generation and the Bash interactive consumer and backend checks pass. Zsh and
Fish interactive checks remain unavailable because those shells are not installed.
The completion consumer fixture declares the reserved `format` flag, so App The completion consumer fixture declares the reserved `format` flag, so App
construction fails before it can generate scripts or exercise interactive construction fails before it can generate scripts or exercise interactive
completion. Default test suites skip this optional path. completion. Default test suites skip this optional path.
@@ -169,6 +173,9 @@ through a reachable handle, not an unreachable heap leak.
## F08 — P3: The core example overwrites its optional argument default ## F08 — P3: The core example overwrites its optional argument default
**Complete.** The example assigns a scenario only when supplied; bare and
explicit demo invocations succeed and an invalid scenario returns usage status 2.
The example's scenario setter replaces the factory's `"demo"` default with an The example's scenario setter replaces the factory's `"demo"` default with an
unsupplied empty value. The ordinary `report` invocation consequently fails with unsupplied empty value. The ordinary `report` invocation consequently fails with
a usage error. a usage error.

View File

@@ -1,6 +1,6 @@
# Audit remediation implementation plan # Audit remediation implementation plan
Status: in progress; Stages 1–5 complete. Status: in progress; Stages 1–6 complete.
Baseline: `d492c7747175c01a53261206c2b4356e53453621`. Before this sprint, Baseline: `d492c7747175c01a53261206c2b4356e53453621`. Before this sprint,
intervening changes recorded decisions and retired the completed older intervening changes recorded decisions and retired the completed older
@@ -250,6 +250,13 @@ presentation failures remain separately observable.
## Stage 6 — Repair the maintained consumers ## Stage 6 — Repair the maintained consumers
**Complete.** The fixture generates Bash, Zsh and Fish scripts; the available
interactive Bash backend and consumer checks passed. The full opt-in commands
reported failures for Zsh and Fish because those shells are not installed;
their interactive behavior remains unverified. The core example's bare and
explicit `demo` invocations succeeded, and an invalid scenario returned usage
status 2. Checks used Go 1.27.0 with offline, read-only module resolution.
Findings: F06 and F08. Sources: `testdata/completion/main.go`, Findings: F06 and F08. Sources: `testdata/completion/main.go`,
`completion_shell_test.go`, and `examples/core/main.go`. `completion_shell_test.go`, and `examples/core/main.go`.

View File

@@ -74,7 +74,11 @@ func newApp() (*commandkit.App, error) {
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "scenario", Usage: "demo, recover, warn, warn-error, fail, or partial.", Completion: commandkit.CompleteChoices( commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "scenario", Usage: "demo, recover, warn, warn-error, fail, or partial.", Completion: commandkit.CompleteChoices(
commandkit.CompletionChoice{Value: "demo"}, commandkit.CompletionChoice{Value: "recover"}, commandkit.CompletionChoice{Value: "warn"}, commandkit.CompletionChoice{Value: "demo"}, commandkit.CompletionChoice{Value: "recover"}, commandkit.CompletionChoice{Value: "warn"},
commandkit.CompletionChoice{Value: "warn-error"}, commandkit.CompletionChoice{Value: "fail"}, commandkit.CompletionChoice{Value: "partial"})}, false, func(value string) (string, error) { return value, nil }, commandkit.CompletionChoice{Value: "warn-error"}, commandkit.CompletionChoice{Value: "fail"}, commandkit.CompletionChoice{Value: "partial"})}, false, func(value string) (string, error) { return value, nil },
func(input *reportInput, value commandkit.Supplied[string]) { input.Scenario = value.Value }), func(input *reportInput, value commandkit.Supplied[string]) {
if value.Set {
input.Scenario = value.Value
}
}),
}, },
CheckInput: func(input reportInput) error { CheckInput: func(input reportInput) error {
switch input.Scenario { switch input.Scenario {

View File

@@ -29,7 +29,7 @@ func main() {
Name: "run", Summary: "Run a fixture command.", Name: "run", Summary: "Run a fixture command.",
Flags: []commandkit.Flag[struct{}]{ Flags: []commandkit.Flag[struct{}]{
commandkit.BoolFlag(commandkit.FlagMeta{Name: "switch", Short: "s"}, false, func(*struct{}, commandkit.Supplied[bool]) {}), commandkit.BoolFlag(commandkit.FlagMeta{Name: "switch", Short: "s"}, false, func(*struct{}, commandkit.Supplied[bool]) {}),
flag(commandkit.FlagMeta{Name: "format", Usage: "Report format.", Completion: commandkit.CompleteChoices(commandkit.CompletionChoice{Value: "text", Description: "Readable text"}, commandkit.CompletionChoice{Value: "yaml", Description: "YAML output"})}), flag(commandkit.FlagMeta{Name: "choice", Usage: "Fixture choice.", Completion: commandkit.CompleteChoices(commandkit.CompletionChoice{Value: "text", Description: "Readable text"}, commandkit.CompletionChoice{Value: "yaml", Description: "YAML output"})}),
flag(commandkit.FlagMeta{Name: "config", Short: "c", Usage: "Configuration path.", Completion: commandkit.CompleteFiles()}), flag(commandkit.FlagMeta{Name: "config", Short: "c", Usage: "Configuration path.", Completion: commandkit.CompleteFiles()}),
flag(commandkit.FlagMeta{Name: "directory", Short: "d", Usage: "Directory path.", Completion: commandkit.CompleteDirectories()}), flag(commandkit.FlagMeta{Name: "directory", Short: "d", Usage: "Directory path.", Completion: commandkit.CompleteDirectories()}),
}, },