refactor redundant code around calls to cmd.Parse
Signed-off-by: Tibor Vass <teabee89@gmail.com>
This commit is contained in:
parent
d440ff0beb
commit
f23192465b
1 changed files with 68 additions and 46 deletions
114
mflag/flag.go
114
mflag/flag.go
|
@ -284,13 +284,14 @@ type FlagSet struct {
|
||||||
// a custom error handler.
|
// a custom error handler.
|
||||||
Usage func()
|
Usage func()
|
||||||
|
|
||||||
name string
|
name string
|
||||||
parsed bool
|
parsed bool
|
||||||
actual map[string]*Flag
|
actual map[string]*Flag
|
||||||
formal map[string]*Flag
|
formal map[string]*Flag
|
||||||
args []string // arguments after flags
|
args []string // arguments after flags
|
||||||
errorHandling ErrorHandling
|
errorHandling ErrorHandling
|
||||||
output io.Writer // nil means stderr; use out() accessor
|
output io.Writer // nil means stderr; use Out() accessor
|
||||||
|
nArgRequirements []nArgRequirement
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Flag represents the state of a flag.
|
// A Flag represents the state of a flag.
|
||||||
|
@ -348,7 +349,13 @@ func sortFlags(flags map[string]*Flag) []*Flag {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlagSet) out() io.Writer {
|
// Name returns the name of the FlagSet.
|
||||||
|
func (f *FlagSet) Name() string {
|
||||||
|
return f.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out returns the destination for usage and error messages.
|
||||||
|
func (f *FlagSet) Out() io.Writer {
|
||||||
if f.output == nil {
|
if f.output == nil {
|
||||||
return os.Stderr
|
return os.Stderr
|
||||||
}
|
}
|
||||||
|
@ -410,45 +417,60 @@ func IsSet(name string) bool {
|
||||||
return CommandLine.IsSet(name)
|
return CommandLine.IsSet(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nArgRequirementType int
|
||||||
|
|
||||||
// Indicator used to pass to BadArgs function
|
// Indicator used to pass to BadArgs function
|
||||||
const (
|
const (
|
||||||
Exact = 1
|
Exact nArgRequirementType = iota
|
||||||
Max = 2
|
Max
|
||||||
Min = 3
|
Min
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bad Args takes two arguments.
|
type nArgRequirement struct {
|
||||||
// The first one indicates whether the number of arguments should, be
|
Type nArgRequirementType
|
||||||
// A Minimal number of arguments, a maximum number of arguments or
|
N int
|
||||||
// The exact number of arguments required
|
}
|
||||||
// If the actuall number of arguments is not valid and error message
|
|
||||||
// prints and true is returned, otherwise false is returned
|
// Require adds a requirement about the number of arguments for the FlagSet.
|
||||||
func (f *FlagSet) BadArgs(arg_type, nargs int) bool {
|
// The first parameter can be Exact, Max, or Min to respectively specify the exact,
|
||||||
if arg_type == Max && f.NArg() > nargs {
|
// the maximum, or the minimal number of arguments required.
|
||||||
if nargs == 1 {
|
// The actual check is done in FlagSet.CheckArgs().
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
|
func (f *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) {
|
||||||
|
f.nArgRequirements = append(f.nArgRequirements, nArgRequirement{nArgRequirementType, nArg})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckArgs uses the requirements set by FlagSet.Require() to validate
|
||||||
|
// the number of arguments. If the requirements are not met,
|
||||||
|
// an error message string is returned.
|
||||||
|
func (f *FlagSet) CheckArgs() (message string) {
|
||||||
|
for _, req := range f.nArgRequirements {
|
||||||
|
var arguments string
|
||||||
|
if req.N == 1 {
|
||||||
|
arguments = "1 argument"
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
|
arguments = fmt.Sprintf("%d arguments", req.N)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
str := func(kind string) string {
|
||||||
if arg_type == Exact && f.NArg() != nargs {
|
return fmt.Sprintf("%q requires %s%s", f.name, kind, arguments)
|
||||||
if nargs == 1 {
|
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires 1 argument. See 'docker %s --help'.\n", f.name, f.name)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
|
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
switch req.Type {
|
||||||
if arg_type == Min && f.NArg() < nargs {
|
case Exact:
|
||||||
if nargs == 1 {
|
if f.NArg() != req.N {
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
|
return str("")
|
||||||
} else {
|
}
|
||||||
fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
|
case Max:
|
||||||
|
if f.NArg() > req.N {
|
||||||
|
return str("a maximum of ")
|
||||||
|
}
|
||||||
|
case Min:
|
||||||
|
if f.NArg() < req.N {
|
||||||
|
return str("a minimum of ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sets the value of the named flag.
|
// Set sets the value of the named flag.
|
||||||
|
@ -476,7 +498,7 @@ func Set(name, value string) error {
|
||||||
// PrintDefaults prints, to standard error unless configured
|
// PrintDefaults prints, to standard error unless configured
|
||||||
// otherwise, the default values of all defined flags in the set.
|
// otherwise, the default values of all defined flags in the set.
|
||||||
func (f *FlagSet) PrintDefaults() {
|
func (f *FlagSet) PrintDefaults() {
|
||||||
writer := tabwriter.NewWriter(f.out(), 20, 1, 3, ' ', 0)
|
writer := tabwriter.NewWriter(f.Out(), 20, 1, 3, ' ', 0)
|
||||||
f.VisitAll(func(flag *Flag) {
|
f.VisitAll(func(flag *Flag) {
|
||||||
format := " -%s=%s"
|
format := " -%s=%s"
|
||||||
if _, ok := flag.Value.(*stringValue); ok {
|
if _, ok := flag.Value.(*stringValue); ok {
|
||||||
|
@ -510,9 +532,9 @@ func PrintDefaults() {
|
||||||
// defaultUsage is the default function to print a usage message.
|
// defaultUsage is the default function to print a usage message.
|
||||||
func defaultUsage(f *FlagSet) {
|
func defaultUsage(f *FlagSet) {
|
||||||
if f.name == "" {
|
if f.name == "" {
|
||||||
fmt.Fprintf(f.out(), "Usage:\n")
|
fmt.Fprintf(f.Out(), "Usage:\n")
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
|
fmt.Fprintf(f.Out(), "Usage of %s:\n", f.name)
|
||||||
}
|
}
|
||||||
f.PrintDefaults()
|
f.PrintDefaults()
|
||||||
}
|
}
|
||||||
|
@ -805,7 +827,7 @@ func (f *FlagSet) Var(value Value, names []string, usage string) {
|
||||||
} else {
|
} else {
|
||||||
msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
|
msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(f.out(), msg)
|
fmt.Fprintln(f.Out(), msg)
|
||||||
panic(msg) // Happens only if flags are declared with identical names
|
panic(msg) // Happens only if flags are declared with identical names
|
||||||
}
|
}
|
||||||
if f.formal == nil {
|
if f.formal == nil {
|
||||||
|
@ -829,8 +851,8 @@ func Var(value Value, names []string, usage string) {
|
||||||
// returns the error.
|
// returns the error.
|
||||||
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
||||||
err := fmt.Errorf(format, a...)
|
err := fmt.Errorf(format, a...)
|
||||||
fmt.Fprintln(f.out(), err)
|
fmt.Fprintln(f.Out(), err)
|
||||||
fmt.Fprintf(f.out(), "See 'docker %s --help'.\n", f.name)
|
fmt.Fprintf(f.Out(), "See 'docker %s --help'.\n", f.name)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,9 +978,9 @@ func (f *FlagSet) parseOne() (bool, string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if replacement != "" {
|
if replacement != "" {
|
||||||
fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
|
fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
|
fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue