parse boolean flags differently from string flags

This is important, because "-std -foo" and "-buildid -foo" are entirely
different cases. The first is equivalent to "-std=true -foo" since the
flag is boolean, but the second is equivalent to "-buildid=-foo" since
the flag isn't boolean.

We can keep track of which of the flags we're interested in are boolean,
which isn't much extra work. Also add unit tests; the build ID is a
hash, so it's very hard to write an end-to-end test that reliably has an
ID starting with a dash.
pull/22/head
Daniel Martí 4 years ago
parent ce0137fa6a
commit b10cce34f8

@ -266,7 +266,8 @@ func transformCompile(args []string) ([]string, error) {
func readBuildIDs(flags []string) error {
buildInfo.buildID = flagValue(flags, "-buildid")
if buildInfo.buildID == "" {
switch buildInfo.buildID {
case "", "true":
return fmt.Errorf("could not find -buildid argument")
}
buildInfo.buildID = trimBuildID(buildInfo.buildID)
@ -393,6 +394,7 @@ func transformGo(node ast.Node, info *types.Info) ast.Node {
buildID = id
}
}
// log.Printf("%q hashed with %q", node.Name, buildID)
node.Name = hashWith(buildID, node.Name)
}
return true
@ -457,49 +459,61 @@ func splitFlagsFromFiles(args []string, ext string) (flags, paths []string) {
return args, nil
}
// booleanFlag records which of the flags that we need are boolean. This
// matters, because boolean flags never consume the following argument, while
// non-boolean flags always do.
//
// For now, this stati
func booleanFlag(name string) bool {
switch name {
case "-std":
return true
default:
return false
}
}
// flagValue retrieves the value of a flag such as "-foo", from strings in the
// list of arguments like "-foo=bar" or "-foo" "bar".
func flagValue(flags []string, name string) string {
isBool := booleanFlag(name)
for i, arg := range flags {
if val := strings.TrimPrefix(arg, name+"="); val != arg {
// -name=value
return val
}
if arg == name {
if arg == name { // -name ...
if isBool {
// -name, equivalent to -name=true
return "true"
}
if i+1 < len(flags) {
if val := flags[i+1]; !strings.HasPrefix(val, "-") {
// -name value
return flags[i+1]
}
// -name value
return flags[i+1]
}
// -name, equivalent to -name=true
return "true"
}
}
return ""
}
func flagSetValue(flags []string, name, value string) []string {
isBool := booleanFlag(name)
for i, arg := range flags {
if strings.HasPrefix(arg, name+"=") {
// -name=value
if value == "true" {
flags[i] = name
} else {
flags[i] = name + "=" + value
}
flags[i] = name + "=" + value
return flags
}
if arg == name {
if i+1 < len(flags) {
if val := flags[i+1]; !strings.HasPrefix(val, "-") {
flags[i+1] = value
return flags
}
}
// -name, equivalent to -name=true
if value != "true" {
if arg == name { // -name ...
if isBool {
// -name, equivalent to -name=true
flags[i] = name + "=" + value
return flags
}
if i+1 < len(flags) {
// -name value
flags[i+1] = value
return flags
}
return flags
}

@ -96,3 +96,37 @@ func bincmp(ts *testscript.TestScript, neg bool, args []string) {
args[0], args[1], sizeDiff)
}
}
func TestFlagValue(t *testing.T) {
t.Parallel()
tests := []struct {
name string
flags []string
flagName string
want string
}{
{"BoolAlone", []string{"-std"}, "-std", "true"},
{"BoolFollowed", []string{"-std", "-foo"}, "-std", "true"},
{"BoolFalse", []string{"-std=false"}, "-std", "false"},
{"BoolMissing", []string{"-foo"}, "-std", ""},
{"BoolEmpty", []string{"-std="}, "-std", ""},
{"StrSpace", []string{"-buildid", "bar"}, "-buildid", "bar"},
{"StrSpaceDash", []string{"-buildid", "-bar"}, "-buildid", "-bar"},
{"StrEqual", []string{"-buildid=bar"}, "-buildid", "bar"},
{"StrEqualDash", []string{"-buildid=-bar"}, "-buildid", "-bar"},
{"StrMissing", []string{"-foo"}, "-buildid", ""},
{"StrNotFollowed", []string{"-buildid"}, "-buildid", ""},
{"StrEmpty", []string{"-buildid="}, "-buildid", ""},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
got := flagValue(test.flags, test.flagName)
if got != test.want {
t.Fatalf("flagValue(%q, %q) got %q, want %q",
test.flags, test.flagName, got, test.want)
}
})
}
}

Loading…
Cancel
Save