Custom testing and flag handling can be achieved using flag.Var in flag .
Flag.Var "defines a flag with the specified name and usage string. The type and value of the flag is represented by the first argument of type Value, which usually contains a custom implementation of Value.
A flag.Value is any type that satisfies the Value interface, defined as:
type Value interface { String() string Set(string) error }
There is a good example flag source package in example_test.go
In your use case, you can use something like:
package main import ( "errors" "flag" "fmt" ) type formatType string func (f *formatType) String() string { return fmt.Sprint(*f) } func (f *formatType) Set(value string) error { if len(*f) > 0 && *f != "text" { return errors.New("format flag already set") } if value != "text" && value != "json" && value != "hash" { return errors.New("Invalid Format Type") } *f = formatType(value) return nil } var typeFlag formatType func init() { typeFlag = "text" usage := `Format type. Must be "text", "json" or "hash". Defaults to "text".` flag.Var(&typeFlag, "format", usage) flag.Var(&typeFlag, "f", usage+" (shorthand)") } func main() { flag.Parse() fmt.Println("Format type is", typeFlag) }
This is probably too large for such a simple example, but it can be very useful in defining more complex flag types (the linked example converts the list of intervals separated by commas into a slice of the user type based on time.Duration ).
EDIT: in response to how to run unit tests against flags, the most canonical example is flag_test.go in the source of the flag package . The section related to checking custom flag variables starts with Line 181 .
source share