TUN-3922: Repoint urfave/cli/v2 library at patched branch at github.com/ipostelnik/cli/v2@fixed which correctly handles reading flags declared at multiple levels of subcommands.
This commit is contained in:
parent
a8ae6de213
commit
1670ee87fb
2
go.mod
2
go.mod
|
@ -2,6 +2,8 @@ module github.com/cloudflare/cloudflared
|
||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
|
replace github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 // indirect
|
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 // indirect
|
||||||
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93
|
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -350,6 +350,8 @@ github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w=
|
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69 h1:TuZfNu8oRuQr6Y8UIvQlpXq+G+SzytMUGx8NrBt+2jg=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||||
|
@ -978,6 +980,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
cli
|
cli
|
||||||
===
|
===
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli)
|
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||||
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
|
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
|
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
|
||||||
[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
|
[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
|
||||||
|
@ -17,11 +17,15 @@ Usage documentation exists for each major version. Don't know what version you'r
|
||||||
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
||||||
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
||||||
|
|
||||||
|
Guides for migrating to newer versions:
|
||||||
|
|
||||||
|
- `v1-to-v2` - [./docs/migrate-v1-to-v2.md](./docs/migrate-v1-to-v2.md)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Make sure you have a working Go environment. Go version 1.11+ is supported. [See the install instructions for Go](http://golang.org/doc/install.html).
|
Using this package requires a working Go environment. [See the install instructions for Go](http://golang.org/doc/install.html).
|
||||||
|
|
||||||
Go Modules are strongly recommended when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
|
Go Modules are required when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
|
||||||
|
|
||||||
### Using `v2` releases
|
### Using `v2` releases
|
||||||
|
|
||||||
|
@ -63,4 +67,4 @@ export PATH=$PATH:$GOPATH/bin
|
||||||
|
|
||||||
cli is tested against multiple versions of Go on Linux, and against the latest
|
cli is tested against multiple versions of Go on Linux, and against the latest
|
||||||
released version of Go on OS X and Windows. This project uses Github Actions for
|
released version of Go on OS X and Windows. This project uses Github Actions for
|
||||||
builds. For more build info, please look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml).
|
builds. To see our currently supported go versions and platforms, look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml).
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package altsrc
|
||||||
|
|
||||||
|
// defaultInputSource creates a default InputSourceContext.
|
||||||
|
func defaultInputSource() (InputSourceContext, error) {
|
||||||
|
return &MapInputSource{file: "", valueMap: map[interface{}]interface{}{}}, nil
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Only types that provide implementation of FlagInputSourceExtension can be listed here
|
||||||
|
# please keep list sorted alphabetically
|
||||||
|
flag_types = [
|
||||||
|
"Bool",
|
||||||
|
"Duration",
|
||||||
|
"Float64",
|
||||||
|
"Generic",
|
||||||
|
"Int",
|
||||||
|
"IntSlice",
|
||||||
|
"Path",
|
||||||
|
"String",
|
||||||
|
"StringSlice",
|
||||||
|
]
|
||||||
|
|
||||||
|
print('''// Code generated by fg.py; DO NOT EDIT.
|
||||||
|
|
||||||
|
package altsrc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)''')
|
||||||
|
|
||||||
|
for t in flag_types:
|
||||||
|
print(f'''
|
||||||
|
// {t}Flag is the flag type that wraps cli.{t}Flag to allow
|
||||||
|
// for other values to be specified
|
||||||
|
type {t}Flag struct {{
|
||||||
|
*cli.{t}Flag
|
||||||
|
set *flag.FlagSet
|
||||||
|
}}
|
||||||
|
var _ FlagInputSourceExtension = (*{t}Flag)(nil)
|
||||||
|
|
||||||
|
// New{t}Flag creates a new {t}Flag
|
||||||
|
func New{t}Flag(fl *cli.{t}Flag) *{t}Flag {{
|
||||||
|
return &{t}Flag{{{t}Flag: fl, set: nil}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
// Apply saves the flagSet for later usage calls, then calls
|
||||||
|
// the wrapped {t}Flag.Apply
|
||||||
|
func (f *{t}Flag) Apply(set *flag.FlagSet) error {{
|
||||||
|
f.set = set
|
||||||
|
return f.{t}Flag.Apply(set)
|
||||||
|
}}''')
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated by fg; DO NOT EDIT.
|
// Code generated by fg.py; DO NOT EDIT.
|
||||||
|
|
||||||
package altsrc
|
package altsrc
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ type BoolFlag struct {
|
||||||
*cli.BoolFlag
|
*cli.BoolFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*BoolFlag)(nil)
|
||||||
|
|
||||||
// NewBoolFlag creates a new BoolFlag
|
// NewBoolFlag creates a new BoolFlag
|
||||||
func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag {
|
func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag {
|
||||||
|
@ -33,6 +34,7 @@ type DurationFlag struct {
|
||||||
*cli.DurationFlag
|
*cli.DurationFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*DurationFlag)(nil)
|
||||||
|
|
||||||
// NewDurationFlag creates a new DurationFlag
|
// NewDurationFlag creates a new DurationFlag
|
||||||
func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag {
|
func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag {
|
||||||
|
@ -52,6 +54,7 @@ type Float64Flag struct {
|
||||||
*cli.Float64Flag
|
*cli.Float64Flag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*Float64Flag)(nil)
|
||||||
|
|
||||||
// NewFloat64Flag creates a new Float64Flag
|
// NewFloat64Flag creates a new Float64Flag
|
||||||
func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag {
|
func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag {
|
||||||
|
@ -71,6 +74,7 @@ type GenericFlag struct {
|
||||||
*cli.GenericFlag
|
*cli.GenericFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*GenericFlag)(nil)
|
||||||
|
|
||||||
// NewGenericFlag creates a new GenericFlag
|
// NewGenericFlag creates a new GenericFlag
|
||||||
func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag {
|
func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag {
|
||||||
|
@ -84,31 +88,13 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.GenericFlag.Apply(set)
|
return f.GenericFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64Flag is the flag type that wraps cli.Int64Flag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Int64Flag struct {
|
|
||||||
*cli.Int64Flag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInt64Flag creates a new Int64Flag
|
|
||||||
func NewInt64Flag(fl *cli.Int64Flag) *Int64Flag {
|
|
||||||
return &Int64Flag{Int64Flag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped Int64Flag.Apply
|
|
||||||
func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Int64Flag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntFlag is the flag type that wraps cli.IntFlag to allow
|
// IntFlag is the flag type that wraps cli.IntFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type IntFlag struct {
|
type IntFlag struct {
|
||||||
*cli.IntFlag
|
*cli.IntFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*IntFlag)(nil)
|
||||||
|
|
||||||
// NewIntFlag creates a new IntFlag
|
// NewIntFlag creates a new IntFlag
|
||||||
func NewIntFlag(fl *cli.IntFlag) *IntFlag {
|
func NewIntFlag(fl *cli.IntFlag) *IntFlag {
|
||||||
|
@ -128,6 +114,7 @@ type IntSliceFlag struct {
|
||||||
*cli.IntSliceFlag
|
*cli.IntSliceFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*IntSliceFlag)(nil)
|
||||||
|
|
||||||
// NewIntSliceFlag creates a new IntSliceFlag
|
// NewIntSliceFlag creates a new IntSliceFlag
|
||||||
func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag {
|
func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag {
|
||||||
|
@ -141,42 +128,24 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.IntSliceFlag.Apply(set)
|
return f.IntSliceFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow
|
// PathFlag is the flag type that wraps cli.PathFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type Int64SliceFlag struct {
|
type PathFlag struct {
|
||||||
*cli.Int64SliceFlag
|
*cli.PathFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*PathFlag)(nil)
|
||||||
|
|
||||||
// NewInt64SliceFlag creates a new Int64SliceFlag
|
// NewPathFlag creates a new PathFlag
|
||||||
func NewInt64SliceFlag(fl *cli.Int64SliceFlag) *Int64SliceFlag {
|
func NewPathFlag(fl *cli.PathFlag) *PathFlag {
|
||||||
return &Int64SliceFlag{Int64SliceFlag: fl, set: nil}
|
return &PathFlag{PathFlag: fl, set: nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
// Apply saves the flagSet for later usage calls, then calls
|
||||||
// the wrapped Int64SliceFlag.Apply
|
// the wrapped PathFlag.Apply
|
||||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||||
f.set = set
|
f.set = set
|
||||||
return f.Int64SliceFlag.Apply(set)
|
return f.PathFlag.Apply(set)
|
||||||
}
|
|
||||||
|
|
||||||
// Float64SliceFlag is the flag type that wraps cli.Float64SliceFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Float64SliceFlag struct {
|
|
||||||
*cli.Float64SliceFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFloat64SliceFlag creates a new Float64SliceFlag
|
|
||||||
func NewFloat64SliceFlag(fl *cli.Float64SliceFlag) *Float64SliceFlag {
|
|
||||||
return &Float64SliceFlag{Float64SliceFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls the
|
|
||||||
// wrapped Float64SliceFlag.Apply
|
|
||||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Float64SliceFlag.Apply(set)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringFlag is the flag type that wraps cli.StringFlag to allow
|
// StringFlag is the flag type that wraps cli.StringFlag to allow
|
||||||
|
@ -185,6 +154,7 @@ type StringFlag struct {
|
||||||
*cli.StringFlag
|
*cli.StringFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*StringFlag)(nil)
|
||||||
|
|
||||||
// NewStringFlag creates a new StringFlag
|
// NewStringFlag creates a new StringFlag
|
||||||
func NewStringFlag(fl *cli.StringFlag) *StringFlag {
|
func NewStringFlag(fl *cli.StringFlag) *StringFlag {
|
||||||
|
@ -198,31 +168,13 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.StringFlag.Apply(set)
|
return f.StringFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathFlag is the flag type that wraps cli.PathFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type PathFlag struct {
|
|
||||||
*cli.PathFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPathFlag creates a new PathFlag
|
|
||||||
func NewPathFlag(fl *cli.PathFlag) *PathFlag {
|
|
||||||
return &PathFlag{PathFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls the
|
|
||||||
// wrapped PathFlag.Apply
|
|
||||||
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.PathFlag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
|
// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type StringSliceFlag struct {
|
type StringSliceFlag struct {
|
||||||
*cli.StringSliceFlag
|
*cli.StringSliceFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*StringSliceFlag)(nil)
|
||||||
|
|
||||||
// NewStringSliceFlag creates a new StringSliceFlag
|
// NewStringSliceFlag creates a new StringSliceFlag
|
||||||
func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag {
|
func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag {
|
||||||
|
@ -235,41 +187,3 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
f.set = set
|
f.set = set
|
||||||
return f.StringSliceFlag.Apply(set)
|
return f.StringSliceFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64Flag is the flag type that wraps cli.Uint64Flag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Uint64Flag struct {
|
|
||||||
*cli.Uint64Flag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUint64Flag creates a new Uint64Flag
|
|
||||||
func NewUint64Flag(fl *cli.Uint64Flag) *Uint64Flag {
|
|
||||||
return &Uint64Flag{Uint64Flag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped Uint64Flag.Apply
|
|
||||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Uint64Flag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintFlag is the flag type that wraps cli.UintFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type UintFlag struct {
|
|
||||||
*cli.UintFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUintFlag creates a new UintFlag
|
|
||||||
func NewUintFlag(fl *cli.UintFlag) *UintFlag {
|
|
||||||
return &UintFlag{UintFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped UintFlag.Apply
|
|
||||||
func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.UintFlag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,8 +17,12 @@ import (
|
||||||
// by the given flag.
|
// by the given flag.
|
||||||
func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) {
|
func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
|
if context.IsSet(flag) {
|
||||||
return NewJSONSourceFromFile(context.String(flag))
|
return NewJSONSourceFromFile(context.String(flag))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewJSONSourceFromFile returns an InputSourceContext suitable for
|
// NewJSONSourceFromFile returns an InputSourceContext suitable for
|
||||||
|
|
|
@ -16,6 +16,11 @@ type MapInputSource struct {
|
||||||
valueMap map[interface{}]interface{}
|
valueMap map[interface{}]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewMapInputSource creates a new MapInputSource for implementing custom input sources.
|
||||||
|
func NewMapInputSource(file string, valueMap map[interface{}]interface{}) *MapInputSource {
|
||||||
|
return &MapInputSource{file: file, valueMap: valueMap}
|
||||||
|
}
|
||||||
|
|
||||||
// nestedVal checks if the name has '.' delimiters.
|
// nestedVal checks if the name has '.' delimiters.
|
||||||
// If so, it tries to traverse the tree by the '.' delimited sections to find
|
// If so, it tries to traverse the tree by the '.' delimited sections to find
|
||||||
// a nested value for the key.
|
// a nested value for the key.
|
||||||
|
|
|
@ -87,9 +87,13 @@ func NewTomlSourceFromFile(file string) (InputSourceContext, error) {
|
||||||
// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
|
// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
|
||||||
func NewTomlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
func NewTomlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
|
if context.IsSet(flagFileName) {
|
||||||
filePath := context.String(flagFileName)
|
filePath := context.String(flagFileName)
|
||||||
return NewTomlSourceFromFile(filePath)
|
return NewTomlSourceFromFile(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCommandToml(filePath string, container interface{}) (err error) {
|
func readCommandToml(filePath string, container interface{}) (err error) {
|
||||||
|
|
|
@ -33,9 +33,13 @@ func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
|
||||||
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
|
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
|
||||||
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
|
if context.IsSet(flagFileName) {
|
||||||
filePath := context.String(flagFileName)
|
filePath := context.String(flagFileName)
|
||||||
return NewYamlSourceFromFile(filePath)
|
return NewYamlSourceFromFile(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCommandYaml(filePath string, container interface{}) (err error) {
|
func readCommandYaml(filePath string, container interface{}) (err error) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ type App struct {
|
||||||
Action ActionFunc
|
Action ActionFunc
|
||||||
// Execute this function if the proper command cannot be found
|
// Execute this function if the proper command cannot be found
|
||||||
CommandNotFound CommandNotFoundFunc
|
CommandNotFound CommandNotFoundFunc
|
||||||
// Execute this function if an usage error occurs
|
// Execute this function if a usage error occurs
|
||||||
OnUsageError OnUsageErrorFunc
|
OnUsageError OnUsageErrorFunc
|
||||||
// Compilation date
|
// Compilation date
|
||||||
Compiled time.Time
|
Compiled time.Time
|
||||||
|
@ -72,12 +72,15 @@ type App struct {
|
||||||
Authors []*Author
|
Authors []*Author
|
||||||
// Copyright of the binary if any
|
// Copyright of the binary if any
|
||||||
Copyright string
|
Copyright string
|
||||||
|
// Reader reader to write input to (useful for tests)
|
||||||
|
Reader io.Reader
|
||||||
// Writer writer to write output to
|
// Writer writer to write output to
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
// ErrWriter writes error output
|
// ErrWriter writes error output
|
||||||
ErrWriter io.Writer
|
ErrWriter io.Writer
|
||||||
// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to
|
// ExitErrHandler processes any error encountered while running an App before
|
||||||
// function as a default, so this is optional.
|
// it is returned to the caller. If no function is provided, HandleExitCoder
|
||||||
|
// is used as the default behavior.
|
||||||
ExitErrHandler ExitErrHandlerFunc
|
ExitErrHandler ExitErrHandlerFunc
|
||||||
// Other custom info
|
// Other custom info
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
|
@ -116,7 +119,9 @@ func NewApp() *App {
|
||||||
BashComplete: DefaultAppComplete,
|
BashComplete: DefaultAppComplete,
|
||||||
Action: helpCommand.Action,
|
Action: helpCommand.Action,
|
||||||
Compiled: compileTime(),
|
Compiled: compileTime(),
|
||||||
|
Reader: os.Stdin,
|
||||||
Writer: os.Stdout,
|
Writer: os.Stdout,
|
||||||
|
ErrWriter: os.Stderr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +140,7 @@ func (a *App) Setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.HelpName == "" {
|
if a.HelpName == "" {
|
||||||
a.HelpName = filepath.Base(os.Args[0])
|
a.HelpName = a.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Usage == "" {
|
if a.Usage == "" {
|
||||||
|
@ -158,10 +163,18 @@ func (a *App) Setup() {
|
||||||
a.Compiled = compileTime()
|
a.Compiled = compileTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.Reader == nil {
|
||||||
|
a.Reader = os.Stdin
|
||||||
|
}
|
||||||
|
|
||||||
if a.Writer == nil {
|
if a.Writer == nil {
|
||||||
a.Writer = os.Stdout
|
a.Writer = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.ErrWriter == nil {
|
||||||
|
a.ErrWriter = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
var newCommands []*Command
|
var newCommands []*Command
|
||||||
|
|
||||||
for _, c := range a.Commands {
|
for _, c := range a.Commands {
|
||||||
|
@ -195,10 +208,6 @@ func (a *App) Setup() {
|
||||||
if a.Metadata == nil {
|
if a.Metadata == nil {
|
||||||
a.Metadata = make(map[string]interface{})
|
a.Metadata = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Writer == nil {
|
|
||||||
a.Writer = os.Stdout
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
||||||
|
@ -290,8 +299,6 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
beforeErr := a.Before(context)
|
beforeErr := a.Before(context)
|
||||||
if beforeErr != nil {
|
if beforeErr != nil {
|
||||||
_, _ = fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
a.handleExitCoder(context, beforeErr)
|
a.handleExitCoder(context, beforeErr)
|
||||||
err = beforeErr
|
err = beforeErr
|
||||||
return err
|
return err
|
||||||
|
@ -321,11 +328,11 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||||
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
||||||
//
|
//
|
||||||
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
||||||
// to cli.App.Run. This will cause the application to exit with the given eror
|
// to cli.App.Run. This will cause the application to exit with the given error
|
||||||
// code in the cli.ExitCoder
|
// code in the cli.ExitCoder
|
||||||
func (a *App) RunAndExitOnError() {
|
func (a *App) RunAndExitOnError() {
|
||||||
if err := a.Run(os.Args); err != nil {
|
if err := a.Run(os.Args); err != nil {
|
||||||
_, _ = fmt.Fprintln(a.errWriter(), err)
|
_, _ = fmt.Fprintln(a.ErrWriter, err)
|
||||||
OsExiter(1)
|
OsExiter(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,15 +486,6 @@ func (a *App) VisibleFlags() []Flag {
|
||||||
return visibleFlags(a.Flags)
|
return visibleFlags(a.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) errWriter() io.Writer {
|
|
||||||
// When the app ErrWriter is nil use the package level one.
|
|
||||||
if a.ErrWriter == nil {
|
|
||||||
return ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) appendFlag(fl Flag) {
|
func (a *App) appendFlag(fl Flag) {
|
||||||
if !hasFlag(a.Flags, fl) {
|
if !hasFlag(a.Flags, fl) {
|
||||||
a.Flags = append(a.Flags, fl)
|
a.Flags = append(a.Flags, fl)
|
||||||
|
|
|
@ -150,7 +150,6 @@ func (c *Command) Run(ctx *Context) (err error) {
|
||||||
if c.Before != nil {
|
if c.Before != nil {
|
||||||
err = c.Before(context)
|
err = c.Before(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = ShowCommandHelp(context, c.Name)
|
|
||||||
context.App.handleExitCoder(context, err)
|
context.App.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -242,8 +241,9 @@ func (c *Command) startApp(ctx *Context) error {
|
||||||
app.HideHelpCommand = c.HideHelpCommand
|
app.HideHelpCommand = c.HideHelpCommand
|
||||||
|
|
||||||
app.Version = ctx.App.Version
|
app.Version = ctx.App.Version
|
||||||
app.HideVersion = ctx.App.HideVersion
|
app.HideVersion = true
|
||||||
app.Compiled = ctx.App.Compiled
|
app.Compiled = ctx.App.Compiled
|
||||||
|
app.Reader = ctx.App.Reader
|
||||||
app.Writer = ctx.App.Writer
|
app.Writer = ctx.App.Writer
|
||||||
app.ErrWriter = ctx.App.ErrWriter
|
app.ErrWriter = ctx.App.ErrWriter
|
||||||
app.ExitErrHandler = ctx.App.ExitErrHandler
|
app.ExitErrHandler = ctx.App.ExitErrHandler
|
||||||
|
|
|
@ -18,6 +18,7 @@ type Context struct {
|
||||||
Command *Command
|
Command *Command
|
||||||
shellComplete bool
|
shellComplete bool
|
||||||
flagSet *flag.FlagSet
|
flagSet *flag.FlagSet
|
||||||
|
fromFlagSet map[string]bool
|
||||||
parentContext *Context
|
parentContext *Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +33,14 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pre-compute flag seen on the command line at this context
|
||||||
|
c.fromFlagSet = make(map[string]bool)
|
||||||
|
if set != nil {
|
||||||
|
set.Visit(func(f *flag.Flag) {
|
||||||
|
c.fromFlagSet[f.Name] = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
c.Command = &Command{}
|
c.Command = &Command{}
|
||||||
|
|
||||||
if c.Context == nil {
|
if c.Context == nil {
|
||||||
|
@ -48,35 +57,49 @@ func (c *Context) NumFlags() int {
|
||||||
|
|
||||||
// Set sets a context flag to a value.
|
// Set sets a context flag to a value.
|
||||||
func (c *Context) Set(name, value string) error {
|
func (c *Context) Set(name, value string) error {
|
||||||
return c.flagSet.Set(name, value)
|
err := c.flagSet.Set(name, value)
|
||||||
|
if err == nil {
|
||||||
|
c.fromFlagSet[name] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSet determines if the flag was actually set
|
// IsSet determines if the flag was actually set
|
||||||
func (c *Context) IsSet(name string) bool {
|
func (c *Context) IsSet(name string) bool {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
for ctx := c; ctx != nil; ctx = ctx.parentContext {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
// try flags parsed from command line first
|
||||||
isSet := false
|
if ctx.flagSet.Lookup(name) == nil {
|
||||||
fs.Visit(func(f *flag.Flag) {
|
// flag not defined in this context
|
||||||
if f.Name == name {
|
continue
|
||||||
isSet = true
|
|
||||||
}
|
}
|
||||||
})
|
if ctx.flagOnCommandLine(name) {
|
||||||
if isSet {
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// now see if value was set externally via environment
|
||||||
|
definedFlags := ctx.Command.Flags
|
||||||
|
if ctx.Command.Name == "" && ctx.App != nil {
|
||||||
|
definedFlags = ctx.App.Flags
|
||||||
|
}
|
||||||
|
for _, ff := range definedFlags {
|
||||||
|
for _, fn := range ff.Names() {
|
||||||
|
if fn == name {
|
||||||
|
if ff.IsSet() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f := lookupFlag(name, c)
|
|
||||||
if f == nil {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return f.IsSet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) flagOnCommandLine(name string) bool {
|
||||||
|
return c.fromFlagSet[name]
|
||||||
|
}
|
||||||
|
|
||||||
// LocalFlagNames returns a slice of flag names used in this context.
|
// LocalFlagNames returns a slice of flag names used in this context.
|
||||||
func (c *Context) LocalFlagNames() []string {
|
func (c *Context) LocalFlagNames() []string {
|
||||||
var names []string
|
var names []string
|
||||||
|
@ -108,7 +131,10 @@ func (c *Context) Lineage() []*Context {
|
||||||
|
|
||||||
// Value returns the value of the flag corresponding to `name`
|
// Value returns the value of the flag corresponding to `name`
|
||||||
func (c *Context) Value(name string) interface{} {
|
func (c *Context) Value(name string) interface{} {
|
||||||
return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
|
return fs.Lookup(name).Value.(flag.Getter).Get()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Args returns the command line arguments associated with the context.
|
// Args returns the command line arguments associated with the context.
|
||||||
|
@ -150,6 +176,25 @@ func lookupFlag(name string, ctx *Context) Flag {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) resolveFlagDeep(name string) *flag.Flag {
|
||||||
|
var src *flag.Flag
|
||||||
|
for cur := c; cur != nil; cur = cur.parentContext {
|
||||||
|
if f := cur.flagSet.Lookup(name); f != nil {
|
||||||
|
if cur.flagOnCommandLine(name) {
|
||||||
|
// we've found most specific instance on command line, use it
|
||||||
|
src = f
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if src == nil {
|
||||||
|
// flag was defined, but value is not present among flags of the current context
|
||||||
|
// remember the most specific instance of the flag not from command line as fallback
|
||||||
|
src = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
||||||
for _, c := range ctx.Lineage() {
|
for _, c := range ctx.Lineage() {
|
||||||
if f := c.flagSet.Lookup(name); f != nil {
|
if f := c.flagSet.Lookup(name); f != nil {
|
||||||
|
|
|
@ -15,31 +15,39 @@ import (
|
||||||
// The function errors if either parsing or writing of the string fails.
|
// The function errors if either parsing or writing of the string fails.
|
||||||
func (a *App) ToMarkdown() (string, error) {
|
func (a *App) ToMarkdown() (string, error) {
|
||||||
var w bytes.Buffer
|
var w bytes.Buffer
|
||||||
if err := a.writeDocTemplate(&w); err != nil {
|
if err := a.writeDocTemplate(&w, 8); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return w.String(), nil
|
return w.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToMan creates a man page string for the `*App`
|
// ToMan creates a man page string with section number for the `*App`
|
||||||
// The function errors if either parsing or writing of the string fails.
|
// The function errors if either parsing or writing of the string fails.
|
||||||
func (a *App) ToMan() (string, error) {
|
func (a *App) ToManWithSection(sectionNumber int) (string, error) {
|
||||||
var w bytes.Buffer
|
var w bytes.Buffer
|
||||||
if err := a.writeDocTemplate(&w); err != nil {
|
if err := a.writeDocTemplate(&w, sectionNumber); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
man := md2man.Render(w.Bytes())
|
man := md2man.Render(w.Bytes())
|
||||||
return string(man), nil
|
return string(man), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToMan creates a man page string for the `*App`
|
||||||
|
// The function errors if either parsing or writing of the string fails.
|
||||||
|
func (a *App) ToMan() (string, error) {
|
||||||
|
man, err := a.ToManWithSection(8)
|
||||||
|
return man, err
|
||||||
|
}
|
||||||
|
|
||||||
type cliTemplate struct {
|
type cliTemplate struct {
|
||||||
App *App
|
App *App
|
||||||
|
SectionNum int
|
||||||
Commands []string
|
Commands []string
|
||||||
GlobalArgs []string
|
GlobalArgs []string
|
||||||
SynopsisArgs []string
|
SynopsisArgs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) writeDocTemplate(w io.Writer) error {
|
func (a *App) writeDocTemplate(w io.Writer, sectionNum int) error {
|
||||||
const name = "cli"
|
const name = "cli"
|
||||||
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,6 +55,7 @@ func (a *App) writeDocTemplate(w io.Writer) error {
|
||||||
}
|
}
|
||||||
return t.ExecuteTemplate(w, name, &cliTemplate{
|
return t.ExecuteTemplate(w, name, &cliTemplate{
|
||||||
App: a,
|
App: a,
|
||||||
|
SectionNum: sectionNum,
|
||||||
Commands: prepareCommands(a.Commands, 0),
|
Commands: prepareCommands(a.Commands, 0),
|
||||||
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
||||||
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
||||||
|
|
|
@ -17,11 +17,10 @@ var ErrWriter io.Writer = os.Stderr
|
||||||
// MultiError is an error that wraps multiple errors.
|
// MultiError is an error that wraps multiple errors.
|
||||||
type MultiError interface {
|
type MultiError interface {
|
||||||
error
|
error
|
||||||
// Errors returns a copy of the errors slice
|
|
||||||
Errors() []error
|
Errors() []error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMultiError creates a new MultiError. Pass in one or more errors.
|
// newMultiError creates a new MultiError. Pass in one or more errors.
|
||||||
func newMultiError(err ...error) MultiError {
|
func newMultiError(err ...error) MultiError {
|
||||||
ret := multiError(err)
|
ret := multiError(err)
|
||||||
return &ret
|
return &ret
|
||||||
|
@ -65,13 +64,20 @@ type exitError struct {
|
||||||
message interface{}
|
message interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewExitError makes a new *exitError
|
// NewExitError calls Exit to create a new ExitCoder.
|
||||||
|
//
|
||||||
|
// Deprecated: This function is a duplicate of Exit and will eventually be removed.
|
||||||
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
||||||
return Exit(message, exitCode)
|
return Exit(message, exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit wraps a message and exit code into an ExitCoder suitable for handling by
|
// Exit wraps a message and exit code into an error, which by default is
|
||||||
// HandleExitCoder
|
// handled with a call to os.Exit during default error handling.
|
||||||
|
//
|
||||||
|
// This is the simplest way to trigger a non-zero exit code for an App without
|
||||||
|
// having to call os.Exit manually. During testing, this behavior can be avoided
|
||||||
|
// by overiding the ExitErrHandler function on an App or the package-global
|
||||||
|
// OsExiter function.
|
||||||
func Exit(message interface{}, exitCode int) ExitCoder {
|
func Exit(message interface{}, exitCode int) ExitCoder {
|
||||||
return &exitError{
|
return &exitError{
|
||||||
message: message,
|
message: message,
|
||||||
|
@ -87,10 +93,14 @@ func (ee *exitError) ExitCode() int {
|
||||||
return ee.exitCode
|
return ee.exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
|
// HandleExitCoder handles errors implementing ExitCoder by printing their
|
||||||
// so prints the error to stderr (if it is non-empty) and calls OsExiter with the
|
// message and calling OsExiter with the given exit code.
|
||||||
// given exit code. If the given error is a MultiError, then this func is
|
//
|
||||||
// called on all members of the Errors slice and calls OsExiter with the last exit code.
|
// If the given error instead implements MultiError, each error will be checked
|
||||||
|
// for the ExitCoder interface, and OsExiter will be called with the last exit
|
||||||
|
// code found, or exit code 1 if no ExitCoder is found.
|
||||||
|
//
|
||||||
|
// This function is the default error-handling behavior for an App.
|
||||||
func HandleExitCoder(err error) {
|
func HandleExitCoder(err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -171,6 +171,10 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||||
if f.TakesFile {
|
if f.TakesFile {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case *PathFlag:
|
||||||
|
if f.TakesFile {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
completion.WriteString(" -f")
|
completion.WriteString(" -f")
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,11 @@ func stringifySliceFlag(usage string, names, defaultVals []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
||||||
return fmt.Sprintf("%s\t%s", prefixedNames(names, placeholder), usageWithDefault)
|
multiInputString := "(accepts multiple inputs)"
|
||||||
|
if usageWithDefault != "" {
|
||||||
|
multiInputString = "\t" + multiInputString
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s\t%s%s", prefixedNames(names, placeholder), usageWithDefault, multiInputString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasFlag(flags []Flag, fl Flag) bool {
|
func hasFlag(flags []Flag, fl Flag) bool {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Bool looks up the value of a local BoolFlag, returns
|
// Bool looks up the value of a local BoolFlag, returns
|
||||||
// false if not found
|
// false if not found
|
||||||
func (c *Context) Bool(name string) bool {
|
func (c *Context) Bool(name string) bool {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupBool(c.resolveFlagDeep(name))
|
||||||
return lookupBool(name, fs)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
func lookupBool(f *flag.Flag) bool {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseBool(f.Value.String())
|
parsed, err := strconv.ParseBool(f.Value.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Duration looks up the value of a local DurationFlag, returns
|
// Duration looks up the value of a local DurationFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Duration(name string) time.Duration {
|
func (c *Context) Duration(name string) time.Duration {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupDuration(c.resolveFlagDeep(name))
|
||||||
return lookupDuration(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
func lookupDuration(f *flag.Flag) time.Duration {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := time.ParseDuration(f.Value.String())
|
parsed, err := time.ParseDuration(f.Value.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||||
// Float64 looks up the value of a local Float64Flag, returns
|
// Float64 looks up the value of a local Float64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Float64(name string) float64 {
|
func (c *Context) Float64(name string) float64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupFloat64(c.resolveFlagDeep(name))
|
||||||
return lookupFloat64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
func lookupFloat64(f *flag.Flag) float64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -146,14 +146,10 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Float64Slice(name string) []float64 {
|
func (c *Context) Float64Slice(name string) []float64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupFloat64Slice(c.resolveFlagDeep(name))
|
||||||
return lookupFloat64Slice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
func lookupFloat64Slice(f *flag.Flag) []float64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*Float64Slice); ok {
|
if slice, ok := f.Value.(*Float64Slice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -89,14 +89,10 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Generic looks up the value of a local GenericFlag, returns
|
// Generic looks up the value of a local GenericFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Generic(name string) interface{} {
|
func (c *Context) Generic(name string) interface{} {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupGeneric(c.resolveFlagDeep(name))
|
||||||
return lookupGeneric(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
func lookupGeneric(f *flag.Flag) interface{} {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value, error(nil)
|
parsed, err := f.Value, error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Int looks up the value of a local IntFlag, returns
|
// Int looks up the value of a local IntFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Int(name string) int {
|
func (c *Context) Int(name string) int {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupInt(c.resolveFlagDeep(name))
|
||||||
return lookupInt(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt(name string, set *flag.FlagSet) int {
|
func lookupInt(f *flag.Flag) int {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||||
// Int64 looks up the value of a local Int64Flag, returns
|
// Int64 looks up the value of a local Int64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Int64(name string) int64 {
|
func (c *Context) Int64(name string) int64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupInt64(c.resolveFlagDeep(name))
|
||||||
return lookupInt64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
func lookupInt64(f *flag.Flag) int64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -145,11 +145,10 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Int64Slice(name string) []int64 {
|
func (c *Context) Int64Slice(name string) []int64 {
|
||||||
return lookupInt64Slice(name, c.flagSet)
|
return lookupInt64Slice(c.resolveFlagDeep(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
func lookupInt64Slice(f *flag.Flag) []int64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*Int64Slice); ok {
|
if slice, ok := f.Value.(*Int64Slice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -156,14 +156,10 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) IntSlice(name string) []int {
|
func (c *Context) IntSlice(name string) []int {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupIntSlice(c.resolveFlagDeep(name))
|
||||||
return lookupIntSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
func lookupIntSlice(f *flag.Flag) []int {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*IntSlice); ok {
|
if slice, ok := f.Value.(*IntSlice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -75,15 +75,10 @@ func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Path looks up the value of a local PathFlag, returns
|
// Path looks up the value of a local PathFlag, returns
|
||||||
// "" if not found
|
// "" if not found
|
||||||
func (c *Context) Path(name string) string {
|
func (c *Context) Path(name string) string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupPath(c.resolveFlagDeep(name))
|
||||||
return lookupPath(name, fs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupPath(name string, set *flag.FlagSet) string {
|
func lookupPath(f *flag.Flag) string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value.String(), error(nil)
|
parsed, err := f.Value.String(), error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -76,14 +76,10 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||||
// String looks up the value of a local StringFlag, returns
|
// String looks up the value of a local StringFlag, returns
|
||||||
// "" if not found
|
// "" if not found
|
||||||
func (c *Context) String(name string) string {
|
func (c *Context) String(name string) string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupString(c.resolveFlagDeep(name))
|
||||||
return lookupString(name, fs)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupString(name string, set *flag.FlagSet) string {
|
func lookupString(f *flag.Flag) string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value.String(), error(nil)
|
parsed, err := f.Value.String(), error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -116,8 +116,17 @@ func (f *StringSliceFlag) GetValue() string {
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
|
|
||||||
|
if f.Destination != nil && f.Value != nil {
|
||||||
|
f.Destination.slice = make([]string, len(f.Value.slice))
|
||||||
|
copy(f.Destination.slice, f.Value.slice)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||||
|
if f.Value == nil {
|
||||||
f.Value = &StringSlice{}
|
f.Value = &StringSlice{}
|
||||||
|
}
|
||||||
destination := f.Value
|
destination := f.Value
|
||||||
if f.Destination != nil {
|
if f.Destination != nil {
|
||||||
destination = f.Destination
|
destination = f.Destination
|
||||||
|
@ -154,14 +163,10 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) StringSlice(name string) []string {
|
func (c *Context) StringSlice(name string) []string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupStringSlice(c.resolveFlagDeep(name))
|
||||||
return lookupStringSlice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
func lookupStringSlice(f *flag.Flag) []string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*StringSlice); ok {
|
if slice, ok := f.Value.(*StringSlice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -118,7 +118,9 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||||
if f.Layout == "" {
|
if f.Layout == "" {
|
||||||
return fmt.Errorf("timestamp Layout is required")
|
return fmt.Errorf("timestamp Layout is required")
|
||||||
}
|
}
|
||||||
|
if f.Value == nil {
|
||||||
f.Value = &Timestamp{}
|
f.Value = &Timestamp{}
|
||||||
|
}
|
||||||
f.Value.SetLayout(f.Layout)
|
f.Value.SetLayout(f.Layout)
|
||||||
|
|
||||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||||
|
@ -136,15 +138,11 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||||
|
|
||||||
// Timestamp gets the timestamp from a flag name
|
// Timestamp gets the timestamp from a flag name
|
||||||
func (c *Context) Timestamp(name string) *time.Time {
|
func (c *Context) Timestamp(name string) *time.Time {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupTimestamp(c.resolveFlagDeep(name))
|
||||||
return lookupTimestamp(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the timestamp value from the local timestampWrap
|
// Fetches the timestamp value from the local timestampWrap
|
||||||
func lookupTimestamp(name string, set *flag.FlagSet) *time.Time {
|
func lookupTimestamp(f *flag.Flag) *time.Time {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
return (f.Value.(*Timestamp)).Value()
|
return (f.Value.(*Timestamp)).Value()
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *UintFlag) GetValue() string {
|
||||||
// Uint looks up the value of a local UintFlag, returns
|
// Uint looks up the value of a local UintFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Uint(name string) uint {
|
func (c *Context) Uint(name string) uint {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupUint(c.resolveFlagDeep(name))
|
||||||
return lookupUint(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupUint(name string, set *flag.FlagSet) uint {
|
func lookupUint(f *flag.Flag) uint {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *Uint64Flag) GetValue() string {
|
||||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Uint64(name string) uint64 {
|
func (c *Context) Uint64(name string) uint64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupUint64(c.resolveFlagDeep(name))
|
||||||
return lookupUint64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
func lookupUint64(f *flag.Flag) uint64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,5 +5,5 @@ go 1.11
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
gopkg.in/yaml.v2 v2.2.3
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,5 +10,5 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -72,13 +72,13 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
|
||||||
|
|
||||||
// ShowAppHelp is an action that displays the help.
|
// ShowAppHelp is an action that displays the help.
|
||||||
func ShowAppHelp(c *Context) error {
|
func ShowAppHelp(c *Context) error {
|
||||||
template := c.App.CustomAppHelpTemplate
|
tpl := c.App.CustomAppHelpTemplate
|
||||||
if template == "" {
|
if tpl == "" {
|
||||||
template = AppHelpTemplate
|
tpl = AppHelpTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.App.ExtraInfo == nil {
|
if c.App.ExtraInfo == nil {
|
||||||
HelpPrinter(c.App.Writer, template, c.App)
|
HelpPrinter(c.App.Writer, tpl, c.App)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ func ShowAppHelp(c *Context) error {
|
||||||
"ExtraInfo": c.App.ExtraInfo,
|
"ExtraInfo": c.App.ExtraInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HelpPrinterCustom(c.App.Writer, template, c.App, customAppData())
|
HelpPrinterCustom(c.App.Writer, tpl, c.App, customAppData())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,12 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||||
|
func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
|
||||||
|
_ = ShowSubcommandHelp(c)
|
||||||
|
os.Exit(exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
// ShowSubcommandHelp prints help for the given subcommand
|
// ShowSubcommandHelp prints help for the given subcommand
|
||||||
func ShowSubcommandHelp(c *Context) error {
|
func ShowSubcommandHelp(c *Context) error {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
@ -264,6 +270,9 @@ func ShowCommandCompletions(ctx *Context, command string) {
|
||||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"join": strings.Join,
|
"join": strings.Join,
|
||||||
|
"indent": indent,
|
||||||
|
"nindent": nindent,
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
}
|
}
|
||||||
for key, value := range customFuncs {
|
for key, value := range customFuncs {
|
||||||
funcMap[key] = value
|
funcMap[key] = value
|
||||||
|
@ -366,3 +375,12 @@ func checkCommandCompletions(c *Context, name string) bool {
|
||||||
ShowCommandCompletions(c, name)
|
ShowCommandCompletions(c, name)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func indent(spaces int, v string) string {
|
||||||
|
pad := strings.Repeat(" ", spaces)
|
||||||
|
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nindent(spaces int, v string) string {
|
||||||
|
return "\n" + indent(spaces, v)
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ VERSION:
|
||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}{{if len .Authors}}
|
{{.Description | nindent 3 | trim}}{{end}}{{if len .Authors}}
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
{{range $index, $author := .Authors}}{{if $index}}
|
||||||
|
@ -45,7 +45,7 @@ CATEGORY:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}{{if .VisibleFlags}}
|
{{.Description | nindent 3 | trim}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}
|
||||||
|
@ -62,7 +62,7 @@ USAGE:
|
||||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}
|
{{.Description | nindent 3 | trim}}{{end}}
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
{{.Name}}:{{range .VisibleCommands}}
|
||||||
|
@ -74,7 +74,7 @@ OPTIONS:
|
||||||
{{end}}{{end}}
|
{{end}}{{end}}
|
||||||
`
|
`
|
||||||
|
|
||||||
var MarkdownDocTemplate = `% {{ .App.Name }} 8
|
var MarkdownDocTemplate = `% {{ .App.Name }} {{ .SectionNum }}
|
||||||
|
|
||||||
# NAME
|
# NAME
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ github.com/shurcooL/sanitized_anchor_name
|
||||||
## explicit
|
## explicit
|
||||||
github.com/stretchr/testify/assert
|
github.com/stretchr/testify/assert
|
||||||
github.com/stretchr/testify/require
|
github.com/stretchr/testify/require
|
||||||
# github.com/urfave/cli/v2 v2.2.0
|
# github.com/urfave/cli/v2 v2.2.0 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69
|
||||||
## explicit
|
## explicit
|
||||||
github.com/urfave/cli/v2
|
github.com/urfave/cli/v2
|
||||||
github.com/urfave/cli/v2/altsrc
|
github.com/urfave/cli/v2/altsrc
|
||||||
|
@ -431,3 +431,4 @@ zombiezen.com/go/capnproto2/rpc/internal/refcount
|
||||||
zombiezen.com/go/capnproto2/schemas
|
zombiezen.com/go/capnproto2/schemas
|
||||||
zombiezen.com/go/capnproto2/server
|
zombiezen.com/go/capnproto2/server
|
||||||
zombiezen.com/go/capnproto2/std/capnp/rpc
|
zombiezen.com/go/capnproto2/std/capnp/rpc
|
||||||
|
# github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69
|
||||||
|
|
Loading…
Reference in New Issue