summaryrefslogtreecommitdiff
path: root/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'parse.go')
-rw-r--r--parse.go65
1 files changed, 36 insertions, 29 deletions
diff --git a/parse.go b/parse.go
index 6d8b509..be77924 100644
--- a/parse.go
+++ b/parse.go
@@ -75,13 +75,28 @@ var ErrHelp = errors.New("help requested by user")
// ErrVersion indicates that --version was provided
var ErrVersion = errors.New("version requested by user")
+// for monkey patching in example code
+var mustParseExit = os.Exit
+
// MustParse processes command line arguments and exits upon failure
func MustParse(dest ...interface{}) *Parser {
- p, err := NewParser(Config{}, dest...)
+ return mustParse(Config{Exit: mustParseExit}, dest...)
+}
+
+// mustParse is a helper that facilitates testing
+func mustParse(config Config, dest ...interface{}) *Parser {
+ if config.Exit == nil {
+ config.Exit = os.Exit
+ }
+ if config.Out == nil {
+ config.Out = os.Stdout
+ }
+
+ p, err := NewParser(config, dest...)
if err != nil {
- fmt.Fprintln(stdout, err)
- osExit(-1)
- return nil // just in case osExit was monkey-patched
+ fmt.Fprintln(config.Out, err)
+ config.Exit(-1)
+ return nil
}
p.MustParse(flags())
@@ -121,9 +136,11 @@ type Config struct {
// subcommand
StrictSubcommands bool
- OsExit func(int)
- Stdout io.Writer
- Stderr io.Writer
+ // Exit is called to terminate the process with an error code (defaults to os.Exit)
+ Exit func(int)
+
+ // Out is where help text, usage text, and failure messages are printed (defaults to os.Stdout)
+ Out io.Writer
}
// Parser represents a set of command line options with destination values
@@ -137,10 +154,6 @@ type Parser struct {
// the following field changes during processing of command line arguments
lastCmd *command
-
- osExit func(int)
- stdout io.Writer
- stderr io.Writer
}
// Versioned is the interface that the destination struct should implement to
@@ -190,6 +203,14 @@ func walkFieldsImpl(t reflect.Type, visit func(field reflect.StructField, owner
// NewParser constructs a parser from a list of destination structs
func NewParser(config Config, dests ...interface{}) (*Parser, error) {
+ // fill in defaults
+ if config.Exit == nil {
+ config.Exit = os.Exit
+ }
+ if config.Out == nil {
+ config.Out = os.Stdout
+ }
+
// first pick a name for the command for use in the usage text
var name string
switch {
@@ -205,20 +226,6 @@ func NewParser(config Config, dests ...interface{}) (*Parser, error) {
p := Parser{
cmd: &command{name: name},
config: config,
-
- osExit: osExit,
- stdout: stdout,
- stderr: stderr,
- }
-
- if config.OsExit != nil {
- p.osExit = config.OsExit
- }
- if config.Stdout != nil {
- p.stdout = config.Stdout
- }
- if config.Stderr != nil {
- p.stderr = config.Stderr
}
// make a list of roots
@@ -506,11 +513,11 @@ func (p *Parser) MustParse(args []string) {
err := p.Parse(args)
switch {
case err == ErrHelp:
- p.writeHelpForSubcommand(p.stdout, p.lastCmd)
- p.osExit(0)
+ p.writeHelpForSubcommand(p.config.Out, p.lastCmd)
+ p.config.Exit(0)
case err == ErrVersion:
- fmt.Fprintln(p.stdout, p.version)
- p.osExit(0)
+ fmt.Fprintln(p.config.Out, p.version)
+ p.config.Exit(0)
case err != nil:
p.failWithSubcommand(err.Error(), p.lastCmd)
}