add is set method to flag interface - refer #294
This commit is contained in:
parent
2746d8dee6
commit
ef1ba861f7
@ -13,6 +13,7 @@
|
||||
### Changed
|
||||
- `Context.FlagNames` now returns all flags in the context lineage
|
||||
- `Context.IsSet` now considers the full context lineage
|
||||
- Added `IsSet` method to the `Flag` interface which allows us to detect whether or not a flag has been set
|
||||
|
||||
### Removed
|
||||
- the ability to specify `&StringSlice{...string}` or `&IntSlice{...int}`.
|
||||
|
27
app.go
27
app.go
@ -14,8 +14,6 @@ import (
|
||||
var (
|
||||
changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md"
|
||||
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
|
||||
// unused variable. commented for now. will remove in future if agreed upon by everyone
|
||||
//runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL)
|
||||
|
||||
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
|
||||
|
||||
@ -89,7 +87,7 @@ type App struct {
|
||||
// render custom help text by setting this variable.
|
||||
CustomAppHelpTemplate string
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguements into one
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
|
||||
@ -182,11 +180,6 @@ func (a *App) Setup() {
|
||||
}
|
||||
}
|
||||
|
||||
//if a.EnableShellCompletion {
|
||||
// a.appendFlag(GenerateCompletionFlag)
|
||||
// a.appendFlag(InitCompletionFlag)
|
||||
//}
|
||||
|
||||
if !a.HideVersion {
|
||||
a.appendFlag(VersionFlag)
|
||||
}
|
||||
@ -246,14 +239,6 @@ func (a *App) Run(arguments []string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
//if done, cerr := checkInitCompletion(context); done {
|
||||
// if cerr != nil {
|
||||
// err = cerr
|
||||
// } else {
|
||||
// return nil
|
||||
// }
|
||||
//}
|
||||
|
||||
if err != nil {
|
||||
if a.OnUsageError != nil {
|
||||
err := a.OnUsageError(context, err, false)
|
||||
@ -361,17 +346,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
||||
}
|
||||
a.Commands = newCmds
|
||||
|
||||
//<<<<<<< HEAD
|
||||
// // append flags
|
||||
// if a.EnableShellCompletion {
|
||||
// a.appendFlag(GenerateCompletionFlag)
|
||||
// }
|
||||
//
|
||||
// // parse flags
|
||||
// set, err := flagSet(a.Name, a.Flags)
|
||||
//=======
|
||||
_, err = a.newFlagSet()
|
||||
//>>>>>>> master
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1993,6 +1993,10 @@ func (c *customBoolFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *customBoolFlag) IsSet() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func TestCustomFlagsUnused(t *testing.T) {
|
||||
app := &App{
|
||||
Flags: []Flag{&customBoolFlag{"custom"}},
|
||||
|
8
args.go
8
args.go
@ -1,11 +1,5 @@
|
||||
package cli
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
argsRangeErr = errors.New("index out of range")
|
||||
)
|
||||
|
||||
type Args interface {
|
||||
// Get returns the nth argument, or else a blank string
|
||||
Get(n int) string
|
||||
@ -55,6 +49,6 @@ func (a *args) Present() bool {
|
||||
|
||||
func (a *args) Slice() []string {
|
||||
ret := make([]string, len(*a))
|
||||
copy(ret, []string(*a))
|
||||
copy(ret, *a)
|
||||
return ret
|
||||
}
|
||||
|
@ -59,13 +59,6 @@ type commandCategory struct {
|
||||
commands []*Command
|
||||
}
|
||||
|
||||
func newCommandCategory(name string) *commandCategory {
|
||||
return &commandCategory{
|
||||
name: name,
|
||||
commands: []*Command{},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commandCategory) Name() string {
|
||||
return c.name
|
||||
}
|
||||
|
479
cli-v1-to-v2
479
cli-v1-to-v2
@ -1,479 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import argparse
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
_DESCRIPTION = """\
|
||||
Migrate arbitrary `.go` sources (mostly) from the v1 to v2 API.
|
||||
"""
|
||||
_MIGRATORS = []
|
||||
|
||||
|
||||
def main(sysargs=sys.argv[:]):
|
||||
parser = argparse.ArgumentParser(
|
||||
description=_DESCRIPTION,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('path', nargs='*',
|
||||
type=os.path.abspath, default=os.getcwd())
|
||||
parser.add_argument('-w', '--write', help='write changes back to file',
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('-q', '--quiet', help='quiet down the logging',
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('-D', '--debug', help='debug up the logging',
|
||||
action='store_true',
|
||||
default=(os.environ.get('DEBUG') != ''))
|
||||
parser.add_argument('--selftest', help='run internal tests',
|
||||
action='store_true', default=False)
|
||||
|
||||
args = parser.parse_args(sysargs[1:])
|
||||
|
||||
if args.selftest:
|
||||
logging.basicConfig(
|
||||
level=logging.WARN,
|
||||
format='selftest: %(message)s'
|
||||
)
|
||||
test_migrators()
|
||||
return 0
|
||||
|
||||
level = logging.FATAL if args.quiet else logging.INFO
|
||||
level = logging.DEBUG if args.debug else level
|
||||
|
||||
logging.basicConfig(level=level, format='%(message)s')
|
||||
|
||||
paths = args.path
|
||||
if len(paths) == 0:
|
||||
paths = ['.']
|
||||
|
||||
for filepath in _find_candidate_files(paths):
|
||||
updated_source = _update_filepath(filepath)
|
||||
if args.write:
|
||||
logging.info('Updating %s', filepath)
|
||||
|
||||
with io.open(filepath, 'w', encoding='utf-8') as outfile:
|
||||
outfile.write(updated_source)
|
||||
else:
|
||||
logging.info('// Updated %s:', filepath)
|
||||
print(updated_source)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def _find_candidate_files(paths):
|
||||
for path in paths:
|
||||
if not os.path.isdir(path):
|
||||
yield path
|
||||
continue
|
||||
|
||||
for curdir, dirs, files in os.walk(path):
|
||||
for i, dirname in enumerate(dirs[:]):
|
||||
if dirname.startswith('.'):
|
||||
dirs.pop(i)
|
||||
|
||||
for filename in files:
|
||||
if not filename.decode('utf-8').endswith('.go'):
|
||||
continue
|
||||
|
||||
filepath = os.path.join(curdir, filename)
|
||||
if not os.access(filepath, os.R_OK | os.W_OK):
|
||||
continue
|
||||
|
||||
yield filepath
|
||||
|
||||
|
||||
def _update_filepath(filepath):
|
||||
with io.open(filepath, encoding='utf-8') as infile:
|
||||
return _update_source(infile.read())
|
||||
|
||||
|
||||
def _update_source(source):
|
||||
for migrator, func in _MIGRATORS:
|
||||
logging.debug('Running %s migrator', migrator)
|
||||
source = func(source)
|
||||
return source
|
||||
|
||||
|
||||
def _subfmt(pattern, replfmt, source, flags=re.UNICODE):
|
||||
def repl(match):
|
||||
return replfmt.format(**match.groupdict())
|
||||
return re.sub(pattern, repl, source, flags=flags)
|
||||
|
||||
|
||||
def _migrator(func):
|
||||
_MIGRATORS.append((func.__name__.strip('_'), func))
|
||||
return func
|
||||
|
||||
|
||||
@_migrator
|
||||
def _slice_pointer_types(source):
|
||||
return _subfmt(
|
||||
'(?P<prefix>\\[\\])cli\\.(?P<type>Command|Author){',
|
||||
'{prefix}*cli.{type}{{', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _pointer_type_literal(source):
|
||||
return _subfmt(
|
||||
'(?P<prefix>\\s+)cli\\.(?P<type>Command|Author){',
|
||||
'{prefix}&cli.{type}{{', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _slice_types(source):
|
||||
return _subfmt(
|
||||
'&cli\\.(?P<type>IntSlice|StringSlice){(?P<args>[^}]*)}',
|
||||
'cli.New{type}({args})', source, flags=re.DOTALL | re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _flag_literals(source):
|
||||
return _subfmt(
|
||||
'(?P<prefix>\\s+)cli\\.(?P<type>\\w+)Flag{',
|
||||
'{prefix}&cli.{type}Flag{{', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _v1_imports(source):
|
||||
return re.sub(
|
||||
'"(?:github\\.com|gopkg\\.in)/(?:codegangsta|urfave)/cli(?:\\.v1|)"',
|
||||
'"gopkg.in/urfave/cli.v2"', source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _new_exit_error(source):
|
||||
return re.sub('cli\\.NewExitError', 'cli.Exit', source, flags=re.UNICODE)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _bool_t_flag(source):
|
||||
return _subfmt(
|
||||
'cli\\.BoolTFlag{(?P<args>[^}]*)}',
|
||||
'cli.BoolFlag{{Value: true,{args}}}',
|
||||
source, flags=re.DOTALL | re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _context_args_len(source):
|
||||
return _subfmt(
|
||||
'len\\((?P<prefix>\\S+)\\.Args\\(\\)\\)',
|
||||
'{prefix}.Args().Len()', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _context_args_index(source):
|
||||
return _subfmt(
|
||||
'\\.Args\\(\\)\\[(?P<index>\\d+)\\]',
|
||||
'.Args().Get({index})', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _envvar_string(source):
|
||||
return re.sub(
|
||||
'EnvVar:(?P<ws>\\s+)"(?P<string>[^"]+)"',
|
||||
_envvar_string_repl, source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
def _envvar_string_repl(match):
|
||||
return 'EnvVars:{ws}[]string{{{value}}}'.format(
|
||||
value=', '.join([
|
||||
'"{}"'.format(s) for s in
|
||||
re.split(
|
||||
'\\s*,\\s*', match.groupdict()['string'],
|
||||
flags=re.UNICODE
|
||||
)
|
||||
]),
|
||||
**match.groupdict()
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _flag_name_stringly(source):
|
||||
return re.sub(
|
||||
'(?P<prefix>\\s+)Name:(?P<ws>\\s+)"(?P<string>[^"]+)"',
|
||||
_flag_name_stringly_repl, source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
def _flag_name_stringly_repl(match):
|
||||
revars = dict(match.groupdict())
|
||||
|
||||
string = revars['string']
|
||||
parts = list(
|
||||
reversed(
|
||||
sorted(
|
||||
filter(lambda s: len(s.strip()) > 0, [
|
||||
part.strip() for part in string.split(',')
|
||||
]), key=len
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if len(parts) == 1:
|
||||
return '{prefix}Name:{ws}"{string}"'.format(**revars)
|
||||
|
||||
return (
|
||||
'{prefix}Name:{ws}"{name}", Aliases: []string{{{aliases}}}'
|
||||
).format(
|
||||
name=parts[0],
|
||||
aliases=', '.join(['"{}"'.format(s) for s in parts[1:]]),
|
||||
**revars
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _commands_opaque_type(source):
|
||||
return _subfmt(
|
||||
'cli\\.Commands(?P<suffix>[^B])',
|
||||
'[]*cli.Command{suffix}',
|
||||
source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _flag_names(source):
|
||||
return re.sub('\\.GetName\\(\\)', '.Names()[0]', source, flags=re.UNICODE)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _app_categories(source):
|
||||
source = _subfmt(
|
||||
'(?P<prefix>range\\s+\\S+)\\.App\\.Categories\\(\\)',
|
||||
'{prefix}.App.Categories.Categories()', source
|
||||
)
|
||||
|
||||
return re.sub(
|
||||
'\\.App\\.Categories\\(\\)', '.App.Categories',
|
||||
source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _command_category_commands(source):
|
||||
# XXX: brittle
|
||||
return _subfmt(
|
||||
'(?P<prefix>\\s+category\\.)Commands(?P<suffix>[^(])',
|
||||
'{prefix}VisibleCommands(){suffix}', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _context_bool_t(source):
|
||||
# XXX: probably brittle
|
||||
return _subfmt(
|
||||
'(?P<prefix>\\S+)(?:Global|)BoolT\\(',
|
||||
'!{prefix}Bool(', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _context_global_methods(source):
|
||||
return _subfmt(
|
||||
'\\.Global(?P<method>'
|
||||
'Bool|Duration|Float64|Generic|Int|IntSlice|String|StringSlice|'
|
||||
'FlagNames|IsSet|Set'
|
||||
')\\(',
|
||||
'.{method}(', source
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _context_parent(source):
|
||||
# XXX: brittle
|
||||
return re.sub('\\.Parent\\(\\)', '.Lineage()[1]', source, flags=re.UNICODE)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _app_init(source):
|
||||
return re.sub(
|
||||
'cli\\.NewApp\\(\\)', '(&cli.App{})', source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _bash_complete(source):
|
||||
return re.sub(
|
||||
'BashComplete:', 'ShellComplete:',
|
||||
re.sub('\\.BashComplete', '.ShellComplete', source, flags=re.UNICODE))
|
||||
|
||||
|
||||
@_migrator
|
||||
def _enable_bash_completion(source):
|
||||
return re.sub(
|
||||
'\\.EnableBashCompletion', '.EnableShellCompletion', source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
@_migrator
|
||||
def _bash_completion_flag(source):
|
||||
return re.sub(
|
||||
'cli\\.BashCompletionFlag', 'cli.GenerateCompletionFlag', source, flags=re.UNICODE
|
||||
)
|
||||
|
||||
|
||||
def test_migrators():
|
||||
import difflib
|
||||
|
||||
for i, (source, expected) in enumerate(_MIGRATOR_TESTS):
|
||||
actual = _update_source(source)
|
||||
if expected != actual:
|
||||
udiff = difflib.unified_diff(
|
||||
expected.splitlines(), actual.splitlines(),
|
||||
fromfile='a/source.go', tofile='b/source.go', lineterm=''
|
||||
)
|
||||
for line in udiff:
|
||||
print(line)
|
||||
raise AssertionError('migrated source does not match expected')
|
||||
logging.warn('Test case %d/%d OK', i+1, len(_MIGRATOR_TESTS))
|
||||
|
||||
|
||||
_MIGRATOR_TESTS = (
|
||||
("""
|
||||
\t\t\t&cli.StringSlice{"a", "b", "c"},
|
||||
""", """
|
||||
\t\t\tcli.NewStringSlice("a", "b", "c"),
|
||||
"""),
|
||||
("""
|
||||
\t\tcli.IntFlag{
|
||||
\t\t\tName: "yep",
|
||||
\t\t\tValue: 3,
|
||||
\t\t}
|
||||
""", """
|
||||
\t\t&cli.IntFlag{
|
||||
\t\t\tName: "yep",
|
||||
\t\t\tValue: 3,
|
||||
\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\tapp.Commands = []cli.Command{
|
||||
\t\t\t{
|
||||
\t\t\t\tName: "whatebbs",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
""", """
|
||||
\t\tapp.Commands = []*cli.Command{
|
||||
\t\t\t{
|
||||
\t\t\t\tName: "whatebbs",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\tapp.Commands = []cli.Command{
|
||||
\t\t\tcli.Command{
|
||||
\t\t\t\tName: "whatebbs",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
""", """
|
||||
\t\tapp.Commands = []*cli.Command{
|
||||
\t\t\t&cli.Command{
|
||||
\t\t\t\tName: "whatebbs",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t"github.com/codegangsta/cli"
|
||||
\t"github.com/urfave/cli"
|
||||
\t"gopkg.in/codegangsta/cli"
|
||||
\t"gopkg.in/codegangsta/cli.v1"
|
||||
\t"gopkg.in/urfave/cli"
|
||||
\t"gopkg.in/urfave/cli.v1"
|
||||
""", """
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
\t"gopkg.in/urfave/cli.v2"
|
||||
"""),
|
||||
("""
|
||||
\t\t\t\treturn cli.NewExitError("foo whatebber", 9)
|
||||
""", """
|
||||
\t\t\t\treturn cli.Exit("foo whatebber", 9)
|
||||
"""),
|
||||
("""
|
||||
\t\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\t\tcli.StringFlag{
|
||||
\t\t\t\t\tName: "aha",
|
||||
\t\t\t\t},
|
||||
\t\t\t\tcli.BoolTFlag{
|
||||
\t\t\t\t\tName: "blurp",
|
||||
\t\t\t\t},
|
||||
\t\t\t}
|
||||
""", """
|
||||
\t\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\t\t&cli.StringFlag{
|
||||
\t\t\t\t\tName: "aha",
|
||||
\t\t\t\t},
|
||||
\t\t\t\t&cli.BoolFlag{Value: true,
|
||||
\t\t\t\t\tName: "blurp",
|
||||
\t\t\t\t},
|
||||
\t\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\t\tAction = func(c *cli.Context) error {
|
||||
\t\t\t\tif c.Args()[4] == "meep" {
|
||||
\t\t\t\t\treturn nil
|
||||
\t\t\t\t}
|
||||
\t\t\t\treturn errors.New("mope")
|
||||
\t\t\t}
|
||||
""", """
|
||||
\t\t\tAction = func(c *cli.Context) error {
|
||||
\t\t\t\tif c.Args().Get(4) == "meep" {
|
||||
\t\t\t\t\treturn nil
|
||||
\t\t\t\t}
|
||||
\t\t\t\treturn errors.New("mope")
|
||||
\t\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\tcli.StringFlag{
|
||||
\t\t\t\tName: "toots",
|
||||
\t\t\t\tEnvVar: "TOOTS,TOOTERS",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
""", """
|
||||
\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\t&cli.StringFlag{
|
||||
\t\t\t\tName: "toots",
|
||||
\t\t\t\tEnvVars: []string{"TOOTS", "TOOTERS"},
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\tcli.StringFlag{
|
||||
\t\t\t\tName: "t, tootles, toots",
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
""", """
|
||||
\t\tapp.Flags = []cli.Flag{
|
||||
\t\t\t&cli.StringFlag{
|
||||
\t\t\t\tName: "tootles", Aliases: []string{"toots", "t"},
|
||||
\t\t\t},
|
||||
\t\t}
|
||||
"""),
|
||||
("""
|
||||
\t\tapp := cli.NewApp()
|
||||
\t\tapp.HideHelp = true
|
||||
""", """
|
||||
\t\tapp := (&cli.App{})
|
||||
\t\tapp.HideHelp = true
|
||||
""")
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
35
context.go
35
context.go
@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"reflect"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
@ -91,23 +90,25 @@ func (c *Context) IsSet(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
val := reflect.ValueOf(f)
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
//val := reflect.ValueOf(f)
|
||||
//if val.Kind() == reflect.Ptr {
|
||||
// val = val.Elem()
|
||||
//}
|
||||
//
|
||||
//filePathValue := val.FieldByName("FilePath")
|
||||
//if !filePathValue.IsValid() {
|
||||
// return false
|
||||
//}
|
||||
//
|
||||
//envVarValues := val.FieldByName("EnvVars")
|
||||
//if !envVarValues.IsValid() {
|
||||
// return false
|
||||
//}
|
||||
//
|
||||
//_, ok := flagFromEnvOrFile(envVarValues.Interface().([]string), filePathValue.Interface().(string))
|
||||
//return ok
|
||||
|
||||
filePathValue := val.FieldByName("FilePath")
|
||||
if !filePathValue.IsValid() {
|
||||
return false
|
||||
}
|
||||
|
||||
envVarValues := val.FieldByName("EnvVars")
|
||||
if !envVarValues.IsValid() {
|
||||
return false
|
||||
}
|
||||
|
||||
_, ok := flagFromEnvOrFile(envVarValues.Interface().([]string), filePathValue.Interface().(string))
|
||||
return ok
|
||||
return f.IsSet()
|
||||
}
|
||||
|
||||
return false
|
||||
|
@ -222,75 +222,6 @@ func TestContext_IsSet_fromEnv(t *testing.T) {
|
||||
expect(t, uIsSet, false)
|
||||
}
|
||||
|
||||
// XXX Corresponds to hack in context.IsSet for flags with EnvVar field
|
||||
// TODO: Should be moved to `flag_test` in v2
|
||||
//func TestContext_GlobalIsSet_fromEnv(t *testing.T) {
|
||||
// var (
|
||||
// timeoutIsSet, tIsSet bool
|
||||
// noEnvVarIsSet, nIsSet bool
|
||||
// passwordIsSet, pIsSet bool
|
||||
// passwordValue string
|
||||
// unparsableIsSet, uIsSet bool
|
||||
// overrideIsSet, oIsSet bool
|
||||
// overrideValue string
|
||||
// )
|
||||
//
|
||||
// os.Clearenv()
|
||||
// _ = os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
|
||||
// _ = os.Setenv("APP_PASSWORD", "badpass")
|
||||
// _ = os.Setenv("APP_OVERRIDE", "overridden")
|
||||
// a := App{
|
||||
// Flags: []Flag{
|
||||
// Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
|
||||
// StringFlag{Name: "password, p", EnvVar: "APP_PASSWORD"},
|
||||
// Float64Flag{Name: "no-env-var, n"},
|
||||
// Float64Flag{Name: "unparsable, u", EnvVar: "APP_UNPARSABLE"},
|
||||
// StringFlag{Name: "overrides-default, o", Value: "default", EnvVar: "APP_OVERRIDE"},
|
||||
// },
|
||||
// Commands: []Command{
|
||||
// {
|
||||
// Name: "hello",
|
||||
// Action: func(ctx *Context) error {
|
||||
// timeoutIsSet = ctx.GlobalIsSet("timeout")
|
||||
// tIsSet = ctx.GlobalIsSet("t")
|
||||
// passwordIsSet = ctx.GlobalIsSet("password")
|
||||
// pIsSet = ctx.GlobalIsSet("p")
|
||||
// passwordValue = ctx.GlobalString("password")
|
||||
// unparsableIsSet = ctx.GlobalIsSet("unparsable")
|
||||
// uIsSet = ctx.GlobalIsSet("u")
|
||||
// noEnvVarIsSet = ctx.GlobalIsSet("no-env-var")
|
||||
// nIsSet = ctx.GlobalIsSet("n")
|
||||
// overrideIsSet = ctx.GlobalIsSet("overrides-default")
|
||||
// oIsSet = ctx.GlobalIsSet("o")
|
||||
// overrideValue = ctx.GlobalString("overrides-default")
|
||||
// return nil
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// if err := a.Run([]string{"run", "hello"}); err != nil {
|
||||
// t.Logf("error running Run(): %+v", err)
|
||||
// }
|
||||
// expect(t, timeoutIsSet, true)
|
||||
// expect(t, tIsSet, true)
|
||||
// expect(t, passwordIsSet, true)
|
||||
// expect(t, pIsSet, true)
|
||||
// expect(t, passwordValue, "badpass")
|
||||
// expect(t, unparsableIsSet, false)
|
||||
// expect(t, noEnvVarIsSet, false)
|
||||
// expect(t, nIsSet, false)
|
||||
// expect(t, overrideIsSet, true)
|
||||
// expect(t, oIsSet, true)
|
||||
// expect(t, overrideValue, "overridden")
|
||||
//
|
||||
// _ = os.Setenv("APP_UNPARSABLE", "foobar")
|
||||
// if err := a.Run([]string{"run"}); err != nil {
|
||||
// t.Logf("error running Run(): %+v", err)
|
||||
// }
|
||||
// expect(t, unparsableIsSet, false)
|
||||
// expect(t, uIsSet, false)
|
||||
//}
|
||||
|
||||
func TestContext_NumFlags(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("myflag", false, "doc")
|
||||
@ -323,8 +254,8 @@ func TestContext_LocalFlagNames(t *testing.T) {
|
||||
parentSet.Bool("top-flag", true, "doc")
|
||||
parentCtx := NewContext(nil, parentSet, nil)
|
||||
ctx := NewContext(nil, set, parentCtx)
|
||||
set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||
parentSet.Parse([]string{"--top-flag"})
|
||||
_ = set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||
_ = parentSet.Parse([]string{"--top-flag"})
|
||||
|
||||
actualFlags := ctx.LocalFlagNames()
|
||||
sort.Strings(actualFlags)
|
||||
@ -340,8 +271,8 @@ func TestContext_FlagNames(t *testing.T) {
|
||||
parentSet.Bool("top-flag", true, "doc")
|
||||
parentCtx := NewContext(nil, parentSet, nil)
|
||||
ctx := NewContext(nil, set, parentCtx)
|
||||
set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||
parentSet.Parse([]string{"--top-flag"})
|
||||
_ = set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||
_ = parentSet.Parse([]string{"--top-flag"})
|
||||
|
||||
actualFlags := ctx.FlagNames()
|
||||
sort.Strings(actualFlags)
|
||||
@ -356,8 +287,8 @@ func TestContext_Lineage(t *testing.T) {
|
||||
parentSet.Bool("top-flag", true, "doc")
|
||||
parentCtx := NewContext(nil, parentSet, nil)
|
||||
ctx := NewContext(nil, set, parentCtx)
|
||||
set.Parse([]string{"--local-flag"})
|
||||
parentSet.Parse([]string{"--top-flag"})
|
||||
_ = set.Parse([]string{"--local-flag"})
|
||||
_ = parentSet.Parse([]string{"--top-flag"})
|
||||
|
||||
lineage := ctx.Lineage()
|
||||
expect(t, len(lineage), 2)
|
||||
@ -372,8 +303,8 @@ func TestContext_lookupFlagSet(t *testing.T) {
|
||||
parentSet.Bool("top-flag", true, "doc")
|
||||
parentCtx := NewContext(nil, parentSet, nil)
|
||||
ctx := NewContext(nil, set, parentCtx)
|
||||
set.Parse([]string{"--local-flag"})
|
||||
parentSet.Parse([]string{"--top-flag"})
|
||||
_ = set.Parse([]string{"--local-flag"})
|
||||
_ = parentSet.Parse([]string{"--top-flag"})
|
||||
|
||||
fs := lookupFlagSet("top-flag", ctx)
|
||||
expect(t, fs, parentCtx.flagSet)
|
||||
@ -534,15 +465,17 @@ func TestCheckRequiredFlags(t *testing.T) {
|
||||
for _, test := range tdata {
|
||||
t.Run(test.testCase, func(t *testing.T) {
|
||||
// setup
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
for _, flags := range test.flags {
|
||||
flags.Apply(set)
|
||||
}
|
||||
_ = set.Parse(test.parseInput)
|
||||
if test.envVarInput[0] != "" {
|
||||
os.Clearenv()
|
||||
_ = os.Setenv(test.envVarInput[0], test.envVarInput[1])
|
||||
}
|
||||
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
for _, flags := range test.flags {
|
||||
_ = flags.Apply(set)
|
||||
}
|
||||
_ = set.Parse(test.parseInput)
|
||||
|
||||
c := &Context{}
|
||||
ctx := NewContext(c.App, set, c)
|
||||
ctx.Command.Flags = test.flags
|
||||
@ -558,10 +491,12 @@ func TestCheckRequiredFlags(t *testing.T) {
|
||||
t.Errorf("did not expected an error, but there was one: %s", err)
|
||||
}
|
||||
for _, errString := range test.expectedErrorContents {
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), errString) {
|
||||
t.Errorf("expected error %q to contain %q, but it didn't!", err.Error(), errString)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
35
flag.go
35
flag.go
@ -21,26 +21,6 @@ var (
|
||||
commaWhitespace = regexp.MustCompile("[, ]+.*")
|
||||
)
|
||||
|
||||
// GenerateCompletionFlag enables completion for all commands and subcommands
|
||||
//var GenerateCompletionFlag Flag = &BoolFlag{
|
||||
// Name: "generate-completion",
|
||||
// Hidden: true,
|
||||
//}
|
||||
//
|
||||
//func genCompName() string {
|
||||
// names := GenerateCompletionFlag.Names()
|
||||
// if len(names) == 0 {
|
||||
// return "generate-completion"
|
||||
// }
|
||||
// return names[0]
|
||||
//}
|
||||
//
|
||||
//// InitCompletionFlag generates completion code
|
||||
//var InitCompletionFlag = &StringFlag{
|
||||
// Name: "init-completion",
|
||||
// Usage: "generate completion code. Value must be 'bash' or 'zsh'",
|
||||
//}
|
||||
|
||||
// BashCompletionFlag enables bash-completion for all commands and subcommands
|
||||
var BashCompletionFlag Flag = &BoolFlag{
|
||||
Name: "generate-bash-completion",
|
||||
@ -92,16 +72,12 @@ func (f FlagsByName) Len() int {
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
//<<<<<<< HEAD
|
||||
if len(f[j].Names()) == 0 {
|
||||
return false
|
||||
} else if len(f[i].Names()) == 0 {
|
||||
return true
|
||||
}
|
||||
return f[i].Names()[0] < f[j].Names()[0]
|
||||
//=======
|
||||
// return lexicographicLess(f[i].GetName(), f[j].GetName())
|
||||
//>>>>>>> master
|
||||
return lexicographicLess(f[i].Names()[0], f[j].Names()[0])
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
@ -116,6 +92,7 @@ type Flag interface {
|
||||
// Apply Flag settings to the given flag set
|
||||
Apply(*flag.FlagSet) error
|
||||
Names() []string
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// RequiredFlag is an interface that allows us to mark flags as required
|
||||
@ -153,14 +130,6 @@ func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
||||
return set, nil
|
||||
}
|
||||
|
||||
func eachName(longName string, fn func(string)) {
|
||||
parts := strings.Split(longName, ",")
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
fn(name)
|
||||
}
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
|
19
flag_bool.go
19
flag_bool.go
@ -18,6 +18,12 @@ type BoolFlag struct {
|
||||
Value bool
|
||||
DefaultText string
|
||||
Destination *bool
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *BoolFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -57,10 +63,13 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valBool, err := strconv.ParseBool(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as bool value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valBool
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,16 +93,6 @@ func (c *Context) Bool(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GlobalBool looks up the value of a global BoolFlag, returns
|
||||
// false if not found
|
||||
//func (c *Context) GlobalBool(name string) bool {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupBool(name, fs)
|
||||
// }
|
||||
// return false
|
||||
//}
|
||||
|
||||
// TODO: Fix Duplicate
|
||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -18,6 +18,12 @@ type DurationFlag struct {
|
||||
Value time.Duration
|
||||
DefaultText string
|
||||
Destination *time.Duration
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *DurationFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -55,12 +61,15 @@ func (f *DurationFlag) GetValue() string {
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != ""{
|
||||
if val != "" {
|
||||
valDuration, err := time.ParseDuration(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as duration value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valDuration
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,14 +91,6 @@ func (c *Context) Duration(name string) time.Duration {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
// GlobalDuration looks up the value of a global DurationFlag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalDuration(name string) time.Duration {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupDuration(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
||||
f := set.Lookup(name)
|
||||
|
@ -18,6 +18,12 @@ type Float64Flag struct {
|
||||
Value float64
|
||||
DefaultText string
|
||||
Destination *float64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64Flag)IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -57,10 +63,13 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valFloat, err := strconv.ParseFloat(val, 10)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valFloat
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +93,6 @@ func (c *Context) Float64(name string) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GlobalFloat64 looks up the value of a global Float64Flag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalFloat64(name string) float64 {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupFloat64(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -74,6 +74,12 @@ type Float64SliceFlag struct {
|
||||
Hidden bool
|
||||
Value *Float64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -114,6 +120,7 @@ func (f *Float64SliceFlag) GetValue() string {
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
f.Value = &Float64Slice{}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
@ -121,6 +128,9 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return fmt.Errorf("could not parse %q as float64 slice value for flag %s: %s", f.Value, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
@ -142,15 +152,6 @@ func (c *Context) Float64Slice(name string) []float64 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GlobalFloat64Slice looks up the value of a global Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
//func (c *Context) GlobalFloat64Slice(name string) []int {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupFloat64Slice(name, fs)
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -23,6 +23,12 @@ type GenericFlag struct {
|
||||
TakesFile bool
|
||||
Value Generic
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *GenericFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -64,9 +70,13 @@ func (f *GenericFlag) GetValue() string {
|
||||
// provided by the user for parsing by the flag
|
||||
func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
if err := f.Value.Set(val); err != nil {
|
||||
return fmt.Errorf("could not parse %q as value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
@ -79,18 +89,12 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) Generic(name string) interface{} {
|
||||
return lookupGeneric(name, c.flagSet)
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
return lookupGeneric(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GlobalGeneric looks up the value of a global GenericFlag, returns
|
||||
// nil if not found
|
||||
//func (c *Context) GlobalGeneric(name string) interface{} {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupGeneric(name, fs)
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
18
flag_int.go
18
flag_int.go
@ -18,6 +18,12 @@ type IntFlag struct {
|
||||
Value int
|
||||
DefaultText string
|
||||
Destination *int
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -57,10 +63,13 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, 0, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = int(valInt)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +93,6 @@ func (c *Context) Int(name string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GlobalInt looks up the value of a global IntFlag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalInt(name string) int {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupInt(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupInt(name string, set *flag.FlagSet) int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -18,6 +18,12 @@ type Int64Flag struct {
|
||||
Value int64
|
||||
DefaultText string
|
||||
Destination *int64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -57,10 +63,13 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, 0, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +93,6 @@ func (c *Context) Int64(name string) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GlobalInt64 looks up the value of a global Int64Flag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalInt64(name string) int64 {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupInt64(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -74,6 +74,12 @@ type Int64SliceFlag struct {
|
||||
Hidden bool
|
||||
Value *Int64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -121,6 +127,8 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
@ -142,15 +150,6 @@ func (c *Context) Int64Slice(name string) []int64 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
//func (c *Context) GlobalInt64Slice(name string) []int {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupInt64Slice(name, fs)
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -85,6 +85,12 @@ type IntSliceFlag struct {
|
||||
Hidden bool
|
||||
Value *IntSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -132,6 +138,8 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
@ -153,15 +161,6 @@ func (c *Context) IntSlice(name string) []int {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GlobalIntSlice looks up the value of a global IntSliceFlag, returns
|
||||
// nil if not found
|
||||
//func (c *Context) GlobalIntSlice(name string) []int {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupIntSlice(name, fs)
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -14,6 +14,12 @@ type PathFlag struct {
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *PathFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -52,6 +58,7 @@ func (f *PathFlag) GetValue() string {
|
||||
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
|
@ -15,52 +15,59 @@ type StringFlag struct {
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (s *StringFlag) String() string {
|
||||
return FlagStringer(s)
|
||||
func (f *StringFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (s *StringFlag) Names() []string {
|
||||
return flagNames(s)
|
||||
func (f *StringFlag) Names() []string {
|
||||
return flagNames(f)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (s *StringFlag) IsRequired() bool {
|
||||
return s.Required
|
||||
func (f *StringFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (s *StringFlag) TakesValue() bool {
|
||||
func (f *StringFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (s *StringFlag) GetUsage() string {
|
||||
return s.Usage
|
||||
func (f *StringFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (s *StringFlag) GetValue() string {
|
||||
return s.Value
|
||||
func (f *StringFlag) GetValue() string {
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (s *StringFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(s.EnvVars, s.FilePath); ok {
|
||||
s.Value = val
|
||||
func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range s.Names() {
|
||||
if s.Destination != nil {
|
||||
set.StringVar(s.Destination, name, s.Value, s.Usage)
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.String(name, s.Value, s.Usage)
|
||||
set.String(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -75,15 +82,6 @@ func (c *Context) String(name string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GlobalString looks up the value of a global StringFlag, returns
|
||||
// "" if not found
|
||||
//func (c *Context) GlobalString(name string) string {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupPath(name, fs)
|
||||
// }
|
||||
// return ""
|
||||
//}
|
||||
|
||||
func lookupString(name string, set *flag.FlagSet) string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -69,6 +69,12 @@ type StringSliceFlag struct {
|
||||
TakesFile bool
|
||||
Value *StringSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -110,11 +116,14 @@ func (f *StringSliceFlag) GetValue() string {
|
||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
f.Value = &StringSlice{}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as string value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
@ -136,15 +145,6 @@ func (c *Context) StringSlice(name string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GlobalStringSlice looks up the value of a global StringSliceFlag, returns
|
||||
// nil if not found
|
||||
//func (c *Context) GlobalStringSlice(name string) []string {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupStringSlice(name, fs)
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
16
flag_uint.go
16
flag_uint.go
@ -18,6 +18,12 @@ type UintFlag struct {
|
||||
Value uint
|
||||
DefaultText string
|
||||
Destination *uint
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -56,6 +62,7 @@ func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
||||
}
|
||||
|
||||
f.Value = uint(valInt)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,15 +92,6 @@ func (c *Context) Uint(name string) uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GlobalUint looks up the value of a global UintFlag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalUint(name string) uint {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupUint(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupUint(name string, set *flag.FlagSet) uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
@ -18,6 +18,12 @@ type Uint64Flag struct {
|
||||
Value uint64
|
||||
DefaultText string
|
||||
Destination *uint64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
@ -56,6 +62,7 @@ func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,15 +92,6 @@ func (c *Context) Uint64(name string) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GlobalUint64 looks up the value of a global Uint64Flag, returns
|
||||
// 0 if not found
|
||||
//func (c *Context) GlobalUint64(name string) uint64 {
|
||||
// if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
// return lookupUint64(name, fs)
|
||||
// }
|
||||
// return 0
|
||||
//}
|
||||
|
||||
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user