Pull in go-flags, modified to build on Solaris
This commit is contained in:
212
github.com/jessevdk/go-flags/parser.go
Normal file
212
github.com/jessevdk/go-flags/parser.go
Normal file
@@ -0,0 +1,212 @@
|
||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package flags
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// A Parser provides command line option parsing. It can contain several
|
||||
// option groups each with their own set of options.
|
||||
type Parser struct {
|
||||
// Embedded, see Command for more information
|
||||
*Command
|
||||
|
||||
// A usage string to be displayed in the help message.
|
||||
Usage string
|
||||
|
||||
// Option flags changing the behavior of the parser.
|
||||
Options Options
|
||||
|
||||
internalError error
|
||||
}
|
||||
|
||||
// Options provides parser options that change the behavior of the option
|
||||
// parser.
|
||||
type Options uint
|
||||
|
||||
const (
|
||||
// None indicates no options.
|
||||
None Options = 0
|
||||
|
||||
// HelpFlag adds a default Help Options group to the parser containing
|
||||
// -h and --help options. When either -h or --help is specified on the
|
||||
// command line, the parser will return the special error of type
|
||||
// ErrHelp. When PrintErrors is also specified, then the help message
|
||||
// will also be automatically printed to os.Stderr.
|
||||
HelpFlag = 1 << iota
|
||||
|
||||
// PassDoubleDash passes all arguments after a double dash, --, as
|
||||
// remaining command line arguments (i.e. they will not be parsed for
|
||||
// flags).
|
||||
PassDoubleDash
|
||||
|
||||
// IgnoreUnknown ignores any unknown options and passes them as
|
||||
// remaining command line arguments instead of generating an error.
|
||||
IgnoreUnknown
|
||||
|
||||
// PrintErrors prints any errors which occurred during parsing to
|
||||
// os.Stderr.
|
||||
PrintErrors
|
||||
|
||||
// PassAfterNonOption passes all arguments after the first non option
|
||||
// as remaining command line arguments. This is equivalent to strict
|
||||
// POSIX processing.
|
||||
PassAfterNonOption
|
||||
|
||||
// Default is a convenient default set of options which should cover
|
||||
// most of the uses of the flags package.
|
||||
Default = HelpFlag | PrintErrors | PassDoubleDash
|
||||
)
|
||||
|
||||
// Parse is a convenience function to parse command line options with default
|
||||
// settings. The provided data is a pointer to a struct representing the
|
||||
// default option group (named "Application Options"). For more control, use
|
||||
// flags.NewParser.
|
||||
func Parse(data interface{}) ([]string, error) {
|
||||
return NewParser(data, Default).Parse()
|
||||
}
|
||||
|
||||
// ParseArgs is a convenience function to parse command line options with default
|
||||
// settings. The provided data is a pointer to a struct representing the
|
||||
// default option group (named "Application Options"). The args argument is
|
||||
// the list of command line arguments to parse. If you just want to parse the
|
||||
// default program command line arguments (i.e. os.Args), then use flags.Parse
|
||||
// instead. For more control, use flags.NewParser.
|
||||
func ParseArgs(data interface{}, args []string) ([]string, error) {
|
||||
return NewParser(data, Default).ParseArgs(args)
|
||||
}
|
||||
|
||||
// NewParser creates a new parser. It uses os.Args[0] as the application
|
||||
// name and then calls Parser.NewNamedParser (see Parser.NewNamedParser for
|
||||
// more details). The provided data is a pointer to a struct representing the
|
||||
// default option group (named "Application Options"), or nil if the default
|
||||
// group should not be added. The options parameter specifies a set of options
|
||||
// for the parser.
|
||||
func NewParser(data interface{}, options Options) *Parser {
|
||||
ret := NewNamedParser(path.Base(os.Args[0]), options)
|
||||
|
||||
if data != nil {
|
||||
_, ret.internalError = ret.AddGroup("Application Options", "", data)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// NewNamedParser creates a new parser. The appname is used to display the
|
||||
// executable name in the builtin help message. Option groups and commands can
|
||||
// be added to this parser by using AddGroup and AddCommand.
|
||||
func NewNamedParser(appname string, options Options) *Parser {
|
||||
return &Parser{
|
||||
Command: newCommand(appname, "", "", nil),
|
||||
Options: options,
|
||||
}
|
||||
}
|
||||
|
||||
// Parse parses the command line arguments from os.Args using Parser.ParseArgs.
|
||||
// For more detailed information see ParseArgs.
|
||||
func (p *Parser) Parse() ([]string, error) {
|
||||
return p.ParseArgs(os.Args[1:])
|
||||
}
|
||||
|
||||
// ParseArgs parses the command line arguments according to the option groups that
|
||||
// were added to the parser. On successful parsing of the arguments, the
|
||||
// remaining, non-option, arguments (if any) are returned. The returned error
|
||||
// indicates a parsing error and can be used with PrintError to display
|
||||
// contextual information on where the error occurred exactly.
|
||||
//
|
||||
// When the common help group has been added (AddHelp) and either -h or --help
|
||||
// was specified in the command line arguments, a help message will be
|
||||
// automatically printed. Furthermore, the special error type ErrHelp is returned.
|
||||
// It is up to the caller to exit the program if so desired.
|
||||
func (p *Parser) ParseArgs(args []string) ([]string, error) {
|
||||
if p.internalError != nil {
|
||||
return nil, p.internalError
|
||||
}
|
||||
|
||||
p.eachCommand(func(c *Command) {
|
||||
p.eachGroup(func(g *Group) {
|
||||
g.storeDefaults()
|
||||
})
|
||||
}, true)
|
||||
|
||||
// Add builtin help group to all commands if necessary
|
||||
if (p.Options & HelpFlag) != None {
|
||||
p.addHelpGroups(p.showBuiltinHelp)
|
||||
}
|
||||
|
||||
s := &parseState{
|
||||
args: args,
|
||||
retargs: make([]string, 0, len(args)),
|
||||
command: p.Command,
|
||||
lookup: p.makeLookup(),
|
||||
}
|
||||
|
||||
for !s.eof() {
|
||||
arg := s.pop()
|
||||
|
||||
// When PassDoubleDash is set and we encounter a --, then
|
||||
// simply append all the rest as arguments and break out
|
||||
if (p.Options&PassDoubleDash) != None && arg == "--" {
|
||||
s.retargs = append(s.retargs, s.args...)
|
||||
break
|
||||
}
|
||||
|
||||
if !argumentIsOption(arg) {
|
||||
// Note: this also sets s.err, so we can just check for
|
||||
// nil here and use s.err later
|
||||
if p.parseNonOption(s) != nil {
|
||||
break
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
var err error
|
||||
var option *Option
|
||||
|
||||
prefix, optname, islong := stripOptionPrefix(arg)
|
||||
optname, argument := splitOption(prefix, optname, islong)
|
||||
|
||||
if islong {
|
||||
option, err = p.parseLong(s, optname, argument)
|
||||
} else {
|
||||
option, err = p.parseShort(s, optname, argument)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ignoreUnknown := (p.Options & IgnoreUnknown) != None
|
||||
parseErr := wrapError(err)
|
||||
|
||||
if !(parseErr.Type == ErrUnknownFlag && ignoreUnknown) {
|
||||
s.err = parseErr
|
||||
break
|
||||
}
|
||||
|
||||
if ignoreUnknown {
|
||||
s.retargs = append(s.retargs, arg)
|
||||
}
|
||||
} else {
|
||||
delete(s.lookup.required, option)
|
||||
}
|
||||
}
|
||||
|
||||
if s.err == nil {
|
||||
s.checkRequired()
|
||||
}
|
||||
|
||||
if s.err != nil {
|
||||
return nil, p.printError(s.err)
|
||||
}
|
||||
|
||||
if len(s.command.commands) != 0 {
|
||||
return nil, p.printError(s.estimateCommand())
|
||||
} else if cmd, ok := s.command.data.(Commander); ok {
|
||||
return nil, p.printError(cmd.Execute(s.retargs))
|
||||
}
|
||||
|
||||
return s.retargs, nil
|
||||
}
|
||||
Reference in New Issue
Block a user