1
0
Fork 0
mirror of https://github.com/vbatts/go-mtree.git synced 2025-06-30 21:28:28 +00:00

go: update modules

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2022-07-05 09:02:09 -04:00
parent 00deb3ada6
commit 9e437eee80
Signed by: vbatts
GPG key ID: 10937E57733F1362
166 changed files with 9373 additions and 3493 deletions

View file

@ -1,9 +1,10 @@
*.coverprofile
*.orig
node_modules/
vendor
.idea
internal/*/built-example
coverage.txt
/.local/
/site/
*.exe

View file

@ -55,11 +55,12 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting Dan Buch at dan@meatballhat.com. All complaints will be
reviewed and investigated and will result in a response that is deemed necessary
and appropriate to the circumstances. The project team is obligated to maintain
confidentiality with regard to the reporter of an incident. Further details of
specific enforcement policies may be posted separately.
reported by contacting urfave-governance@googlegroups.com, a members-only group
that is world-postable. All complaints will be reviewed and investigated and
will result in a response that is deemed necessary and appropriate to the
circumstances. The project team is obligated to maintain confidentiality with
regard to the reporter of an incident. Further details of specific enforcement
policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2016 Jeremy Saenz & Contributors
Copyright (c) 2022 urfave/cli maintainers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

40
vendor/github.com/urfave/cli/v2/Makefile generated vendored Normal file
View file

@ -0,0 +1,40 @@
# NOTE: this Makefile is meant to provide a simplified entry point for humans to
# run all of the critical steps to verify one's changes are harmonious in
# nature. Keeping target bodies to one line each and abstaining from make magic
# are very important so that maintainers and contributors can focus their
# attention on files that are primarily Go.
.PHONY: all
all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun v2diff
# NOTE: this is a special catch-all rule to run any of the commands
# defined in internal/build/build.go with optional arguments passed
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
#
# $ make test GFLAGS='--packages cli'
%:
go run internal/build/build.go $(GFLAGS) $* $(FLAGS)
.PHONY: tag-test
tag-test:
go run internal/build/build.go -tags urfave_cli_no_docs test
.PHONY: tag-check-binary-size
tag-check-binary-size:
go run internal/build/build.go -tags urfave_cli_no_docs check-binary-size
.PHONY: gfmrun
gfmrun:
go run internal/build/build.go gfmrun docs/v2/manual.md
.PHONY: docs
docs:
mkdocs build
.PHONY: docs-deps
docs-deps:
pip install -r mkdocs-requirements.txt
.PHONY: serve-docs
serve-docs:
mkdocs serve

View file

@ -1,70 +1,19 @@
cli
===
# 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)
[![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/main/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
cli is a simple, fast, and fun package for building command line apps in Go. The
goal is to enable developers to write fast and distributable command line
applications in an expressive way.
## Usage Documentation
## Documentation
Usage documentation exists for each major version. Don't know what version you're on? You're probably using the version from the `master` branch, which is currently `v2`.
More documentation is available in [`./docs`](./docs) or the hosted
documentation site at <https://cli.urfave.org>.
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
## License
Guides for migrating to newer versions:
- `v1-to-v2` - [./docs/migrate-v1-to-v2.md](./docs/migrate-v1-to-v2.md)
## Installation
Using this package requires a working Go environment. [See the install instructions for Go](http://golang.org/doc/install.html).
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
```
$ GO111MODULE=on go get github.com/urfave/cli/v2
```
```go
...
import (
"github.com/urfave/cli/v2" // imports as package "cli"
)
...
```
### Using `v1` releases
```
$ GO111MODULE=on go get github.com/urfave/cli
```
```go
...
import (
"github.com/urfave/cli"
)
...
```
### GOPATH
Make sure your `PATH` includes the `$GOPATH/bin` directory so your commands can
be easily used:
```
export PATH=$PATH:$GOPATH/bin
```
### Supported platforms
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
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).
See [`LICENSE`](./LICENSE)

View file

@ -11,13 +11,19 @@ import (
"time"
)
const suggestDidYouMeanTemplate = "Did you mean %q?"
var (
changeLogURL = "https://github.com/urfave/cli/blob/master/docs/CHANGELOG.md"
changeLogURL = "https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md"
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
errInvalidActionType = NewExitError("ERROR invalid Action type. "+
fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+
fmt.Sprintf("See %s", appActionDeprecationURL), 2)
SuggestFlag SuggestFlagFunc = suggestFlag
SuggestCommand SuggestCommandFunc = suggestCommand
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
)
// App is the main structure of a cli application. It is recommended that
@ -52,6 +58,8 @@ type App struct {
HideVersion bool
// categories contains the categorized commands and is populated on app startup
categories CommandCategories
// flagCategories contains the categorized flags and is populated on app startup
flagCategories FlagCategories
// An action to execute when the shell completion flag is set
BashComplete BashCompleteFunc
// An action to execute before any subcommands are run, but after the context is ready
@ -94,10 +102,16 @@ type App struct {
// single-character bool arguments into one
// i.e. foobar -o -v -> foobar -ov
UseShortOptionHandling bool
// Enable suggestions for commands and flags
Suggest bool
didSetup bool
}
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
type SuggestCommandFunc func(commands []*Command, provided string) string
// Tries to find out when this binary was compiled.
// Returns the current time if it fails to find it.
func compileTime() time.Time {
@ -181,6 +195,8 @@ func (a *App) Setup() {
if c.HelpName == "" {
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
}
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
newCommands = append(newCommands, c)
}
a.Commands = newCommands
@ -205,6 +221,13 @@ func (a *App) Setup() {
}
sort.Sort(a.categories.(*commandCategories))
a.flagCategories = newFlagCategories()
for _, fl := range a.Flags {
if cf, ok := fl.(CategorizableFlag); ok {
a.flagCategories.AddFlag(cf.GetCategory(), cf)
}
}
if a.Metadata == nil {
a.Metadata = make(map[string]interface{})
}
@ -245,48 +268,53 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
err = parseIter(set, a, arguments[1:], shellComplete)
nerr := normalizeFlags(a.Flags, set)
context := NewContext(a, set, &Context{Context: ctx})
cCtx := NewContext(a, set, &Context{Context: ctx})
if nerr != nil {
_, _ = fmt.Fprintln(a.Writer, nerr)
_ = ShowAppHelp(context)
_ = ShowAppHelp(cCtx)
return nerr
}
context.shellComplete = shellComplete
cCtx.shellComplete = shellComplete
if checkCompletions(context) {
if checkCompletions(cCtx) {
return nil
}
if err != nil {
if a.OnUsageError != nil {
err := a.OnUsageError(context, err, false)
a.handleExitCoder(context, err)
err := a.OnUsageError(cCtx, err, false)
a.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
_ = ShowAppHelp(context)
if a.Suggest {
if suggestion, err := a.suggestFlagFromError(err, ""); err == nil {
fmt.Fprintf(a.Writer, suggestion)
}
}
_ = ShowAppHelp(cCtx)
return err
}
if !a.HideHelp && checkHelp(context) {
_ = ShowAppHelp(context)
if !a.HideHelp && checkHelp(cCtx) {
_ = ShowAppHelp(cCtx)
return nil
}
if !a.HideVersion && checkVersion(context) {
ShowVersion(context)
if !a.HideVersion && checkVersion(cCtx) {
ShowVersion(cCtx)
return nil
}
cerr := context.checkRequiredFlags(a.Flags)
cerr := cCtx.checkRequiredFlags(a.Flags)
if cerr != nil {
_ = ShowAppHelp(context)
_ = ShowAppHelp(cCtx)
return cerr
}
if a.After != nil {
defer func() {
if afterErr := a.After(context); afterErr != nil {
if afterErr := a.After(cCtx); afterErr != nil {
if err != nil {
err = newMultiError(err, afterErr)
} else {
@ -297,20 +325,20 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
}
if a.Before != nil {
beforeErr := a.Before(context)
beforeErr := a.Before(cCtx)
if beforeErr != nil {
a.handleExitCoder(context, beforeErr)
a.handleExitCoder(cCtx, beforeErr)
err = beforeErr
return err
}
}
args := context.Args()
args := cCtx.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(context)
return c.Run(cCtx)
}
}
@ -319,12 +347,35 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
}
// Run default Action
err = a.Action(context)
err = a.Action(cCtx)
a.handleExitCoder(context, err)
a.handleExitCoder(cCtx, err)
return err
}
func (a *App) suggestFlagFromError(err error, command string) (string, error) {
flag, parseErr := flagFromError(err)
if parseErr != nil {
return "", err
}
flags := a.Flags
if command != "" {
cmd := a.Command(command)
if cmd == nil {
return "", err
}
flags = cmd.Flags
}
suggestion := SuggestFlag(flags, flag, a.HideHelp)
if len(suggestion) == 0 {
return "", err
}
return fmt.Sprintf(SuggestDidYouMeanTemplate+"\n\n", suggestion), nil
}
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
//
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
@ -359,55 +410,60 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete)
nerr := normalizeFlags(a.Flags, set)
context := NewContext(a, set, ctx)
cCtx := NewContext(a, set, ctx)
if nerr != nil {
_, _ = fmt.Fprintln(a.Writer, nerr)
_, _ = fmt.Fprintln(a.Writer)
if len(a.Commands) > 0 {
_ = ShowSubcommandHelp(context)
_ = ShowSubcommandHelp(cCtx)
} else {
_ = ShowCommandHelp(ctx, context.Args().First())
_ = ShowCommandHelp(ctx, cCtx.Args().First())
}
return nerr
}
if checkCompletions(context) {
if checkCompletions(cCtx) {
return nil
}
if err != nil {
if a.OnUsageError != nil {
err = a.OnUsageError(context, err, true)
a.handleExitCoder(context, err)
err = a.OnUsageError(cCtx, err, true)
a.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
_ = ShowSubcommandHelp(context)
if a.Suggest {
if suggestion, err := a.suggestFlagFromError(err, cCtx.Command.Name); err == nil {
fmt.Fprintf(a.Writer, suggestion)
}
}
_ = ShowSubcommandHelp(cCtx)
return err
}
if len(a.Commands) > 0 {
if checkSubcommandHelp(context) {
if checkSubcommandHelp(cCtx) {
return nil
}
} else {
if checkCommandHelp(ctx, context.Args().First()) {
if checkCommandHelp(ctx, cCtx.Args().First()) {
return nil
}
}
cerr := context.checkRequiredFlags(a.Flags)
cerr := cCtx.checkRequiredFlags(a.Flags)
if cerr != nil {
_ = ShowSubcommandHelp(context)
_ = ShowSubcommandHelp(cCtx)
return cerr
}
if a.After != nil {
defer func() {
afterErr := a.After(context)
afterErr := a.After(cCtx)
if afterErr != nil {
a.handleExitCoder(context, err)
a.handleExitCoder(cCtx, err)
if err != nil {
err = newMultiError(err, afterErr)
} else {
@ -418,27 +474,27 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
}
if a.Before != nil {
beforeErr := a.Before(context)
beforeErr := a.Before(cCtx)
if beforeErr != nil {
a.handleExitCoder(context, beforeErr)
a.handleExitCoder(cCtx, beforeErr)
err = beforeErr
return err
}
}
args := context.Args()
args := cCtx.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(context)
return c.Run(cCtx)
}
}
// Run default Action
err = a.Action(context)
err = a.Action(cCtx)
a.handleExitCoder(context, err)
a.handleExitCoder(cCtx, err)
return err
}
@ -481,6 +537,14 @@ func (a *App) VisibleCommands() []*Command {
return ret
}
// VisibleFlagCategories returns a slice containing all the categories with the flags they contain
func (a *App) VisibleFlagCategories() []VisibleFlagCategory {
if a.flagCategories == nil {
return []VisibleFlagCategory{}
}
return a.flagCategories.VisibleCategories()
}
// VisibleFlags returns a slice of the Flags with Hidden=false
func (a *App) VisibleFlags() []Flag {
return visibleFlags(a.Flags)
@ -498,9 +562,9 @@ func (a *App) appendCommand(c *Command) {
}
}
func (a *App) handleExitCoder(context *Context, err error) {
func (a *App) handleExitCoder(cCtx *Context, err error) {
if a.ExitErrHandler != nil {
a.ExitErrHandler(context, err)
a.ExitErrHandler(cCtx, err)
} else {
HandleExitCoder(err)
}
@ -525,14 +589,14 @@ func (a *Author) String() string {
// HandleAction attempts to figure out which Action signature was used. If
// it's an ActionFunc or a func with the legacy signature for Action, the func
// is run!
func HandleAction(action interface{}, context *Context) (err error) {
func HandleAction(action interface{}, cCtx *Context) (err error) {
switch a := action.(type) {
case ActionFunc:
return a(context)
return a(cCtx)
case func(*Context) error:
return a(context)
return a(cCtx)
case func(*Context): // deprecated function signature
a(context)
a(cCtx)
return nil
}

View file

@ -1,10 +1,12 @@
package cli
import "sort"
// CommandCategories interface allows for category manipulation
type CommandCategories interface {
// AddCommand adds a command to a category, creating a new category if necessary.
AddCommand(category string, command *Command)
// categories returns a copy of the category slice
// Categories returns a slice of categories sorted by name
Categories() []CommandCategory
}
@ -77,3 +79,93 @@ func (c *commandCategory) VisibleCommands() []*Command {
}
return ret
}
// FlagCategories interface allows for category manipulation
type FlagCategories interface {
// AddFlags adds a flag to a category, creating a new category if necessary.
AddFlag(category string, fl Flag)
// VisibleCategories returns a slice of visible flag categories sorted by name
VisibleCategories() []VisibleFlagCategory
}
type defaultFlagCategories struct {
m map[string]*defaultVisibleFlagCategory
}
func newFlagCategories() FlagCategories {
return &defaultFlagCategories{
m: map[string]*defaultVisibleFlagCategory{},
}
}
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
fc := newFlagCategories()
for _, fl := range fs {
if cf, ok := fl.(CategorizableFlag); ok {
fc.AddFlag(cf.GetCategory(), cf)
}
}
return fc
}
func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
if _, ok := f.m[category]; !ok {
f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
}
f.m[category].m[fl.String()] = fl
}
func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
catNames := []string{}
for name := range f.m {
catNames = append(catNames, name)
}
sort.Strings(catNames)
ret := make([]VisibleFlagCategory, len(catNames))
for i, name := range catNames {
ret[i] = f.m[name]
}
return ret
}
// VisibleFlagCategory is a category containing flags.
type VisibleFlagCategory interface {
// Name returns the category name string
Name() string
// Flags returns a slice of VisibleFlag sorted by name
Flags() []VisibleFlag
}
type defaultVisibleFlagCategory struct {
name string
m map[string]Flag
}
func (fc *defaultVisibleFlagCategory) Name() string {
return fc.name
}
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
vfNames := []string{}
for flName, fl := range fc.m {
if vf, ok := fl.(VisibleFlag); ok {
if vf.IsVisible() {
vfNames = append(vfNames, flName)
}
}
}
sort.Strings(vfNames)
ret := make([]VisibleFlag, len(vfNames))
for i, flName := range vfNames {
ret[i] = fc.m[flName].(VisibleFlag)
}
return ret
}

View file

@ -20,4 +20,4 @@
// }
package cli
//go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go
//go:generate go run internal/genflags/cmd/genflags/main.go

View file

@ -38,7 +38,8 @@ type Command struct {
// List of child commands
Subcommands []*Command
// List of flags to parse
Flags []Flag
Flags []Flag
flagCategories FlagCategories
// Treat all flags as normal arguments if true
SkipFlagParsing bool
// Boolean to hide built-in help command and help flag
@ -105,39 +106,44 @@ func (c *Command) Run(ctx *Context) (err error) {
set, err := c.parseFlags(ctx.Args(), ctx.shellComplete)
context := NewContext(ctx.App, set, ctx)
context.Command = c
if checkCommandCompletions(context, c.Name) {
cCtx := NewContext(ctx.App, set, ctx)
cCtx.Command = c
if checkCommandCompletions(cCtx, c.Name) {
return nil
}
if err != nil {
if c.OnUsageError != nil {
err = c.OnUsageError(context, err, false)
context.App.handleExitCoder(context, err)
err = c.OnUsageError(cCtx, err, false)
cCtx.App.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
_, _ = fmt.Fprintln(context.App.Writer)
_ = ShowCommandHelp(context, c.Name)
_, _ = fmt.Fprintln(cCtx.App.Writer, "Incorrect Usage:", err.Error())
_, _ = fmt.Fprintln(cCtx.App.Writer)
if ctx.App.Suggest {
if suggestion, err := ctx.App.suggestFlagFromError(err, c.Name); err == nil {
fmt.Fprintf(cCtx.App.Writer, suggestion)
}
}
_ = ShowCommandHelp(cCtx, c.Name)
return err
}
if checkCommandHelp(context, c.Name) {
if checkCommandHelp(cCtx, c.Name) {
return nil
}
cerr := context.checkRequiredFlags(c.Flags)
cerr := cCtx.checkRequiredFlags(c.Flags)
if cerr != nil {
_ = ShowCommandHelp(context, c.Name)
_ = ShowCommandHelp(cCtx, c.Name)
return cerr
}
if c.After != nil {
defer func() {
afterErr := c.After(context)
afterErr := c.After(cCtx)
if afterErr != nil {
context.App.handleExitCoder(context, err)
cCtx.App.handleExitCoder(cCtx, err)
if err != nil {
err = newMultiError(err, afterErr)
} else {
@ -148,9 +154,9 @@ func (c *Command) Run(ctx *Context) (err error) {
}
if c.Before != nil {
err = c.Before(context)
err = c.Before(cCtx)
if err != nil {
context.App.handleExitCoder(context, err)
cCtx.App.handleExitCoder(cCtx, err)
return err
}
}
@ -159,11 +165,11 @@ func (c *Command) Run(ctx *Context) (err error) {
c.Action = helpSubcommand.Action
}
context.Command = c
err = c.Action(context)
cCtx.Command = c
err = c.Action(cCtx)
if err != nil {
context.App.handleExitCoder(context, err)
cCtx.App.handleExitCoder(cCtx, err)
}
return err
}
@ -249,6 +255,7 @@ func (c *Command) startApp(ctx *Context) error {
app.ErrWriter = ctx.App.ErrWriter
app.ExitErrHandler = ctx.App.ExitErrHandler
app.UseShortOptionHandling = ctx.App.UseShortOptionHandling
app.Suggest = ctx.App.Suggest
app.categories = newCommandCategories()
for _, command := range c.Subcommands {
@ -280,6 +287,14 @@ func (c *Command) startApp(ctx *Context) error {
return app.RunAsSubcommand(ctx)
}
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
if c.flagCategories == nil {
return []VisibleFlagCategory{}
}
return c.flagCategories.VisibleCategories()
}
// VisibleFlags returns a slice of the Flags with Hidden=false
func (c *Command) VisibleFlags() []Flag {
return visibleFlags(c.Flags)

View file

@ -40,18 +40,18 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
}
// NumFlags returns the number of flags set
func (c *Context) NumFlags() int {
return c.flagSet.NFlag()
func (cCtx *Context) NumFlags() int {
return cCtx.flagSet.NFlag()
}
// Set sets a context flag to a value.
func (c *Context) Set(name, value string) error {
return c.flagSet.Set(name, value)
func (cCtx *Context) Set(name, value string) error {
return cCtx.flagSet.Set(name, value)
}
// IsSet determines if the flag was actually set
func (c *Context) IsSet(name string) bool {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) IsSet(name string) bool {
if fs := cCtx.lookupFlagSet(name); fs != nil {
isSet := false
fs.Visit(func(f *flag.Flag) {
if f.Name == name {
@ -62,7 +62,7 @@ func (c *Context) IsSet(name string) bool {
return true
}
f := c.lookupFlag(name)
f := cCtx.lookupFlag(name)
if f == nil {
return false
}
@ -74,28 +74,28 @@ func (c *Context) IsSet(name string) bool {
}
// LocalFlagNames returns a slice of flag names used in this context.
func (c *Context) LocalFlagNames() []string {
func (cCtx *Context) LocalFlagNames() []string {
var names []string
c.flagSet.Visit(makeFlagNameVisitor(&names))
cCtx.flagSet.Visit(makeFlagNameVisitor(&names))
return names
}
// FlagNames returns a slice of flag names used by the this context and all of
// its parent contexts.
func (c *Context) FlagNames() []string {
func (cCtx *Context) FlagNames() []string {
var names []string
for _, ctx := range c.Lineage() {
ctx.flagSet.Visit(makeFlagNameVisitor(&names))
for _, pCtx := range cCtx.Lineage() {
pCtx.flagSet.Visit(makeFlagNameVisitor(&names))
}
return names
}
// Lineage returns *this* context and all of its ancestor contexts in order from
// child to parent
func (c *Context) Lineage() []*Context {
func (cCtx *Context) Lineage() []*Context {
var lineage []*Context
for cur := c; cur != nil; cur = cur.parentContext {
for cur := cCtx; cur != nil; cur = cur.parentContext {
lineage = append(lineage, cur)
}
@ -103,26 +103,26 @@ func (c *Context) Lineage() []*Context {
}
// Value returns the value of the flag corresponding to `name`
func (c *Context) Value(name string) interface{} {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Value(name string) interface{} {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return fs.Lookup(name).Value.(flag.Getter).Get()
}
return nil
}
// Args returns the command line arguments associated with the context.
func (c *Context) Args() Args {
ret := args(c.flagSet.Args())
func (cCtx *Context) Args() Args {
ret := args(cCtx.flagSet.Args())
return &ret
}
// NArg returns the number of the command line arguments.
func (c *Context) NArg() int {
return c.Args().Len()
func (cCtx *Context) NArg() int {
return cCtx.Args().Len()
}
func (ctx *Context) lookupFlag(name string) Flag {
for _, c := range ctx.Lineage() {
func (cCtx *Context) lookupFlag(name string) Flag {
for _, c := range cCtx.Lineage() {
if c.Command == nil {
continue
}
@ -136,8 +136,8 @@ func (ctx *Context) lookupFlag(name string) Flag {
}
}
if ctx.App != nil {
for _, f := range ctx.App.Flags {
if cCtx.App != nil {
for _, f := range cCtx.App.Flags {
for _, n := range f.Names() {
if n == name {
return f
@ -149,8 +149,8 @@ func (ctx *Context) lookupFlag(name string) Flag {
return nil
}
func (ctx *Context) lookupFlagSet(name string) *flag.FlagSet {
for _, c := range ctx.Lineage() {
func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
for _, c := range cCtx.Lineage() {
if c.flagSet == nil {
continue
}
@ -162,7 +162,7 @@ func (ctx *Context) lookupFlagSet(name string) *flag.FlagSet {
return nil
}
func (context *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
var missingFlags []string
for _, f := range flags {
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
@ -174,7 +174,7 @@ func (context *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
flagName = key
}
if context.IsSet(strings.TrimSpace(key)) {
if cCtx.IsSet(strings.TrimSpace(key)) {
flagPresent = true
}
}

View file

@ -1,3 +1,6 @@
//go:build !urfave_cli_no_docs
// +build !urfave_cli_no_docs
package cli
import (
@ -80,14 +83,14 @@ func prepareCommands(commands []*Command, level int) []string {
usageText,
)
flags := prepareArgsWithValues(command.Flags)
flags := prepareArgsWithValues(command.VisibleFlags())
if len(flags) > 0 {
prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n"))
}
coms = append(coms, prepared)
// recursevly iterate subcommands
// recursively iterate subcommands
if len(command.Subcommands) > 0 {
coms = append(
coms,

View file

@ -95,7 +95,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr
completions = append(completions, completion.String())
completions = append(
completions,
a.prepareFishFlags(command.Flags, command.Names())...,
a.prepareFishFlags(command.VisibleFlags(), command.Names())...,
)
// recursevly iterate subcommands

50
vendor/github.com/urfave/cli/v2/flag-spec.yaml generated vendored Normal file
View file

@ -0,0 +1,50 @@
# NOTE: this file is used by the tool defined in
# ./internal/genflags/cmd/genflags/main.go which uses the
# `genflags.Spec` type that maps to this file structure.
flag_types:
bool: {}
float64: {}
int64: {}
int: {}
time.Duration: {}
uint64: {}
uint: {}
string:
struct_fields:
- { name: TakesFile, type: bool }
Generic:
struct_fields:
- { name: TakesFile, type: bool }
Path:
struct_fields:
- { name: TakesFile, type: bool }
Float64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
Int64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
IntSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
StringSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- { name: TakesFile, type: bool }
Timestamp:
value_pointer: true
struct_fields:
- { name: Layout, type: string }
# TODO: enable UintSlice
# UintSlice: {}
# TODO: enable Uint64Slice once #1334 lands
# Uint64Slice: {}

View file

@ -5,7 +5,6 @@ import (
"flag"
"fmt"
"io/ioutil"
"reflect"
"regexp"
"runtime"
"strconv"
@ -117,6 +116,12 @@ type DocGenerationFlag interface {
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
GetValue() string
// GetDefaultText returns the default text for this flag
GetDefaultText() string
// GetEnvVars returns the env vars for this flag
GetEnvVars() []string
}
// VisibleFlag is an interface that allows to check if a flag is visible
@ -127,6 +132,14 @@ type VisibleFlag interface {
IsVisible() bool
}
// CategorizableFlag is an interface that allows us to potentially
// use a flag in a categorized representation.
type CategorizableFlag interface {
VisibleFlag
GetCategory() string
}
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
set := flag.NewFlagSet(name, flag.ContinueOnError)
@ -238,7 +251,7 @@ func prefixedNames(names []string, placeholder string) string {
func withEnvHint(envVars []string, str string) string {
envText := ""
if envVars != nil && len(envVars) > 0 {
if len(envVars) > 0 {
prefix := "$"
suffix := ""
sep := ", $"
@ -253,7 +266,7 @@ func withEnvHint(envVars []string, str string) string {
return str + envText
}
func flagNames(name string, aliases []string) []string {
func FlagNames(name string, aliases []string) []string {
var ret []string
for _, part := range append([]string{name}, aliases...) {
@ -267,17 +280,6 @@ func flagNames(name string, aliases []string) []string {
return ret
}
func flagStringSliceField(f Flag, name string) []string {
fv := flagValue(f)
field := fv.FieldByName(name)
if field.IsValid() {
return field.Interface().([]string)
}
return []string{}
}
func withFileHint(filePath, str string) string {
fileText := ""
if filePath != "" {
@ -286,68 +288,34 @@ func withFileHint(filePath, str string) string {
return str + fileText
}
func flagValue(f Flag) reflect.Value {
fv := reflect.ValueOf(f)
for fv.Kind() == reflect.Ptr {
fv = reflect.Indirect(fv)
}
return fv
}
func formatDefault(format string) string {
return " (default: " + format + ")"
}
func stringifyFlag(f Flag) string {
fv := flagValue(f)
switch f := f.(type) {
case *IntSliceFlag:
return withEnvHint(flagStringSliceField(f, "EnvVars"),
stringifyIntSliceFlag(f))
case *Int64SliceFlag:
return withEnvHint(flagStringSliceField(f, "EnvVars"),
stringifyInt64SliceFlag(f))
case *Float64SliceFlag:
return withEnvHint(flagStringSliceField(f, "EnvVars"),
stringifyFloat64SliceFlag(f))
case *StringSliceFlag:
return withEnvHint(flagStringSliceField(f, "EnvVars"),
stringifyStringSliceFlag(f))
// enforce DocGeneration interface on flags to avoid reflection
df, ok := f.(DocGenerationFlag)
if !ok {
return ""
}
placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String())
needsPlaceholder := false
defaultValueString := ""
val := fv.FieldByName("Value")
if val.IsValid() {
needsPlaceholder = val.Kind() != reflect.Bool
defaultValueString = fmt.Sprintf(formatDefault("%v"), val.Interface())
if val.Kind() == reflect.String && val.String() != "" {
defaultValueString = fmt.Sprintf(formatDefault("%q"), val.String())
}
}
helpText := fv.FieldByName("DefaultText")
if helpText.IsValid() && helpText.String() != "" {
needsPlaceholder = val.Kind() != reflect.Bool
defaultValueString = fmt.Sprintf(formatDefault("%s"), helpText.String())
}
if defaultValueString == formatDefault("") {
defaultValueString = ""
}
placeholder, usage := unquoteUsage(df.GetUsage())
needsPlaceholder := df.TakesValue()
if needsPlaceholder && placeholder == "" {
placeholder = defaultPlaceholder
}
defaultValueString := ""
if s := df.GetDefaultText(); s != "" {
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
}
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
return withEnvHint(flagStringSliceField(f, "EnvVars"),
fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault))
return withEnvHint(df.GetEnvVars(),
fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
}
func stringifyIntSliceFlag(f *IntSliceFlag) string {
@ -426,19 +394,26 @@ func hasFlag(flags []Flag, fl Flag) bool {
return false
}
func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool) {
// Return the first value from a list of environment variables and files
// (which may or may not exist), a description of where the value was found,
// and a boolean which is true if a value was found.
func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhere string, found bool) {
for _, envVar := range envVars {
envVar = strings.TrimSpace(envVar)
if val, ok := syscall.Getenv(envVar); ok {
return val, true
if value, found := syscall.Getenv(envVar); found {
return value, fmt.Sprintf("environment variable %q", envVar), true
}
}
for _, fileVar := range strings.Split(filePath, ",") {
if fileVar != "" {
if data, err := ioutil.ReadFile(fileVar); err == nil {
return string(data), true
return string(data), fmt.Sprintf("file %q", filePath), true
}
}
}
return "", false
return "", "", false
}
func flagSplitMultiValues(val string) []string {
return strings.Split(val, ",")
}

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// BoolFlag is a flag with type bool
type BoolFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *BoolFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *BoolFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *BoolFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *BoolFlag) TakesValue() bool {
return false
@ -52,25 +16,38 @@ func (f *BoolFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *BoolFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *BoolFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *BoolFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *BoolFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return fmt.Sprintf("%v", f.Value)
}
// GetEnvVars returns the env vars for this flag
func (f *BoolFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *BoolFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
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)
return fmt.Errorf("could not parse %q as bool value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = valBool
@ -89,10 +66,15 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *BoolFlag) Get(ctx *Context) bool {
return ctx.Bool(f.Name)
}
// Bool looks up the value of a local BoolFlag, returns
// false if not found
func (c *Context) Bool(name string) bool {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Bool(name string) bool {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupBool(name, fs)
}
return false

View file

@ -6,42 +6,6 @@ import (
"time"
)
// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
type DurationFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *DurationFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *DurationFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *DurationFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *DurationFlag) TakesValue() bool {
return true
@ -52,25 +16,38 @@ func (f *DurationFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *DurationFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *DurationFlag) GetValue() string {
return f.Value.String()
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *DurationFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *DurationFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *DurationFlag) GetEnvVars() []string {
return f.EnvVars
}
// 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, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
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)
return fmt.Errorf("could not parse %q as duration value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = valDuration
@ -88,10 +65,15 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *DurationFlag) Get(ctx *Context) time.Duration {
return ctx.Duration(f.Name)
}
// Duration looks up the value of a local DurationFlag, returns
// 0 if not found
func (c *Context) Duration(name string) time.Duration {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Duration(name string) time.Duration {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupDuration(name, fs)
}
return 0

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// Float64Flag is a flag with type float64
type Float64Flag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *Float64Flag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *Float64Flag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Float64Flag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *Float64Flag) TakesValue() bool {
return true
@ -52,24 +16,37 @@ func (f *Float64Flag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *Float64Flag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Float64Flag) GetValue() string {
return fmt.Sprintf("%f", f.Value)
return fmt.Sprintf("%v", f.Value)
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Float64Flag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *Float64Flag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Float64Flag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *Float64Flag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valFloat, err := strconv.ParseFloat(val, 64)
if err != nil {
return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", val, f.Name, err)
return fmt.Errorf("could not parse %q as float64 value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = valFloat
@ -88,10 +65,15 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *Float64Flag) Get(ctx *Context) float64 {
return ctx.Float64(f.Name)
}
// Float64 looks up the value of a local Float64Flag, returns
// 0 if not found
func (c *Context) Float64(name string) float64 {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Float64(name string) float64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupFloat64(name, fs)
}
return 0

View file

@ -43,18 +43,25 @@ func (f *Float64Slice) Set(value string) error {
return nil
}
tmp, err := strconv.ParseFloat(value, 64)
if err != nil {
return err
}
for _, s := range flagSplitMultiValues(value) {
tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
if err != nil {
return err
}
f.slice = append(f.slice, tmp)
f.slice = append(f.slice, tmp)
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (f *Float64Slice) String() string {
return fmt.Sprintf("%#v", f.slice)
v := f.slice
if v == nil {
// treat nil the same as zero length non-nil
v = make([]float64, 0)
}
return fmt.Sprintf("%#v", v)
}
// Serialize allows Float64Slice to fulfill Serializer
@ -73,39 +80,10 @@ func (f *Float64Slice) Get() interface{} {
return *f
}
// Float64SliceFlag is a flag with type *Float64Slice
type Float64SliceFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
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
// (for usage defaults)
func (f *Float64SliceFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *Float64SliceFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Float64SliceFlag) IsRequired() bool {
return f.Required
return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f))
}
// TakesValue returns true if the flag takes a value, otherwise false
@ -118,6 +96,11 @@ func (f *Float64SliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *Float64SliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Float64SliceFlag) GetValue() string {
@ -127,45 +110,69 @@ func (f *Float64SliceFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Float64SliceFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *Float64SliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Float64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// 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{}
// apply any default
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]float64, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
for _, s := range strings.Split(val, ",") {
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as float64 slice value for flag %s: %s", f.Value, f.Name, err)
// resolve setValue (what we will assign to the set)
var setValue *Float64Slice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(Float64Slice)
}
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as float64 slice value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
f.Value.hasBeenSet = false
setValue.hasBeenSet = false
f.HasBeenSet = true
}
}
if f.Value == nil {
f.Value = &Float64Slice{}
}
copyValue := f.Value.clone()
for _, name := range f.Names() {
set.Var(copyValue, name, f.Usage)
set.Var(setValue, name, f.Usage)
}
return nil
}
// Get returns the flags value in the given Context.
func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
return ctx.Float64Slice(f.Name)
}
// Float64Slice looks up the value of a local Float64SliceFlag, returns
// nil if not found
func (c *Context) Float64Slice(name string) []float64 {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Float64Slice(name string) []float64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupFloat64Slice(name, fs)
}
return nil
@ -174,7 +181,7 @@ func (c *Context) Float64Slice(name string) []float64 {
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
f := set.Lookup(name)
if f != nil {
if slice, ok := f.Value.(*Float64Slice); ok {
if slice, ok := unwrapFlagValue(f.Value).(*Float64Slice); ok {
return slice.Value()
}
}

View file

@ -11,42 +11,6 @@ type Generic interface {
String() string
}
// GenericFlag is a flag with type Generic
type GenericFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *GenericFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *GenericFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *GenericFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *GenericFlag) TakesValue() bool {
return true
@ -57,6 +21,11 @@ func (f *GenericFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *GenericFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *GenericFlag) GetValue() string {
@ -66,18 +35,26 @@ func (f *GenericFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *GenericFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *GenericFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *GenericFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply takes the flagset and calls Set on the generic flag with the value
// 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, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
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)
return fmt.Errorf("could not parse %q from %s as value for flag %s: %s", val, source, f.Name, err)
}
f.HasBeenSet = true
@ -91,10 +68,15 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *GenericFlag) Get(ctx *Context) interface{} {
return ctx.Generic(f.Name)
}
// Generic looks up the value of a local GenericFlag, returns
// nil if not found
func (c *Context) Generic(name string) interface{} {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Generic(name string) interface{} {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupGeneric(name, fs)
}
return nil

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// IntFlag is a flag with type int
type IntFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *IntFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *IntFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *IntFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *IntFlag) TakesValue() bool {
return true
@ -52,25 +16,38 @@ func (f *IntFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *IntFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *IntFlag) GetValue() string {
return fmt.Sprintf("%d", f.Value)
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *IntFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *IntFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *IntFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *IntFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
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)
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = int(valInt)
@ -89,10 +66,15 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *IntFlag) Get(ctx *Context) int {
return ctx.Int(f.Name)
}
// Int looks up the value of a local IntFlag, returns
// 0 if not found
func (c *Context) Int(name string) int {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Int(name string) int {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupInt(name, fs)
}
return 0

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// Int64Flag is a flag with type int64
type Int64Flag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *Int64Flag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *Int64Flag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Int64Flag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *Int64Flag) TakesValue() bool {
return true
@ -52,25 +16,38 @@ func (f *Int64Flag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *Int64Flag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Int64Flag) GetValue() string {
return fmt.Sprintf("%d", f.Value)
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Int64Flag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *Int64Flag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Int64Flag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *Int64Flag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
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)
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = valInt
@ -88,10 +65,15 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *Int64Flag) Get(ctx *Context) int64 {
return ctx.Int64(f.Name)
}
// Int64 looks up the value of a local Int64Flag, returns
// 0 if not found
func (c *Context) Int64(name string) int64 {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Int64(name string) int64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupInt64(name, fs)
}
return 0

View file

@ -43,19 +43,26 @@ func (i *Int64Slice) Set(value string) error {
return nil
}
tmp, err := strconv.ParseInt(value, 0, 64)
if err != nil {
return err
}
for _, s := range flagSplitMultiValues(value) {
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
if err != nil {
return err
}
i.slice = append(i.slice, tmp)
i.slice = append(i.slice, tmp)
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (i *Int64Slice) String() string {
return fmt.Sprintf("%#v", i.slice)
v := i.slice
if v == nil {
// treat nil the same as zero length non-nil
v = make([]int64, 0)
}
return fmt.Sprintf("%#v", v)
}
// Serialize allows Int64Slice to fulfill Serializer
@ -74,39 +81,10 @@ func (i *Int64Slice) Get() interface{} {
return *i
}
// Int64SliceFlag is a flag with type *Int64Slice
type Int64SliceFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
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
// (for usage defaults)
func (f *Int64SliceFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *Int64SliceFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Int64SliceFlag) IsRequired() bool {
return f.Required
return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f))
}
// TakesValue returns true of the flag takes a value, otherwise false
@ -115,10 +93,15 @@ func (f *Int64SliceFlag) TakesValue() bool {
}
// GetUsage returns the usage string for the flag
func (f Int64SliceFlag) GetUsage() string {
func (f *Int64SliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *Int64SliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Int64SliceFlag) GetValue() string {
@ -128,43 +111,67 @@ func (f *Int64SliceFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Int64SliceFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *Int64SliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Int64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
f.Value = &Int64Slice{}
// apply any default
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]int64, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
for _, s := range strings.Split(val, ",") {
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", val, f.Name, err)
// resolve setValue (what we will assign to the set)
var setValue *Int64Slice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(Int64Slice)
}
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int64 slice value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
f.Value.hasBeenSet = false
setValue.hasBeenSet = false
f.HasBeenSet = true
}
if f.Value == nil {
f.Value = &Int64Slice{}
}
copyValue := f.Value.clone()
for _, name := range f.Names() {
set.Var(copyValue, name, f.Usage)
set.Var(setValue, name, f.Usage)
}
return nil
}
// Get returns the flags value in the given Context.
func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
return ctx.Int64Slice(f.Name)
}
// Int64Slice looks up the value of a local Int64SliceFlag, returns
// nil if not found
func (c *Context) Int64Slice(name string) []int64 {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Int64Slice(name string) []int64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupInt64Slice(name, fs)
}
return nil
@ -173,7 +180,7 @@ func (c *Context) Int64Slice(name string) []int64 {
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
f := set.Lookup(name)
if f != nil {
if slice, ok := f.Value.(*Int64Slice); ok {
if slice, ok := unwrapFlagValue(f.Value).(*Int64Slice); ok {
return slice.Value()
}
}

View file

@ -54,19 +54,26 @@ func (i *IntSlice) Set(value string) error {
return nil
}
tmp, err := strconv.ParseInt(value, 0, 64)
if err != nil {
return err
}
for _, s := range flagSplitMultiValues(value) {
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
if err != nil {
return err
}
i.slice = append(i.slice, int(tmp))
i.slice = append(i.slice, int(tmp))
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (i *IntSlice) String() string {
return fmt.Sprintf("%#v", i.slice)
v := i.slice
if v == nil {
// treat nil the same as zero length non-nil
v = make([]int, 0)
}
return fmt.Sprintf("%#v", v)
}
// Serialize allows IntSlice to fulfill Serializer
@ -85,39 +92,10 @@ func (i *IntSlice) Get() interface{} {
return *i
}
// IntSliceFlag is a flag with type *IntSlice
type IntSliceFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
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
// (for usage defaults)
func (f *IntSliceFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *IntSliceFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *IntSliceFlag) IsRequired() bool {
return f.Required
return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f))
}
// TakesValue returns true of the flag takes a value, otherwise false
@ -126,10 +104,15 @@ func (f *IntSliceFlag) TakesValue() bool {
}
// GetUsage returns the usage string for the flag
func (f IntSliceFlag) GetUsage() string {
func (f *IntSliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *IntSliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *IntSliceFlag) GetValue() string {
@ -139,43 +122,67 @@ func (f *IntSliceFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *IntSliceFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *IntSliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *IntSliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
f.Value = &IntSlice{}
// apply any default
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]int, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
for _, s := range strings.Split(val, ",") {
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", val, f.Name, err)
// resolve setValue (what we will assign to the set)
var setValue *IntSlice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(IntSlice)
}
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int slice value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
f.Value.hasBeenSet = false
setValue.hasBeenSet = false
f.HasBeenSet = true
}
if f.Value == nil {
f.Value = &IntSlice{}
}
copyValue := f.Value.clone()
for _, name := range f.Names() {
set.Var(copyValue, name, f.Usage)
set.Var(setValue, name, f.Usage)
}
return nil
}
// Get returns the flags value in the given Context.
func (f *IntSliceFlag) Get(ctx *Context) []int {
return ctx.IntSlice(f.Name)
}
// IntSlice looks up the value of a local IntSliceFlag, returns
// nil if not found
func (c *Context) IntSlice(name string) []int {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) IntSlice(name string) []int {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupIntSlice(name, fs)
}
return nil
@ -184,7 +191,7 @@ func (c *Context) IntSlice(name string) []int {
func lookupIntSlice(name string, set *flag.FlagSet) []int {
f := set.Lookup(name)
if f != nil {
if slice, ok := f.Value.(*IntSlice); ok {
if slice, ok := unwrapFlagValue(f.Value).(*IntSlice); ok {
return slice.Value()
}
}

View file

@ -1,42 +1,11 @@
package cli
import "flag"
import (
"flag"
"fmt"
)
type PathFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
TakesFile bool
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
// (for usage defaults)
func (f *PathFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *PathFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *PathFlag) IsRequired() bool {
return f.Required
}
type Path = string
// TakesValue returns true of the flag takes a value, otherwise false
func (f *PathFlag) TakesValue() bool {
@ -48,20 +17,36 @@ func (f *PathFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *PathFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *PathFlag) GetValue() string {
return f.Value
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *PathFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *PathFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
if f.Value == "" {
return f.Value
}
return fmt.Sprintf("%q", f.Value)
}
// GetEnvVars returns the env vars for this flag
func (f *PathFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *PathFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val
f.HasBeenSet = true
}
@ -77,10 +62,15 @@ func (f *PathFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *PathFlag) Get(ctx *Context) string {
return ctx.Path(f.Name)
}
// Path looks up the value of a local PathFlag, returns
// "" if not found
func (c *Context) Path(name string) string {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Path(name string) string {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupPath(name, fs)
}

View file

@ -1,43 +1,9 @@
package cli
import "flag"
// StringFlag is a flag with type string
type StringFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
TakesFile bool
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 (f *StringFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *StringFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *StringFlag) IsRequired() bool {
return f.Required
}
import (
"flag"
"fmt"
)
// TakesValue returns true of the flag takes a value, otherwise false
func (f *StringFlag) TakesValue() bool {
@ -49,20 +15,36 @@ func (f *StringFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *StringFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *StringFlag) GetValue() string {
return f.Value
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *StringFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *StringFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
if f.Value == "" {
return f.Value
}
return fmt.Sprintf("%q", f.Value)
}
// GetEnvVars returns the env vars for this flag
func (f *StringFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *StringFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val
f.HasBeenSet = true
}
@ -78,10 +60,15 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *StringFlag) Get(ctx *Context) string {
return ctx.String(f.Name)
}
// String looks up the value of a local StringFlag, returns
// "" if not found
func (c *Context) String(name string) string {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) String(name string) string {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupString(name, fs)
}
return ""

View file

@ -42,7 +42,9 @@ func (s *StringSlice) Set(value string) error {
return nil
}
s.slice = append(s.slice, value)
for _, t := range flagSplitMultiValues(value) {
s.slice = append(s.slice, strings.TrimSpace(t))
}
return nil
}
@ -68,41 +70,10 @@ func (s *StringSlice) Get() interface{} {
return *s
}
// StringSliceFlag is a flag with type *StringSlice
type StringSliceFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
TakesFile bool
Value *StringSlice
DefaultText string
HasBeenSet bool
Destination *StringSlice
}
// 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
// (for usage defaults)
func (f *StringSliceFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *StringSliceFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *StringSliceFlag) IsRequired() bool {
return f.Required
return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f))
}
// TakesValue returns true of the flag takes a value, otherwise false
@ -115,6 +86,11 @@ func (f *StringSliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *StringSliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *StringSliceFlag) GetValue() string {
@ -124,48 +100,51 @@ func (f *StringSliceFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *StringSliceFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *StringSliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *StringSliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
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 f.Value == nil {
f.Value = &StringSlice{}
}
destination := f.Value
if f.Destination != nil {
destination = f.Destination
}
// resolve setValue (what we will assign to the set)
var setValue *StringSlice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(StringSlice)
}
for _, s := range strings.Split(val, ",") {
if err := destination.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as string value for flag %s: %s", val, f.Name, err)
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
destination.hasBeenSet = false
setValue.hasBeenSet = false
f.HasBeenSet = true
}
if f.Value == nil {
f.Value = &StringSlice{}
}
setValue := f.Destination
if f.Destination == nil {
setValue = f.Value.clone()
}
for _, name := range f.Names() {
set.Var(setValue, name, f.Usage)
}
@ -173,10 +152,15 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *StringSliceFlag) Get(ctx *Context) []string {
return ctx.StringSlice(f.Name)
}
// StringSlice looks up the value of a local StringSliceFlag, returns
// nil if not found
func (c *Context) StringSlice(name string) []string {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) StringSlice(name string) []string {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupStringSlice(name, fs)
}
return nil
@ -185,7 +169,7 @@ func (c *Context) StringSlice(name string) []string {
func lookupStringSlice(name string, set *flag.FlagSet) []string {
f := set.Lookup(name)
if f != nil {
if slice, ok := f.Value.(*StringSlice); ok {
if slice, ok := unwrapFlagValue(f.Value).(*StringSlice); ok {
return slice.Value()
}
}

View file

@ -58,43 +58,6 @@ func (t *Timestamp) Get() interface{} {
return *t
}
// TimestampFlag is a flag with type time
type TimestampFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
Layout string
Value *Timestamp
DefaultText string
HasBeenSet bool
Destination *Timestamp
}
// IsSet returns whether or not the flag has been set through env or file
func (f *TimestampFlag) IsSet() bool {
return f.HasBeenSet
}
// String returns a readable representation of this value
// (for usage defaults)
func (f *TimestampFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *TimestampFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *TimestampFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *TimestampFlag) TakesValue() bool {
return true
@ -105,6 +68,11 @@ func (f *TimestampFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *TimestampFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *TimestampFlag) GetValue() string {
@ -114,9 +82,17 @@ func (f *TimestampFlag) GetValue() string {
return ""
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *TimestampFlag) IsVisible() bool {
return !f.Hidden
// GetDefaultText returns the default text for this flag
func (f *TimestampFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *TimestampFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
@ -133,9 +109,9 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
f.Destination.SetLayout(f.Layout)
}
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if err := f.Value.Set(val); err != nil {
return fmt.Errorf("could not parse %q as timestamp value for flag %s: %s", val, f.Name, err)
return fmt.Errorf("could not parse %q as timestamp value from %s for flag %s: %s", val, source, f.Name, err)
}
f.HasBeenSet = true
}
@ -151,9 +127,14 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
return nil
}
// Get returns the flags value in the given Context.
func (f *TimestampFlag) Get(ctx *Context) *time.Time {
return ctx.Timestamp(f.Name)
}
// Timestamp gets the timestamp from a flag name
func (c *Context) Timestamp(name string) *time.Time {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Timestamp(name string) *time.Time {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupTimestamp(name, fs)
}
return nil

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// UintFlag is a flag with type uint
type UintFlag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *UintFlag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *UintFlag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *UintFlag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *UintFlag) TakesValue() bool {
return true
@ -52,18 +16,18 @@ func (f *UintFlag) GetUsage() string {
return f.Usage
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *UintFlag) IsVisible() bool {
return !f.Hidden
// GetCategory returns the category for the flag
func (f *UintFlag) GetCategory() string {
return f.Category
}
// Apply populates the flag given the flag set and environment
func (f *UintFlag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseUint(val, 0, 64)
if err != nil {
return fmt.Errorf("could not parse %q as uint value for flag %s: %s", val, f.Name, err)
return fmt.Errorf("could not parse %q as uint value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = uint(valInt)
@ -88,10 +52,28 @@ func (f *UintFlag) GetValue() string {
return fmt.Sprintf("%d", f.Value)
}
// GetDefaultText returns the default text for this flag
func (f *UintFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *UintFlag) GetEnvVars() []string {
return f.EnvVars
}
// Get returns the flags value in the given Context.
func (f *UintFlag) Get(ctx *Context) uint {
return ctx.Uint(f.Name)
}
// Uint looks up the value of a local UintFlag, returns
// 0 if not found
func (c *Context) Uint(name string) uint {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Uint(name string) uint {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupUint(name, fs)
}
return 0

View file

@ -6,42 +6,6 @@ import (
"strconv"
)
// Uint64Flag is a flag with type uint64
type Uint64Flag struct {
Name string
Aliases []string
Usage string
EnvVars []string
FilePath string
Required bool
Hidden bool
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
// (for usage defaults)
func (f *Uint64Flag) String() string {
return FlagStringer(f)
}
// Names returns the names of the flag
func (f *Uint64Flag) Names() []string {
return flagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Uint64Flag) IsRequired() bool {
return f.Required
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *Uint64Flag) TakesValue() bool {
return true
@ -52,18 +16,18 @@ func (f *Uint64Flag) GetUsage() string {
return f.Usage
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Uint64Flag) IsVisible() bool {
return !f.Hidden
// GetCategory returns the category for the flag
func (f *Uint64Flag) GetCategory() string {
return f.Category
}
// Apply populates the flag given the flag set and environment
func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseUint(val, 0, 64)
if err != nil {
return fmt.Errorf("could not parse %q as uint64 value for flag %s: %s", val, f.Name, err)
return fmt.Errorf("could not parse %q as uint64 value from %s for flag %s: %s", val, source, f.Name, err)
}
f.Value = valInt
@ -88,10 +52,28 @@ func (f *Uint64Flag) GetValue() string {
return fmt.Sprintf("%d", f.Value)
}
// GetDefaultText returns the default text for this flag
func (f *Uint64Flag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Uint64Flag) GetEnvVars() []string {
return f.EnvVars
}
// Get returns the flags value in the given Context.
func (f *Uint64Flag) Get(ctx *Context) uint64 {
return ctx.Uint64(f.Name)
}
// Uint64 looks up the value of a local Uint64Flag, returns
// 0 if not found
func (c *Context) Uint64(name string) uint64 {
if fs := c.lookupFlagSet(name); fs != nil {
func (cCtx *Context) Uint64(name string) uint64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupUint64(name, fs)
}
return 0

View file

@ -21,11 +21,11 @@ type CommandNotFoundFunc func(*Context, string)
// customized usage error messages. This function is able to replace the
// original error messages. If this function is not set, the "Incorrect usage"
// is displayed and the execution is interrupted.
type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error
type OnUsageErrorFunc func(cCtx *Context, err error, isSubcommand bool) error
// ExitErrHandlerFunc is executed if provided in order to handle exitError values
// returned by Actions and Before/After functions.
type ExitErrHandlerFunc func(context *Context, err error)
type ExitErrHandlerFunc func(cCtx *Context, err error)
// FlagStringFunc is used by the help generation to display a flag, which is
// expected to be a single line.

2310
vendor/github.com/urfave/cli/v2/godoc-current.txt generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -10,34 +10,39 @@ import (
"unicode/utf8"
)
const (
helpName = "help"
helpAlias = "h"
)
var helpCommand = &Command{
Name: "help",
Aliases: []string{"h"},
Name: helpName,
Aliases: []string{helpAlias},
Usage: "Shows a list of commands or help for one command",
ArgsUsage: "[command]",
Action: func(c *Context) error {
args := c.Args()
Action: func(cCtx *Context) error {
args := cCtx.Args()
if args.Present() {
return ShowCommandHelp(c, args.First())
return ShowCommandHelp(cCtx, args.First())
}
_ = ShowAppHelp(c)
_ = ShowAppHelp(cCtx)
return nil
},
}
var helpSubcommand = &Command{
Name: "help",
Aliases: []string{"h"},
Name: helpName,
Aliases: []string{helpAlias},
Usage: "Shows a list of commands or help for one command",
ArgsUsage: "[command]",
Action: func(c *Context) error {
args := c.Args()
Action: func(cCtx *Context) error {
args := cCtx.Args()
if args.Present() {
return ShowCommandHelp(c, args.First())
return ShowCommandHelp(cCtx, args.First())
}
return ShowSubcommandHelp(c)
return ShowSubcommandHelp(cCtx)
},
}
@ -59,6 +64,11 @@ var HelpPrinter helpPrinter = printHelp
// HelpPrinterCustom is a function that writes the help output. It is used as
// the default implementation of HelpPrinter, and may be called directly if
// the ExtraInfo field is set on an App.
//
// In the default implementation, if the customFuncs argument contains a
// "wrapAt" key, which is a function which takes no arguments and returns
// an int, this int value will be used to produce a "wrap" function used
// by the default template to wrap long lines.
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
// VersionPrinter prints the version for the App
@ -71,30 +81,30 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
}
// ShowAppHelp is an action that displays the help.
func ShowAppHelp(c *Context) error {
tpl := c.App.CustomAppHelpTemplate
func ShowAppHelp(cCtx *Context) error {
tpl := cCtx.App.CustomAppHelpTemplate
if tpl == "" {
tpl = AppHelpTemplate
}
if c.App.ExtraInfo == nil {
HelpPrinter(c.App.Writer, tpl, c.App)
if cCtx.App.ExtraInfo == nil {
HelpPrinter(cCtx.App.Writer, tpl, cCtx.App)
return nil
}
customAppData := func() map[string]interface{} {
return map[string]interface{}{
"ExtraInfo": c.App.ExtraInfo,
"ExtraInfo": cCtx.App.ExtraInfo,
}
}
HelpPrinterCustom(c.App.Writer, tpl, c.App, customAppData())
HelpPrinterCustom(cCtx.App.Writer, tpl, cCtx.App, customAppData())
return nil
}
// DefaultAppComplete prints the list of subcommands as the default app completion method
func DefaultAppComplete(c *Context) {
DefaultCompleteWithFlags(nil)(c)
func DefaultAppComplete(cCtx *Context) {
DefaultCompleteWithFlags(nil)(cCtx)
}
func printCommandSuggestions(commands []*Command, writer io.Writer) {
@ -102,7 +112,7 @@ func printCommandSuggestions(commands []*Command, writer io.Writer) {
if command.Hidden {
continue
}
if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" {
if strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
for _, name := range command.Names() {
_, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage)
}
@ -159,23 +169,30 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
}
}
func DefaultCompleteWithFlags(cmd *Command) func(c *Context) {
return func(c *Context) {
func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) {
return func(cCtx *Context) {
if len(os.Args) > 2 {
lastArg := os.Args[len(os.Args)-2]
if strings.HasPrefix(lastArg, "-") {
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
if cmd != nil {
printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer)
printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer)
return
}
printFlagSuggestions(lastArg, cCtx.App.Flags, cCtx.App.Writer)
return
}
}
if cmd != nil {
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
} else {
printCommandSuggestions(c.App.Commands, c.App.Writer)
printCommandSuggestions(cmd.Subcommands, cCtx.App.Writer)
return
}
printCommandSuggestions(cCtx.App.Commands, cCtx.App.Writer)
}
}
@ -207,7 +224,13 @@ func ShowCommandHelp(ctx *Context, command string) error {
}
if ctx.App.CommandNotFound == nil {
return Exit(fmt.Sprintf("No help topic for '%v'", command), 3)
errMsg := fmt.Sprintf("No help topic for '%v'", command)
if ctx.App.Suggest {
if suggestion := SuggestCommand(ctx.App.Commands, command); suggestion != "" {
errMsg += ". " + suggestion
}
}
return Exit(errMsg, 3)
}
ctx.App.CommandNotFound(ctx, command)
@ -221,32 +244,32 @@ func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
}
// ShowSubcommandHelp prints help for the given subcommand
func ShowSubcommandHelp(c *Context) error {
if c == nil {
func ShowSubcommandHelp(cCtx *Context) error {
if cCtx == nil {
return nil
}
if c.Command != nil {
return ShowCommandHelp(c, c.Command.Name)
if cCtx.Command != nil {
return ShowCommandHelp(cCtx, cCtx.Command.Name)
}
return ShowCommandHelp(c, "")
return ShowCommandHelp(cCtx, "")
}
// ShowVersion prints the version number of the App
func ShowVersion(c *Context) {
VersionPrinter(c)
func ShowVersion(cCtx *Context) {
VersionPrinter(cCtx)
}
func printVersion(c *Context) {
_, _ = fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
func printVersion(cCtx *Context) {
_, _ = fmt.Fprintf(cCtx.App.Writer, "%v version %v\n", cCtx.App.Name, cCtx.App.Version)
}
// ShowCompletions prints the lists of commands within a given context
func ShowCompletions(c *Context) {
a := c.App
func ShowCompletions(cCtx *Context) {
a := cCtx.App
if a != nil && a.BashComplete != nil {
a.BashComplete(c)
a.BashComplete(cCtx)
}
}
@ -268,12 +291,29 @@ func ShowCommandCompletions(ctx *Context, command string) {
// The customFuncs map will be combined with a default template.FuncMap to
// allow using arbitrary functions in template rendering.
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
const maxLineLength = 10000
funcMap := template.FuncMap{
"join": strings.Join,
"indent": indent,
"nindent": nindent,
"trim": strings.TrimSpace,
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
"offset": offset,
}
if customFuncs["wrapAt"] != nil {
if wa, ok := customFuncs["wrapAt"]; ok {
if waf, ok := wa.(func() int); ok {
wrapAt := waf()
customFuncs["wrap"] = func(input string, offset int) string {
return wrap(input, offset, wrapAt)
}
}
}
}
for key, value := range customFuncs {
funcMap[key] = value
}
@ -297,20 +337,20 @@ func printHelp(out io.Writer, templ string, data interface{}) {
HelpPrinterCustom(out, templ, data, nil)
}
func checkVersion(c *Context) bool {
func checkVersion(cCtx *Context) bool {
found := false
for _, name := range VersionFlag.Names() {
if c.Bool(name) {
if cCtx.Bool(name) {
found = true
}
}
return found
}
func checkHelp(c *Context) bool {
func checkHelp(cCtx *Context) bool {
found := false
for _, name := range HelpFlag.Names() {
if c.Bool(name) {
if cCtx.Bool(name) {
found = true
}
}
@ -326,9 +366,9 @@ func checkCommandHelp(c *Context, name string) bool {
return false
}
func checkSubcommandHelp(c *Context) bool {
if c.Bool("h") || c.Bool("help") {
_ = ShowSubcommandHelp(c)
func checkSubcommandHelp(cCtx *Context) bool {
if cCtx.Bool("h") || cCtx.Bool("help") {
_ = ShowSubcommandHelp(cCtx)
return true
}
@ -350,20 +390,20 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
return true, arguments[:pos]
}
func checkCompletions(c *Context) bool {
if !c.shellComplete {
func checkCompletions(cCtx *Context) bool {
if !cCtx.shellComplete {
return false
}
if args := c.Args(); args.Present() {
if args := cCtx.Args(); args.Present() {
name := args.First()
if cmd := c.App.Command(name); cmd != nil {
if cmd := cCtx.App.Command(name); cmd != nil {
// let the command handle the completion
return false
}
}
ShowCompletions(c)
ShowCompletions(cCtx)
return true
}
@ -384,3 +424,55 @@ func indent(spaces int, v string) string {
func nindent(spaces int, v string) string {
return "\n" + indent(spaces, v)
}
func wrap(input string, offset int, wrapAt int) string {
var sb strings.Builder
lines := strings.Split(input, "\n")
padding := strings.Repeat(" ", offset)
for i, line := range lines {
if i != 0 {
sb.WriteString(padding)
}
sb.WriteString(wrapLine(line, offset, wrapAt, padding))
if i != len(lines)-1 {
sb.WriteString("\n")
}
}
return sb.String()
}
func wrapLine(input string, offset int, wrapAt int, padding string) string {
if wrapAt <= offset || len(input) <= wrapAt-offset {
return input
}
lineWidth := wrapAt - offset
words := strings.Fields(input)
if len(words) == 0 {
return input
}
wrapped := words[0]
spaceLeft := lineWidth - len(wrapped)
for _, word := range words[1:] {
if len(word)+1 > spaceLeft {
wrapped += "\n" + padding + word
spaceLeft = lineWidth - len(word)
} else {
wrapped += " " + word
spaceLeft -= 1 + len(word)
}
}
return wrapped
}
func offset(input string, fixed int) int {
return len(input) + fixed
}

View file

@ -0,0 +1,5 @@
mkdocs-git-revision-date-localized-plugin~=1.0
mkdocs-material-extensions~=1.0
mkdocs-material~=8.2
mkdocs~=1.3
pygments~=2.12

62
vendor/github.com/urfave/cli/v2/mkdocs.yml generated vendored Normal file
View file

@ -0,0 +1,62 @@
# NOTE: the mkdocs dependencies will need to be installed out of
# band until this whole thing gets more automated:
#
# pip install -r mkdocs-requirements.txt
#
site_name: urfave/cli
site_url: https://cli.urfave.org/
repo_url: https://github.com/urfave/cli
edit_uri: edit/main/docs/
nav:
- Home: index.md
- v2 Manual: v2/index.md
- v1 Manual: v1/index.md
theme:
name: material
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
toggle:
icon: material/brightness-4
name: dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-7
name: light mode
plugins:
- git-revision-date-localized
- search
# NOTE: this is the recommended configuration from
# https://squidfunk.github.io/mkdocs-material/setup/extensions/#recommended-configuration
markdown_extensions:
- abbr
- admonition
- attr_list
- def_list
- footnotes
- meta
- md_in_html
- toc:
permalink: true
- pymdownx.arithmatex:
generic: true
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.details
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.highlight
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde

View file

@ -26,9 +26,8 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
return err
}
errStr := err.Error()
trimmed := strings.TrimPrefix(errStr, "flag provided but not defined: -")
if errStr == trimmed {
trimmed, trimErr := flagFromError(err)
if trimErr != nil {
return err
}
@ -67,6 +66,19 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
}
}
const providedButNotDefinedErrMsg = "flag provided but not defined: -"
// flagFromError tries to parse a provided flag from an error message. If the
// parsing fials, it returns the input error and an empty string
func flagFromError(err error) (string, error) {
errStr := err.Error()
trimmed := strings.TrimPrefix(errStr, providedButNotDefinedErrMsg)
if errStr == trimmed {
return "", err
}
return trimmed, nil
}
func splitShortOptions(set *flag.FlagSet, arg string) []string {
shortFlagsExist := func(s string) bool {
for _, c := range s[1:] {

293
vendor/github.com/urfave/cli/v2/sliceflag.go generated vendored Normal file
View file

@ -0,0 +1,293 @@
//go:build go1.18
// +build go1.18
package cli
import (
"flag"
"reflect"
)
type (
// SliceFlag extends implementations like StringSliceFlag and IntSliceFlag with support for using slices directly,
// as Value and/or Destination.
// See also SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag, MultiIntFlag.
SliceFlag[T SliceFlagTarget[E], S ~[]E, E any] struct {
Target T
Value S
Destination *S
}
// SliceFlagTarget models a target implementation for use with SliceFlag.
// The three methods, SetValue, SetDestination, and GetDestination, are necessary to propagate Value and
// Destination, where Value is propagated inwards (initially), and Destination is propagated outwards (on every
// update).
SliceFlagTarget[E any] interface {
Flag
RequiredFlag
DocGenerationFlag
VisibleFlag
CategorizableFlag
// SetValue should propagate the given slice to the target, ideally as a new value.
// Note that a nil slice should nil/clear any existing value (modelled as ~[]E).
SetValue(slice []E)
// SetDestination should propagate the given slice to the target, ideally as a new value.
// Note that a nil slice should nil/clear any existing value (modelled as ~*[]E).
SetDestination(slice []E)
// GetDestination should return the current value referenced by any destination, or nil if nil/unset.
GetDestination() []E
}
// MultiStringFlag extends StringSliceFlag with support for using slices directly, as Value and/or Destination.
// See also SliceFlag.
MultiStringFlag = SliceFlag[*StringSliceFlag, []string, string]
// MultiFloat64Flag extends Float64SliceFlag with support for using slices directly, as Value and/or Destination.
// See also SliceFlag.
MultiFloat64Flag = SliceFlag[*Float64SliceFlag, []float64, float64]
// MultiInt64Flag extends Int64SliceFlag with support for using slices directly, as Value and/or Destination.
// See also SliceFlag.
MultiInt64Flag = SliceFlag[*Int64SliceFlag, []int64, int64]
// MultiIntFlag extends IntSliceFlag with support for using slices directly, as Value and/or Destination.
// See also SliceFlag.
MultiIntFlag = SliceFlag[*IntSliceFlag, []int, int]
flagValueHook struct {
value Generic
hook func()
}
)
var (
// compile time assertions
_ SliceFlagTarget[string] = (*StringSliceFlag)(nil)
_ SliceFlagTarget[string] = (*SliceFlag[*StringSliceFlag, []string, string])(nil)
_ SliceFlagTarget[string] = (*MultiStringFlag)(nil)
_ SliceFlagTarget[float64] = (*MultiFloat64Flag)(nil)
_ SliceFlagTarget[int64] = (*MultiInt64Flag)(nil)
_ SliceFlagTarget[int] = (*MultiIntFlag)(nil)
_ Generic = (*flagValueHook)(nil)
_ Serializer = (*flagValueHook)(nil)
)
func (x *SliceFlag[T, S, E]) Apply(set *flag.FlagSet) error {
x.Target.SetValue(x.convertSlice(x.Value))
destination := x.Destination
if destination == nil {
x.Target.SetDestination(nil)
return x.Target.Apply(set)
}
x.Target.SetDestination(x.convertSlice(*destination))
return applyFlagValueHook(set, x.Target.Apply, func() {
*destination = x.Target.GetDestination()
})
}
func (x *SliceFlag[T, S, E]) convertSlice(slice S) []E {
result := make([]E, len(slice))
copy(result, slice)
return result
}
func (x *SliceFlag[T, S, E]) SetValue(slice S) {
x.Value = slice
}
func (x *SliceFlag[T, S, E]) SetDestination(slice S) {
if slice != nil {
x.Destination = &slice
} else {
x.Destination = nil
}
}
func (x *SliceFlag[T, S, E]) GetDestination() S {
if destination := x.Destination; destination != nil {
return *destination
}
return nil
}
func (x *SliceFlag[T, S, E]) String() string { return x.Target.String() }
func (x *SliceFlag[T, S, E]) Names() []string { return x.Target.Names() }
func (x *SliceFlag[T, S, E]) IsSet() bool { return x.Target.IsSet() }
func (x *SliceFlag[T, S, E]) IsRequired() bool { return x.Target.IsRequired() }
func (x *SliceFlag[T, S, E]) TakesValue() bool { return x.Target.TakesValue() }
func (x *SliceFlag[T, S, E]) GetUsage() string { return x.Target.GetUsage() }
func (x *SliceFlag[T, S, E]) GetValue() string { return x.Target.GetValue() }
func (x *SliceFlag[T, S, E]) GetDefaultText() string { return x.Target.GetDefaultText() }
func (x *SliceFlag[T, S, E]) GetEnvVars() []string { return x.Target.GetEnvVars() }
func (x *SliceFlag[T, S, E]) IsVisible() bool { return x.Target.IsVisible() }
func (x *SliceFlag[T, S, E]) GetCategory() string { return x.Target.GetCategory() }
func (x *flagValueHook) Set(value string) error {
if err := x.value.Set(value); err != nil {
return err
}
x.hook()
return nil
}
func (x *flagValueHook) String() string {
// note: this is necessary due to the way Go's flag package handles defaults
isZeroValue := func(f flag.Value, v string) bool {
/*
https://cs.opensource.google/go/go/+/refs/tags/go1.18.3:src/flag/flag.go;drc=2580d0e08d5e9f979b943758d3c49877fb2324cb;l=453
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Build a zero value of the flag's Value type, and see if the
// result of calling its String method equals the value passed in.
// This works unless the Value type is itself an interface type.
typ := reflect.TypeOf(f)
var z reflect.Value
if typ.Kind() == reflect.Pointer {
z = reflect.New(typ.Elem())
} else {
z = reflect.Zero(typ)
}
return v == z.Interface().(flag.Value).String()
}
if x.value != nil {
// only return non-empty if not the same string as returned by the zero value
if s := x.value.String(); !isZeroValue(x.value, s) {
return s
}
}
return ``
}
func (x *flagValueHook) Serialize() string {
if value, ok := x.value.(Serializer); ok {
return value.Serialize()
}
return x.String()
}
// applyFlagValueHook wraps calls apply then wraps flags to call a hook function on update and after initial apply.
func applyFlagValueHook(set *flag.FlagSet, apply func(set *flag.FlagSet) error, hook func()) error {
if apply == nil || set == nil || hook == nil {
panic(`invalid input`)
}
var tmp flag.FlagSet
if err := apply(&tmp); err != nil {
return err
}
tmp.VisitAll(func(f *flag.Flag) { set.Var(&flagValueHook{value: f.Value, hook: hook}, f.Name, f.Usage) })
hook()
return nil
}
// newSliceFlagValue is for implementing SliceFlagTarget.SetValue and SliceFlagTarget.SetDestination.
// It's e.g. as part of StringSliceFlag.SetValue, using the factory NewStringSlice.
func newSliceFlagValue[R any, S ~[]E, E any](factory func(defaults ...E) *R, defaults S) *R {
if defaults == nil {
return nil
}
return factory(defaults...)
}
// unwrapFlagValue strips any/all *flagValueHook wrappers.
func unwrapFlagValue(v flag.Value) flag.Value {
for {
h, ok := v.(*flagValueHook)
if !ok {
return v
}
v = h.value
}
}
// NOTE: the methods below are in this file to make use of the build constraint
func (f *Float64SliceFlag) SetValue(slice []float64) {
f.Value = newSliceFlagValue(NewFloat64Slice, slice)
}
func (f *Float64SliceFlag) SetDestination(slice []float64) {
f.Destination = newSliceFlagValue(NewFloat64Slice, slice)
}
func (f *Float64SliceFlag) GetDestination() []float64 {
if destination := f.Destination; destination != nil {
return destination.Value()
}
return nil
}
func (f *Int64SliceFlag) SetValue(slice []int64) {
f.Value = newSliceFlagValue(NewInt64Slice, slice)
}
func (f *Int64SliceFlag) SetDestination(slice []int64) {
f.Destination = newSliceFlagValue(NewInt64Slice, slice)
}
func (f *Int64SliceFlag) GetDestination() []int64 {
if destination := f.Destination; destination != nil {
return destination.Value()
}
return nil
}
func (f *IntSliceFlag) SetValue(slice []int) {
f.Value = newSliceFlagValue(NewIntSlice, slice)
}
func (f *IntSliceFlag) SetDestination(slice []int) {
f.Destination = newSliceFlagValue(NewIntSlice, slice)
}
func (f *IntSliceFlag) GetDestination() []int {
if destination := f.Destination; destination != nil {
return destination.Value()
}
return nil
}
func (f *StringSliceFlag) SetValue(slice []string) {
f.Value = newSliceFlagValue(NewStringSlice, slice)
}
func (f *StringSliceFlag) SetDestination(slice []string) {
f.Destination = newSliceFlagValue(NewStringSlice, slice)
}
func (f *StringSliceFlag) GetDestination() []string {
if destination := f.Destination; destination != nil {
return destination.Value()
}
return nil
}

10
vendor/github.com/urfave/cli/v2/sliceflag_pre18.go generated vendored Normal file
View file

@ -0,0 +1,10 @@
//go:build !go1.18
// +build !go1.18
package cli
import (
"flag"
)
func unwrapFlagValue(v flag.Value) flag.Value { return v }

60
vendor/github.com/urfave/cli/v2/suggestions.go generated vendored Normal file
View file

@ -0,0 +1,60 @@
package cli
import (
"fmt"
"github.com/xrash/smetrics"
)
func jaroWinkler(a, b string) float64 {
// magic values are from https://github.com/xrash/smetrics/blob/039620a656736e6ad994090895784a7af15e0b80/jaro-winkler.go#L8
const (
boostThreshold = 0.7
prefixSize = 4
)
return smetrics.JaroWinkler(a, b, boostThreshold, prefixSize)
}
func suggestFlag(flags []Flag, provided string, hideHelp bool) string {
distance := 0.0
suggestion := ""
for _, flag := range flags {
flagNames := flag.Names()
if !hideHelp {
flagNames = append(flagNames, HelpFlag.Names()...)
}
for _, name := range flagNames {
newDistance := jaroWinkler(name, provided)
if newDistance > distance {
distance = newDistance
suggestion = name
}
}
}
if len(suggestion) == 1 {
suggestion = "-" + suggestion
} else if len(suggestion) > 1 {
suggestion = "--" + suggestion
}
return suggestion
}
// suggestCommand takes a list of commands and a provided string to suggest a
// command name
func suggestCommand(commands []*Command, provided string) (suggestion string) {
distance := 0.0
for _, command := range commands {
for _, name := range append(command.Names(), helpName, helpAlias) {
newDistance := jaroWinkler(name, provided)
if newDistance > distance {
distance = newDistance
suggestion = name
}
}
}
return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion)
}

View file

@ -4,16 +4,16 @@ package cli
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
var AppHelpTemplate = `NAME:
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
{{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
USAGE:
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
VERSION:
{{.Version}}{{end}}{{end}}{{if .Description}}
DESCRIPTION:
{{.Description | nindent 3 | trim}}{{end}}{{if len .Authors}}
{{wrap .Description 3}}{{end}}{{if len .Authors}}
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{range $index, $author := .Authors}}{{if $index}}
@ -22,34 +22,44 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
{{if .Name}}{{.Name}}
{{end}}{{range .Flags}}{{.}}
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
GLOBAL OPTIONS:
{{range $index, $option := .VisibleFlags}}{{if $index}}
{{end}}{{$option}}{{end}}{{end}}{{if .Copyright}}
{{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}}
COPYRIGHT:
{{.Copyright}}{{end}}
{{wrap .Copyright 3}}{{end}}
`
// CommandHelpTemplate is the text template for the command help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
var CommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}}
{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
USAGE:
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
CATEGORY:
{{.Category}}{{end}}{{if .Description}}
DESCRIPTION:
{{.Description | nindent 3 | trim}}{{end}}{{if .VisibleFlags}}
{{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}}
OPTIONS:{{range .VisibleFlagCategories}}
{{if .Name}}{{.Name}}
{{end}}{{range .Flags}}{{.}}
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
OPTIONS:
{{range .VisibleFlags}}{{.}}
{{end}}{{end}}
{{end}}{{end}}{{end}}
`
// SubcommandHelpTemplate is the text template for the subcommand help topic.
@ -59,10 +69,10 @@ var SubcommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}}
USAGE:
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
DESCRIPTION:
{{.Description | nindent 3 | trim}}{{end}}
{{wrap .Description 3}}{{end}}
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}}

672
vendor/github.com/urfave/cli/v2/zz_generated.flags.go generated vendored Normal file
View file

@ -0,0 +1,672 @@
// WARNING: this file is generated. DO NOT EDIT
package cli
import "time"
// Float64SliceFlag is a flag with type *Float64Slice
type Float64SliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *Float64Slice
Destination *Float64Slice
Aliases []string
EnvVars []string
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Float64SliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Float64SliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Float64SliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Float64SliceFlag) IsVisible() bool {
return !f.Hidden
}
// GenericFlag is a flag with type Generic
type GenericFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value Generic
Destination *Generic
Aliases []string
EnvVars []string
TakesFile bool
}
// String returns a readable representation of this value (for usage defaults)
func (f *GenericFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *GenericFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *GenericFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *GenericFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *GenericFlag) IsVisible() bool {
return !f.Hidden
}
// Int64SliceFlag is a flag with type *Int64Slice
type Int64SliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *Int64Slice
Destination *Int64Slice
Aliases []string
EnvVars []string
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Int64SliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Int64SliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Int64SliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Int64SliceFlag) IsVisible() bool {
return !f.Hidden
}
// IntSliceFlag is a flag with type *IntSlice
type IntSliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *IntSlice
Destination *IntSlice
Aliases []string
EnvVars []string
}
// IsSet returns whether or not the flag has been set through env or file
func (f *IntSliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *IntSliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *IntSliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *IntSliceFlag) IsVisible() bool {
return !f.Hidden
}
// PathFlag is a flag with type Path
type PathFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value Path
Destination *Path
Aliases []string
EnvVars []string
TakesFile bool
}
// String returns a readable representation of this value (for usage defaults)
func (f *PathFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *PathFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *PathFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *PathFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *PathFlag) IsVisible() bool {
return !f.Hidden
}
// StringSliceFlag is a flag with type *StringSlice
type StringSliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *StringSlice
Destination *StringSlice
Aliases []string
EnvVars []string
TakesFile bool
}
// IsSet returns whether or not the flag has been set through env or file
func (f *StringSliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *StringSliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *StringSliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *StringSliceFlag) IsVisible() bool {
return !f.Hidden
}
// TimestampFlag is a flag with type *Timestamp
type TimestampFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *Timestamp
Destination *Timestamp
Aliases []string
EnvVars []string
Layout string
}
// String returns a readable representation of this value (for usage defaults)
func (f *TimestampFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *TimestampFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *TimestampFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *TimestampFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *TimestampFlag) IsVisible() bool {
return !f.Hidden
}
// BoolFlag is a flag with type bool
type BoolFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value bool
Destination *bool
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *BoolFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *BoolFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *BoolFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *BoolFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *BoolFlag) IsVisible() bool {
return !f.Hidden
}
// Float64Flag is a flag with type float64
type Float64Flag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value float64
Destination *float64
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *Float64Flag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Float64Flag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Float64Flag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Float64Flag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Float64Flag) IsVisible() bool {
return !f.Hidden
}
// IntFlag is a flag with type int
type IntFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value int
Destination *int
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *IntFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *IntFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *IntFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *IntFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *IntFlag) IsVisible() bool {
return !f.Hidden
}
// Int64Flag is a flag with type int64
type Int64Flag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value int64
Destination *int64
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *Int64Flag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Int64Flag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Int64Flag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Int64Flag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Int64Flag) IsVisible() bool {
return !f.Hidden
}
// StringFlag is a flag with type string
type StringFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value string
Destination *string
Aliases []string
EnvVars []string
TakesFile bool
}
// String returns a readable representation of this value (for usage defaults)
func (f *StringFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *StringFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *StringFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *StringFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *StringFlag) IsVisible() bool {
return !f.Hidden
}
// DurationFlag is a flag with type time.Duration
type DurationFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value time.Duration
Destination *time.Duration
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *DurationFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *DurationFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *DurationFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *DurationFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *DurationFlag) IsVisible() bool {
return !f.Hidden
}
// UintFlag is a flag with type uint
type UintFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value uint
Destination *uint
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *UintFlag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *UintFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *UintFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *UintFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *UintFlag) IsVisible() bool {
return !f.Hidden
}
// Uint64Flag is a flag with type uint64
type Uint64Flag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value uint64
Destination *uint64
Aliases []string
EnvVars []string
}
// String returns a readable representation of this value (for usage defaults)
func (f *Uint64Flag) String() string {
return FlagStringer(f)
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Uint64Flag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Uint64Flag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Uint64Flag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Uint64Flag) IsVisible() bool {
return !f.Hidden
}
// vim:ro