How do you get spaces in flag values when using directives?
Context
The flag
package receives and/or handles flags with spaces differently depending on how Go is called. Quoting the flag value works from the command-line but not with a directive, such as go generate
, for example.
In other words, called from the command line, Flag1
will receive the correct value (i.e., 4 words, 3 spaces).
Works
% go run -tags generate main.go -Flag1="flag value with spaces"
Doesn't Work
However, calling the exact same command in a directive file, e.g., with go generate ./...
, Flag1
will not receive the correct value. Take a directive file (e.g., generate.go
) with this line in it:
//go:generate go run -tags generate main.go -Flag1="flag value with spaces" -Flag2=next
Flag1
is not set correctly and Flag2
is not set at all.
CodePudding user response:
The arguments to go run
are parsed by your shell. The go:generate directive does its own parsing and that parsing is different from shells.
The relevant go:generate documentation is:
The arguments to the directive are space-separated tokens or double-quoted strings passed to the generator as individual arguments when it is run.
Quoted strings use Go syntax and are evaluated before execution; a quoted string appears as a single argument to the generator.
Each argument is separated by spaces. An argument is either a "token" or a double-quoted string. The documentation does not describe a token, but we can assume it means a sequence of non-space characters.
Quoted strings are evaluated. That means that quotes are removed, escape sequences are unescaped, etc. The implementation evaluates the string using strconv.Unquote.
Based on the above, use:
//go:generate go run -tags generate main.go "-Flag1=flag value with spaces"
The important change here is the "
is moved forward to a position where it's proceeded by a space. Quotes inside of a token are ignored.
CodePudding user response:
Extrapolating from an old, related, but not the same question, enclose the entire flag key, dash, and value in quotes.
//go:generate go run -tags generate main.go "-Flag1=flag value with spaces"
This syntax has the advantage of working on the command line or in directive files.
None of the current documentation (that I could find) provides a clear answer:
- The
flag
documentation does not mention flag values with spaces. - The directive documentation provides this cryptic hint that leads you to the correct solution (though a bit more clarity would be helpful).
Quoted strings use Go syntax and are evaluated before execution; a quoted string appears as a single argument to the generator.