Home > Software engineering >  Use a space in a flag value in a Golang directive
Use a space in a flag value in a Golang directive

Time:09-17

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.

  • Related