diff --git a/builtins/break/break.go b/builtins/break/break.go index 1fdecfb9..9c489338 100644 --- a/builtins/break/break.go +++ b/builtins/break/break.go @@ -42,9 +42,9 @@ var Cmd = builtins.Command{ } func run(_ context.Context, callCtx *builtins.CallContext, args []string) builtins.Result { - if len(args) > 0 && args[0] == "--help" { + if len(args) > 0 && (args[0] == "--help" || args[0] == "-h") { callCtx.Outf("%s\n", helpText) - return builtins.Result{Code: 2} + return builtins.Result{} } return loopctl.LoopControl(callCtx, "break", args) } diff --git a/builtins/continue/continue.go b/builtins/continue/continue.go index ca107a79..143389b5 100644 --- a/builtins/continue/continue.go +++ b/builtins/continue/continue.go @@ -42,9 +42,9 @@ var Cmd = builtins.Command{ } func run(_ context.Context, callCtx *builtins.CallContext, args []string) builtins.Result { - if len(args) > 0 && args[0] == "--help" { + if len(args) > 0 && (args[0] == "--help" || args[0] == "-h") { callCtx.Outf("%s\n", helpText) - return builtins.Result{Code: 2} + return builtins.Result{} } return loopctl.LoopControl(callCtx, "continue", args) } diff --git a/builtins/help/help.go b/builtins/help/help.go index 2e6641df..ca2b93bc 100644 --- a/builtins/help/help.go +++ b/builtins/help/help.go @@ -15,8 +15,8 @@ // // Exit codes: // -// 0 Success. -// 1 Unknown command or --help was requested. +// 0 Success or --help was requested. +// 1 Unknown command. package help import ( @@ -44,7 +44,7 @@ func registerFlags(fs *builtins.FlagSet) builtins.HandlerFunc { return func(ctx context.Context, callCtx *builtins.CallContext, args []string) builtins.Result { if *helpFlag { printUsage(callCtx) - return builtins.Result{Code: 1} + return builtins.Result{} } // help — show detailed help for a specific command. diff --git a/builtins/tests/help/help_test.go b/builtins/tests/help/help_test.go index ff7ec50f..2ecaf5aa 100644 --- a/builtins/tests/help/help_test.go +++ b/builtins/tests/help/help_test.go @@ -249,7 +249,7 @@ func TestHelpShowsCommandHelp(t *testing.T) { func TestHelpFlagPrintsUsage(t *testing.T) { stdout, _, code := runScript(t, "help --help", "", interpoption.AllowAllCommands().(interp.RunnerOption)) - assert.Equal(t, 1, code) + assert.Equal(t, 0, code) assert.Contains(t, stdout, "Usage: help") assert.Contains(t, stdout, "Display help for builtin commands.") } diff --git a/tests/scenarios/cmd/break/help_flag.yaml b/tests/scenarios/cmd/break/help_flag.yaml new file mode 100644 index 00000000..ac3627a5 --- /dev/null +++ b/tests/scenarios/cmd/break/help_flag.yaml @@ -0,0 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "break --help"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). +description: break --help prints usage and exits zero. +skip_assert_against_bash: true +input: + script: |+ + break --help +expect: + stdout_contains: ["break: break [n]"] + stderr: "" + exit_code: 0 diff --git a/tests/scenarios/cmd/break/help_flag_short.yaml b/tests/scenarios/cmd/break/help_flag_short.yaml new file mode 100644 index 00000000..1a80a857 --- /dev/null +++ b/tests/scenarios/cmd/break/help_flag_short.yaml @@ -0,0 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "break -h"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). +description: break -h prints usage and exits zero. +skip_assert_against_bash: true +input: + script: |+ + break -h +expect: + stdout_contains: ["break: break [n]"] + stderr: "" + exit_code: 0 diff --git a/tests/scenarios/cmd/continue/help_flag.yaml b/tests/scenarios/cmd/continue/help_flag.yaml new file mode 100644 index 00000000..dcb1f3f6 --- /dev/null +++ b/tests/scenarios/cmd/continue/help_flag.yaml @@ -0,0 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "continue --help"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). +description: continue --help prints usage and exits zero. +skip_assert_against_bash: true +input: + script: |+ + continue --help +expect: + stdout_contains: ["continue: continue [n]"] + stderr: "" + exit_code: 0 diff --git a/tests/scenarios/cmd/continue/help_flag_short.yaml b/tests/scenarios/cmd/continue/help_flag_short.yaml new file mode 100644 index 00000000..bc6348c9 --- /dev/null +++ b/tests/scenarios/cmd/continue/help_flag_short.yaml @@ -0,0 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "continue -h"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). +description: continue -h prints usage and exits zero. +skip_assert_against_bash: true +input: + script: |+ + continue -h +expect: + stdout_contains: ["continue: continue [n]"] + stderr: "" + exit_code: 0 diff --git a/tests/scenarios/cmd/help/help_flag.yaml b/tests/scenarios/cmd/help/help_flag.yaml index b7c12e4a..a6bed079 100644 --- a/tests/scenarios/cmd/help/help_flag.yaml +++ b/tests/scenarios/cmd/help/help_flag.yaml @@ -1,3 +1,6 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "help --help"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). description: Help --help prints usage. skip_assert_against_bash: true input: @@ -6,4 +9,4 @@ input: expect: stdout_contains: ["Usage: help"] stderr: "" - exit_code: 1 + exit_code: 0 diff --git a/tests/scenarios/shell/for_clause/break_cont/break_help.yaml b/tests/scenarios/shell/for_clause/break_cont/break_help.yaml index c3fbd987..7f0d818d 100644 --- a/tests/scenarios/shell/for_clause/break_cont/break_help.yaml +++ b/tests/scenarios/shell/for_clause/break_cont/break_help.yaml @@ -1,8 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "break --help"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). description: Break --help displays usage information. +skip_assert_against_bash: true input: script: |+ for i in 1; do break --help; done expect: stdout: "break: break [n]\n Exit for, while, or until loops.\n \n Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n loops.\n \n Exit Status:\n The exit status is 0 unless N is not greater than or equal to 1.\n" stderr: "" - exit_code: 2 + exit_code: 0 diff --git a/tests/scenarios/shell/for_clause/break_cont/continue_help.yaml b/tests/scenarios/shell/for_clause/break_cont/continue_help.yaml index 8692ed5d..1dd8ccf2 100644 --- a/tests/scenarios/shell/for_clause/break_cont/continue_help.yaml +++ b/tests/scenarios/shell/for_clause/break_cont/continue_help.yaml @@ -1,8 +1,12 @@ +# skip_assert_against_bash: true — intentional divergence from bash. +# Bash returns exit code 2 for "continue --help"; rshell returns 0 per project +# convention (RULES.md: "When --help is passed: Set exit code 0 and return"). description: Continue --help displays usage information. +skip_assert_against_bash: true input: script: |+ for i in 1; do continue --help; done expect: stdout: "continue: continue [n]\n Resume for, while, or until loops.\n \n Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n If N is specified, resumes the Nth enclosing loop.\n \n Exit Status:\n The exit status is 0 unless N is not greater than or equal to 1.\n" stderr: "" - exit_code: 2 + exit_code: 0