diff options
Diffstat (limited to 'parse.go')
| -rw-r--r-- | parse.go | 85 |
1 files changed, 35 insertions, 50 deletions
@@ -3,9 +3,7 @@ package arg import ( "errors" "fmt" - "io" "os" - "path/filepath" "reflect" "strconv" "strings" @@ -23,10 +21,10 @@ type spec struct { wasPresent bool } -// Parse returns this value to indicate that -h or --help were provided +// ErrHelp indicates that -h or --help were provided var ErrHelp = errors.New("help requested by user") -// MustParse processes command line arguments and exits upon failure. +// MustParse processes command line arguments and exits upon failure func MustParse(dest ...interface{}) { p, err := NewParser(dest...) if err != nil { @@ -34,19 +32,20 @@ func MustParse(dest ...interface{}) { os.Exit(1) } err = p.Parse(os.Args[1:]) + if err == ErrHelp { + p.WriteUsage(os.Stdout) + os.Exit(0) + } if err != nil { - fmt.Println(err) - writeUsage(os.Stdout, filepath.Base(os.Args[0]), p.spec) - os.Exit(1) + p.Fail(err.Error()) } } -// Parse processes command line arguments and stores them in dest. +// Parse processes command line arguments and stores them in dest func Parse(dest ...interface{}) error { p, err := NewParser(dest...) if err != nil { - fmt.Println(err) - os.Exit(1) + return err } return p.Parse(os.Args[1:]) } @@ -57,44 +56,7 @@ type Parser struct { } // NewParser constructs a parser from a list of destination structs -func NewParser(dest ...interface{}) (*Parser, error) { - spec, err := extractSpec(dest...) - if err != nil { - return nil, err - } - return &Parser{spec: spec}, nil -} - -// Parse processes the given command line option, storing the results in the field -// of the structs from which NewParser was constructed -func (p *Parser) Parse(args []string) error { - // If -h or --help were specified then print usage - for _, arg := range args { - if arg == "-h" || arg == "--help" { - return ErrHelp - } - if arg == "--" { - break - } - } - - // Process all command line arguments - err := process(p.spec, args) - if err != nil { - return err - } - - // Validate - return validate(p.spec) -} - -// WriteUsage writes usage information to the given writer -func (p *Parser) WriteUsage(w io.Writer) { - writeUsage(w, filepath.Base(os.Args[0]), p.spec) -} - -// extractSpec gets specifications for each argument from the tags in a struct -func extractSpec(dests ...interface{}) ([]*spec, error) { +func NewParser(dests ...interface{}) (*Parser, error) { var specs []*spec for _, dest := range dests { v := reflect.ValueOf(dest) @@ -169,10 +131,33 @@ func extractSpec(dests ...interface{}) ([]*spec, error) { specs = append(specs, &spec) } } - return specs, nil + return &Parser{spec: specs}, nil +} + +// Parse processes the given command line option, storing the results in the field +// of the structs from which NewParser was constructed +func (p *Parser) Parse(args []string) error { + // If -h or --help were specified then print usage + for _, arg := range args { + if arg == "-h" || arg == "--help" { + return ErrHelp + } + if arg == "--" { + break + } + } + + // Process all command line arguments + err := process(p.spec, args) + if err != nil { + return err + } + + // Validate + return validate(p.spec) } -// process goes through arguments the arguments one-by-one, parses them, and assigns the result to +// process goes through arguments one-by-one, parses them, and assigns the result to // the underlying struct field func process(specs []*spec, args []string) error { // construct a map from --option to spec |
