summaryrefslogtreecommitdiff
path: root/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'parse.go')
-rw-r--r--parse.go85
1 files changed, 35 insertions, 50 deletions
diff --git a/parse.go b/parse.go
index 119efbd..dfa3421 100644
--- a/parse.go
+++ b/parse.go
@@ -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