mirror of
https://github.com/golang/go
synced 2024-11-23 00:50:05 -07:00
flag: exit 0 when -h or -help invoked but undefined
flag treats -h or -help as a special case to print a nice help
message, but exit with a status code of 2. This update makes
that status code 0.
Fixes #37533
Change-Id: I7e0bd29944ce46607fb7cfc6740734f7444a151a
GitHub-Last-Rev: 83f64d757b
GitHub-Pull-Request: golang/go#37530
Reviewed-on: https://go-review.googlesource.com/c/go/+/221427
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
041bcb32b5
commit
dcf0929de6
@ -119,6 +119,21 @@ TODO
|
||||
TODO
|
||||
</p>
|
||||
|
||||
<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 221427 -->
|
||||
When the flag package sees <code>-h</code> or <code>-help</code>, and
|
||||
those flags are not defined, the flag package prints a usage message.
|
||||
If the <a href=/pkg/flag/#FlagSet><code>FlagSet</code></a> was created with
|
||||
<a href=/pkg/flag/#ExitOnError><code>ExitOnError</code></a>,
|
||||
<a href=/pkg/flag/#FlagSet.Parse><code>FlagSet.Parse</code></a> would then
|
||||
exit with a status of 2. In this release, the exit status for <code>-h</code>
|
||||
or <code>-help</code> has been changed to 0. In particular, this applies to
|
||||
the default handling of command line flags.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl id="pkg-runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 221779 -->
|
||||
|
@ -308,7 +308,7 @@ type ErrorHandling int
|
||||
// These constants cause FlagSet.Parse to behave as described if the parse fails.
|
||||
const (
|
||||
ContinueOnError ErrorHandling = iota // Return a descriptive error.
|
||||
ExitOnError // Call os.Exit(2).
|
||||
ExitOnError // Call os.Exit(2) or for -h/-help Exit(0).
|
||||
PanicOnError // Call panic with a descriptive error.
|
||||
)
|
||||
|
||||
@ -979,6 +979,9 @@ func (f *FlagSet) Parse(arguments []string) error {
|
||||
case ContinueOnError:
|
||||
return err
|
||||
case ExitOnError:
|
||||
if err == ErrHelp {
|
||||
os.Exit(0)
|
||||
}
|
||||
os.Exit(2)
|
||||
case PanicOnError:
|
||||
panic(err)
|
||||
|
@ -8,9 +8,11 @@ import (
|
||||
"bytes"
|
||||
. "flag"
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -544,3 +546,62 @@ func TestRangeError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExitCode(t *testing.T) {
|
||||
testenv.MustHaveExec(t)
|
||||
|
||||
magic := 123
|
||||
if os.Getenv("GO_CHILD_FLAG") != "" {
|
||||
fs := NewFlagSet("test", ExitOnError)
|
||||
if os.Getenv("GO_CHILD_FLAG_HANDLE") != "" {
|
||||
var b bool
|
||||
fs.BoolVar(&b, os.Getenv("GO_CHILD_FLAG_HANDLE"), false, "")
|
||||
}
|
||||
fs.Parse([]string{os.Getenv("GO_CHILD_FLAG")})
|
||||
os.Exit(magic)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
flag string
|
||||
flagHandle string
|
||||
expectExit int
|
||||
}{
|
||||
{
|
||||
flag: "-h",
|
||||
expectExit: 0,
|
||||
},
|
||||
{
|
||||
flag: "-help",
|
||||
expectExit: 0,
|
||||
},
|
||||
{
|
||||
flag: "-undefined",
|
||||
expectExit: 2,
|
||||
},
|
||||
{
|
||||
flag: "-h",
|
||||
flagHandle: "h",
|
||||
expectExit: magic,
|
||||
},
|
||||
{
|
||||
flag: "-help",
|
||||
flagHandle: "help",
|
||||
expectExit: magic,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestExitCode")
|
||||
cmd.Env = append(
|
||||
os.Environ(),
|
||||
"GO_CHILD_FLAG="+test.flag,
|
||||
"GO_CHILD_FLAG_HANDLE="+test.flagHandle,
|
||||
)
|
||||
cmd.Run()
|
||||
got := cmd.ProcessState.ExitCode()
|
||||
if got != test.expectExit {
|
||||
t.Errorf("unexpected exit code for test case %+v \n: got %d, expect %d",
|
||||
test, got, test.expectExit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user