mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-06-26 18:18:24 +00:00
[no-relnote] Migrate to urfave v3
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
This commit is contained in:
2
vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
2
vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
@@ -1,2 +0,0 @@
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
14
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
14
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
@@ -1,14 +0,0 @@
|
||||
*.coverprofile
|
||||
*.exe
|
||||
*.orig
|
||||
.*envrc
|
||||
.envrc
|
||||
.idea
|
||||
# goimports is installed here if not available
|
||||
/.local/
|
||||
/site/
|
||||
coverage.txt
|
||||
internal/*/built-example
|
||||
vendor
|
||||
/cmd/urfave-cli-genflags/urfave-cli-genflags
|
||||
*.exe
|
||||
4
vendor/github.com/urfave/cli/v2/.golangci.yaml
generated
vendored
4
vendor/github.com/urfave/cli/v2/.golangci.yaml
generated
vendored
@@ -1,4 +0,0 @@
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
linters:
|
||||
enable:
|
||||
- misspell
|
||||
19
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
19
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
@@ -1,19 +0,0 @@
|
||||
# cli
|
||||
|
||||
[](https://github.com/urfave/cli/actions/workflows/cli.yml)
|
||||
[](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||
[](https://goreportcard.com/report/github.com/urfave/cli/v2)
|
||||
[](https://app.codecov.io/gh/urfave/cli/tree/v2-maint)
|
||||
|
||||
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.
|
||||
|
||||
## Documentation
|
||||
|
||||
More documentation is available in [`./docs`](./docs) or the hosted
|
||||
documentation site at <https://cli.urfave.org>.
|
||||
|
||||
## License
|
||||
|
||||
See [`LICENSE`](./LICENSE)
|
||||
536
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
536
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
@@ -1,536 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const suggestDidYouMeanTemplate = "Did you mean %q?"
|
||||
|
||||
var (
|
||||
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)
|
||||
ignoreFlagPrefix = "test." // this is to ignore test flags when adding flags from other packages
|
||||
|
||||
SuggestFlag SuggestFlagFunc = nil // initialized in suggestions.go unless built with urfave_cli_no_suggest
|
||||
SuggestCommand SuggestCommandFunc = nil // initialized in suggestions.go unless built with urfave_cli_no_suggest
|
||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||
)
|
||||
|
||||
// App is the main structure of a cli application. It is recommended that
|
||||
// an app be created with the cli.NewApp() function
|
||||
type App struct {
|
||||
// The name of the program. Defaults to path.Base(os.Args[0])
|
||||
Name string
|
||||
// Full name of command for help, defaults to Name
|
||||
HelpName string
|
||||
// Description of the program.
|
||||
Usage string
|
||||
// Text to override the USAGE section of help
|
||||
UsageText string
|
||||
// Whether this command supports arguments
|
||||
Args bool
|
||||
// Description of the program argument format.
|
||||
ArgsUsage string
|
||||
// Version of the program
|
||||
Version string
|
||||
// Description of the program
|
||||
Description string
|
||||
// DefaultCommand is the (optional) name of a command
|
||||
// to run if no command names are passed as CLI arguments.
|
||||
DefaultCommand string
|
||||
// List of commands to execute
|
||||
Commands []*Command
|
||||
// List of flags to parse
|
||||
Flags []Flag
|
||||
// Boolean to enable bash completion commands
|
||||
EnableBashCompletion bool
|
||||
// Boolean to hide built-in help command and help flag
|
||||
HideHelp bool
|
||||
// Boolean to hide built-in help command but keep help flag.
|
||||
// Ignored if HideHelp is true.
|
||||
HideHelpCommand bool
|
||||
// Boolean to hide built-in version flag and the VERSION section of help
|
||||
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
|
||||
// If a non-nil error is returned, no subcommands are run
|
||||
Before BeforeFunc
|
||||
// An action to execute after any subcommands are run, but after the subcommand has finished
|
||||
// It is run even if Action() panics
|
||||
After AfterFunc
|
||||
// The action to execute when no subcommands are specified
|
||||
Action ActionFunc
|
||||
// Execute this function if the proper command cannot be found
|
||||
CommandNotFound CommandNotFoundFunc
|
||||
// Execute this function if a usage error occurs
|
||||
OnUsageError OnUsageErrorFunc
|
||||
// Execute this function when an invalid flag is accessed from the context
|
||||
InvalidFlagAccessHandler InvalidFlagAccessFunc
|
||||
// Compilation date
|
||||
Compiled time.Time
|
||||
// List of all authors who contributed
|
||||
Authors []*Author
|
||||
// Copyright of the binary if any
|
||||
Copyright string
|
||||
// Reader reader to write input to (useful for tests)
|
||||
Reader io.Reader
|
||||
// Writer writer to write output to
|
||||
Writer io.Writer
|
||||
// ErrWriter writes error output
|
||||
ErrWriter io.Writer
|
||||
// ExitErrHandler processes any error encountered while running an App before
|
||||
// it is returned to the caller. If no function is provided, HandleExitCoder
|
||||
// is used as the default behavior.
|
||||
ExitErrHandler ExitErrHandlerFunc
|
||||
// Other custom info
|
||||
Metadata map[string]interface{}
|
||||
// Carries a function which returns app specific info.
|
||||
ExtraInfo func() map[string]string
|
||||
// CustomAppHelpTemplate the text template for app help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
CustomAppHelpTemplate string
|
||||
// SliceFlagSeparator is used to customize the separator for SliceFlag, the default is ","
|
||||
SliceFlagSeparator string
|
||||
// DisableSliceFlagSeparator is used to disable SliceFlagSeparator, the default is false
|
||||
DisableSliceFlagSeparator bool
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
// Enable suggestions for commands and flags
|
||||
Suggest bool
|
||||
// Allows global flags set by libraries which use flag.XXXVar(...) directly
|
||||
// to be parsed through this library
|
||||
AllowExtFlags bool
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool
|
||||
|
||||
didSetup bool
|
||||
separator separatorSpec
|
||||
|
||||
rootCommand *Command
|
||||
}
|
||||
|
||||
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 {
|
||||
info, err := os.Stat(os.Args[0])
|
||||
if err != nil {
|
||||
return time.Now()
|
||||
}
|
||||
return info.ModTime()
|
||||
}
|
||||
|
||||
// NewApp creates a new cli Application with some reasonable defaults for Name,
|
||||
// Usage, Version and Action.
|
||||
func NewApp() *App {
|
||||
return &App{
|
||||
Name: filepath.Base(os.Args[0]),
|
||||
Usage: "A new cli application",
|
||||
UsageText: "",
|
||||
BashComplete: DefaultAppComplete,
|
||||
Action: helpCommand.Action,
|
||||
Compiled: compileTime(),
|
||||
Reader: os.Stdin,
|
||||
Writer: os.Stdout,
|
||||
ErrWriter: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// Setup runs initialization code to ensure all data structures are ready for
|
||||
// `Run` or inspection prior to `Run`. It is internally called by `Run`, but
|
||||
// will return early if setup has already happened.
|
||||
func (a *App) Setup() {
|
||||
if a.didSetup {
|
||||
return
|
||||
}
|
||||
|
||||
a.didSetup = true
|
||||
|
||||
if a.Name == "" {
|
||||
a.Name = filepath.Base(os.Args[0])
|
||||
}
|
||||
|
||||
if a.HelpName == "" {
|
||||
a.HelpName = a.Name
|
||||
}
|
||||
|
||||
if a.Usage == "" {
|
||||
a.Usage = "A new cli application"
|
||||
}
|
||||
|
||||
if a.Version == "" {
|
||||
a.HideVersion = true
|
||||
}
|
||||
|
||||
if a.BashComplete == nil {
|
||||
a.BashComplete = DefaultAppComplete
|
||||
}
|
||||
|
||||
if a.Action == nil {
|
||||
a.Action = helpCommand.Action
|
||||
}
|
||||
|
||||
if a.Compiled == (time.Time{}) {
|
||||
a.Compiled = compileTime()
|
||||
}
|
||||
|
||||
if a.Reader == nil {
|
||||
a.Reader = os.Stdin
|
||||
}
|
||||
|
||||
if a.Writer == nil {
|
||||
a.Writer = os.Stdout
|
||||
}
|
||||
|
||||
if a.ErrWriter == nil {
|
||||
a.ErrWriter = os.Stderr
|
||||
}
|
||||
|
||||
if a.AllowExtFlags {
|
||||
// add global flags added by other packages
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
// skip test flags
|
||||
if !strings.HasPrefix(f.Name, ignoreFlagPrefix) {
|
||||
a.Flags = append(a.Flags, &extFlag{f})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if len(a.SliceFlagSeparator) != 0 {
|
||||
a.separator.customized = true
|
||||
a.separator.sep = a.SliceFlagSeparator
|
||||
}
|
||||
|
||||
if a.DisableSliceFlagSeparator {
|
||||
a.separator.customized = true
|
||||
a.separator.disabled = true
|
||||
}
|
||||
|
||||
for _, c := range a.Commands {
|
||||
cname := c.Name
|
||||
if c.HelpName != "" {
|
||||
cname = c.HelpName
|
||||
}
|
||||
c.separator = a.separator
|
||||
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname)
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
}
|
||||
|
||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
||||
if !a.HideHelpCommand {
|
||||
a.appendCommand(helpCommand)
|
||||
}
|
||||
|
||||
if HelpFlag != nil {
|
||||
a.appendFlag(HelpFlag)
|
||||
}
|
||||
}
|
||||
|
||||
if !a.HideVersion {
|
||||
a.appendFlag(VersionFlag)
|
||||
}
|
||||
|
||||
a.categories = newCommandCategories()
|
||||
for _, command := range a.Commands {
|
||||
a.categories.AddCommand(command.Category, command)
|
||||
}
|
||||
sort.Sort(a.categories.(*commandCategories))
|
||||
|
||||
a.flagCategories = newFlagCategoriesFromFlags(a.Flags)
|
||||
|
||||
if a.Metadata == nil {
|
||||
a.Metadata = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) newRootCommand() *Command {
|
||||
return &Command{
|
||||
Name: a.Name,
|
||||
Usage: a.Usage,
|
||||
UsageText: a.UsageText,
|
||||
Description: a.Description,
|
||||
ArgsUsage: a.ArgsUsage,
|
||||
BashComplete: a.BashComplete,
|
||||
Before: a.Before,
|
||||
After: a.After,
|
||||
Action: a.Action,
|
||||
OnUsageError: a.OnUsageError,
|
||||
Subcommands: a.Commands,
|
||||
Flags: a.Flags,
|
||||
flagCategories: a.flagCategories,
|
||||
HideHelp: a.HideHelp,
|
||||
HideHelpCommand: a.HideHelpCommand,
|
||||
UseShortOptionHandling: a.UseShortOptionHandling,
|
||||
HelpName: a.HelpName,
|
||||
CustomHelpTemplate: a.CustomAppHelpTemplate,
|
||||
categories: a.categories,
|
||||
SkipFlagParsing: a.SkipFlagParsing,
|
||||
isRoot: true,
|
||||
separator: a.separator,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
||||
return flagSet(a.Name, a.Flags, a.separator)
|
||||
}
|
||||
|
||||
func (a *App) useShortOptionHandling() bool {
|
||||
return a.UseShortOptionHandling
|
||||
}
|
||||
|
||||
// Run is the entry point to the cli app. Parses the arguments slice and routes
|
||||
// to the proper flag/args combination
|
||||
func (a *App) Run(arguments []string) (err error) {
|
||||
return a.RunContext(context.Background(), arguments)
|
||||
}
|
||||
|
||||
// RunContext is like Run except it takes a Context that will be
|
||||
// passed to its commands and sub-commands. Through this, you can
|
||||
// propagate timeouts and cancellation requests
|
||||
func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||
a.Setup()
|
||||
|
||||
// handle the completion flag separately from the flagset since
|
||||
// completion could be attempted after a flag, but before its value was put
|
||||
// on the command line. this causes the flagset to interpret the completion
|
||||
// flag name as the value of the flag before it which is undesirable
|
||||
// note that we can only do this because the shell autocomplete function
|
||||
// always appends the completion flag at the end of the command
|
||||
shellComplete, arguments := checkShellCompleteFlag(a, arguments)
|
||||
|
||||
cCtx := NewContext(a, nil, &Context{Context: ctx})
|
||||
cCtx.shellComplete = shellComplete
|
||||
|
||||
a.rootCommand = a.newRootCommand()
|
||||
cCtx.Command = a.rootCommand
|
||||
|
||||
if err := checkDuplicatedCmds(a.rootCommand); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.rootCommand.Run(cCtx, arguments...)
|
||||
}
|
||||
|
||||
// RunAsSubcommand is for legacy/compatibility purposes only. New code should only
|
||||
// use App.RunContext. This function is slated to be removed in v3.
|
||||
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
||||
a.Setup()
|
||||
|
||||
cCtx := NewContext(a, nil, ctx)
|
||||
cCtx.shellComplete = ctx.shellComplete
|
||||
|
||||
a.rootCommand = a.newRootCommand()
|
||||
cCtx.Command = a.rootCommand
|
||||
|
||||
return a.rootCommand.Run(cCtx, ctx.Args().Slice()...)
|
||||
}
|
||||
|
||||
func (a *App) suggestFlagFromError(err error, command string) (string, error) {
|
||||
flag, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := a.Flags
|
||||
hideHelp := a.HideHelp
|
||||
if command != "" {
|
||||
cmd := a.Command(command)
|
||||
if cmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = cmd.Flags
|
||||
hideHelp = hideHelp || cmd.HideHelp
|
||||
}
|
||||
|
||||
if SuggestFlag == nil {
|
||||
return "", err
|
||||
}
|
||||
suggestion := SuggestFlag(flags, flag, 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
|
||||
// to cli.App.Run. This will cause the application to exit with the given error
|
||||
// code in the cli.ExitCoder
|
||||
func (a *App) RunAndExitOnError() {
|
||||
if err := a.Run(os.Args); err != nil {
|
||||
_, _ = fmt.Fprintln(a.ErrWriter, err)
|
||||
OsExiter(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Command returns the named command on App. Returns nil if the command does not exist
|
||||
func (a *App) Command(name string) *Command {
|
||||
for _, c := range a.Commands {
|
||||
if c.HasName(name) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VisibleCategories returns a slice of categories and commands that are
|
||||
// Hidden=false
|
||||
func (a *App) VisibleCategories() []CommandCategory {
|
||||
ret := []CommandCategory{}
|
||||
for _, category := range a.categories.Categories() {
|
||||
if visible := func() CommandCategory {
|
||||
if len(category.VisibleCommands()) > 0 {
|
||||
return category
|
||||
}
|
||||
return nil
|
||||
}(); visible != nil {
|
||||
ret = append(ret, visible)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (a *App) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range a.Commands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, 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)
|
||||
}
|
||||
|
||||
func (a *App) appendFlag(fl Flag) {
|
||||
if !hasFlag(a.Flags, fl) {
|
||||
a.Flags = append(a.Flags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) appendCommand(c *Command) {
|
||||
if !hasCommand(a.Commands, c) {
|
||||
a.Commands = append(a.Commands, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) handleExitCoder(cCtx *Context, err error) {
|
||||
if a.ExitErrHandler != nil {
|
||||
a.ExitErrHandler(cCtx, err)
|
||||
} else {
|
||||
HandleExitCoder(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) argsWithDefaultCommand(oldArgs Args) Args {
|
||||
if a.DefaultCommand != "" {
|
||||
rawArgs := append([]string{a.DefaultCommand}, oldArgs.Slice()...)
|
||||
newArgs := args(rawArgs)
|
||||
|
||||
return &newArgs
|
||||
}
|
||||
|
||||
return oldArgs
|
||||
}
|
||||
|
||||
func runFlagActions(c *Context, fs []Flag) error {
|
||||
for _, f := range fs {
|
||||
isSet := false
|
||||
for _, name := range f.Names() {
|
||||
if c.IsSet(name) {
|
||||
isSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isSet {
|
||||
if af, ok := f.(ActionableFlag); ok {
|
||||
if err := af.RunAction(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Author represents someone who has contributed to a cli project.
|
||||
type Author struct {
|
||||
Name string // The Authors name
|
||||
Email string // The Authors email
|
||||
}
|
||||
|
||||
// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
|
||||
func (a *Author) String() string {
|
||||
e := ""
|
||||
if a.Email != "" {
|
||||
e = " <" + a.Email + ">"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%v", a.Name, e)
|
||||
}
|
||||
|
||||
// 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{}, cCtx *Context) (err error) {
|
||||
switch a := action.(type) {
|
||||
case ActionFunc:
|
||||
return a(cCtx)
|
||||
case func(*Context) error:
|
||||
return a(cCtx)
|
||||
case func(*Context): // deprecated function signature
|
||||
a(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
return errInvalidActionType
|
||||
}
|
||||
|
||||
func checkStringSliceIncludes(want string, sSlice []string) bool {
|
||||
found := false
|
||||
for _, s := range sSlice {
|
||||
if want == s {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
54
vendor/github.com/urfave/cli/v2/args.go
generated
vendored
54
vendor/github.com/urfave/cli/v2/args.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
package cli
|
||||
|
||||
type Args interface {
|
||||
// Get returns the nth argument, or else a blank string
|
||||
Get(n int) string
|
||||
// First returns the first argument, or else a blank string
|
||||
First() string
|
||||
// Tail returns the rest of the arguments (not the first one)
|
||||
// or else an empty string slice
|
||||
Tail() []string
|
||||
// Len returns the length of the wrapped slice
|
||||
Len() int
|
||||
// Present checks if there are any arguments present
|
||||
Present() bool
|
||||
// Slice returns a copy of the internal slice
|
||||
Slice() []string
|
||||
}
|
||||
|
||||
type args []string
|
||||
|
||||
func (a *args) Get(n int) string {
|
||||
if len(*a) > n {
|
||||
return (*a)[n]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *args) First() string {
|
||||
return a.Get(0)
|
||||
}
|
||||
|
||||
func (a *args) Tail() []string {
|
||||
if a.Len() >= 2 {
|
||||
tail := []string((*a)[1:])
|
||||
ret := make([]string, len(tail))
|
||||
copy(ret, tail)
|
||||
return ret
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (a *args) Len() int {
|
||||
return len(*a)
|
||||
}
|
||||
|
||||
func (a *args) Present() bool {
|
||||
return a.Len() != 0
|
||||
}
|
||||
|
||||
func (a *args) Slice() []string {
|
||||
ret := make([]string, len(*a))
|
||||
copy(ret, *a)
|
||||
return ret
|
||||
}
|
||||
25
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
25
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
@@ -1,25 +0,0 @@
|
||||
// Package cli provides a minimal framework for creating and organizing command line
|
||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
||||
// cli application can be written as follows:
|
||||
//
|
||||
// func main() {
|
||||
// (&cli.App{}).Run(os.Args)
|
||||
// }
|
||||
//
|
||||
// Of course this application does not do much, so let's make this an actual application:
|
||||
//
|
||||
// func main() {
|
||||
// app := &cli.App{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// app.Run(os.Args)
|
||||
// }
|
||||
package cli
|
||||
|
||||
//go:generate make -C cmd/urfave-cli-genflags run
|
||||
421
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
421
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
@@ -1,421 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Command is a subcommand for a cli.App.
|
||||
type Command struct {
|
||||
// The name of the command
|
||||
Name string
|
||||
// A list of aliases for the command
|
||||
Aliases []string
|
||||
// A short description of the usage of this command
|
||||
Usage string
|
||||
// Custom text to show on USAGE section of help
|
||||
UsageText string
|
||||
// A longer explanation of how the command works
|
||||
Description string
|
||||
// Whether this command supports arguments
|
||||
Args bool
|
||||
// A short description of the arguments of this command
|
||||
ArgsUsage string
|
||||
// The category the command is part of
|
||||
Category string
|
||||
// The function to call when checking for bash command completions
|
||||
BashComplete BashCompleteFunc
|
||||
// An action to execute before any sub-subcommands are run, but after the context is ready
|
||||
// If a non-nil error is returned, no sub-subcommands are run
|
||||
Before BeforeFunc
|
||||
// An action to execute after any subcommands are run, but after the subcommand has finished
|
||||
// It is run even if Action() panics
|
||||
After AfterFunc
|
||||
// The function to call when this command is invoked
|
||||
Action ActionFunc
|
||||
// Execute this function if a usage error occurs.
|
||||
OnUsageError OnUsageErrorFunc
|
||||
// List of child commands
|
||||
Subcommands []*Command
|
||||
// List of flags to parse
|
||||
Flags []Flag
|
||||
flagCategories FlagCategories
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool
|
||||
// Boolean to hide built-in help command and help flag
|
||||
HideHelp bool
|
||||
// Boolean to hide built-in help command but keep help flag
|
||||
// Ignored if HideHelp is true.
|
||||
HideHelpCommand bool
|
||||
// Boolean to hide this command from help or completion
|
||||
Hidden bool
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
|
||||
// Full name of command for help, defaults to full command name, including parent commands.
|
||||
HelpName string
|
||||
commandNamePath []string
|
||||
|
||||
// CustomHelpTemplate 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.
|
||||
CustomHelpTemplate string
|
||||
|
||||
// categories contains the categorized commands and is populated on app startup
|
||||
categories CommandCategories
|
||||
|
||||
// if this is a root "special" command
|
||||
isRoot bool
|
||||
|
||||
separator separatorSpec
|
||||
}
|
||||
|
||||
type Commands []*Command
|
||||
|
||||
type CommandsByName []*Command
|
||||
|
||||
func (c CommandsByName) Len() int {
|
||||
return len(c)
|
||||
}
|
||||
|
||||
func (c CommandsByName) Less(i, j int) bool {
|
||||
return lexicographicLess(c[i].Name, c[j].Name)
|
||||
}
|
||||
|
||||
func (c CommandsByName) Swap(i, j int) {
|
||||
c[i], c[j] = c[j], c[i]
|
||||
}
|
||||
|
||||
// FullName returns the full name of the command.
|
||||
// For subcommands this ensures that parent commands are part of the command path
|
||||
func (c *Command) FullName() string {
|
||||
if c.commandNamePath == nil {
|
||||
return c.Name
|
||||
}
|
||||
return strings.Join(c.commandNamePath, " ")
|
||||
}
|
||||
|
||||
func (cmd *Command) Command(name string) *Command {
|
||||
for _, c := range cmd.Subcommands {
|
||||
if c.HasName(name) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Command) setup(ctx *Context) {
|
||||
if c.Command(helpCommand.Name) == nil && !c.HideHelp {
|
||||
if !c.HideHelpCommand {
|
||||
c.Subcommands = append(c.Subcommands, helpCommand)
|
||||
}
|
||||
}
|
||||
|
||||
if !c.HideHelp && HelpFlag != nil {
|
||||
// append help to flags
|
||||
c.appendFlag(HelpFlag)
|
||||
}
|
||||
|
||||
if ctx.App.UseShortOptionHandling {
|
||||
c.UseShortOptionHandling = true
|
||||
}
|
||||
|
||||
c.categories = newCommandCategories()
|
||||
for _, command := range c.Subcommands {
|
||||
c.categories.AddCommand(command.Category, command)
|
||||
}
|
||||
sort.Sort(c.categories.(*commandCategories))
|
||||
|
||||
for _, scmd := range c.Subcommands {
|
||||
if scmd.HelpName == "" {
|
||||
scmd.HelpName = fmt.Sprintf("%s %s", c.HelpName, scmd.Name)
|
||||
}
|
||||
scmd.separator = c.separator
|
||||
}
|
||||
|
||||
if c.BashComplete == nil {
|
||||
c.BashComplete = DefaultCompleteWithFlags(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
|
||||
|
||||
if !c.isRoot {
|
||||
c.setup(cCtx)
|
||||
if err := checkDuplicatedCmds(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a := args(arguments)
|
||||
set, err := c.parseFlags(&a, cCtx.shellComplete)
|
||||
cCtx.flagSet = set
|
||||
|
||||
if checkCompletions(cCtx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if c.OnUsageError != nil {
|
||||
err = c.OnUsageError(cCtx, err, !c.isRoot)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(cCtx.App.Writer, "%s %s\n\n", "Incorrect Usage:", err.Error())
|
||||
if cCtx.App.Suggest {
|
||||
if suggestion, err := c.suggestFlagFromError(err, ""); err == nil {
|
||||
fmt.Fprintf(cCtx.App.Writer, "%s", suggestion)
|
||||
}
|
||||
}
|
||||
if !c.HideHelp {
|
||||
if c.isRoot {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
} else {
|
||||
_ = ShowCommandHelp(cCtx.parentContext, c.Name)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if checkHelp(cCtx) {
|
||||
return helpCommand.Action(cCtx)
|
||||
}
|
||||
|
||||
if c.isRoot && !cCtx.App.HideVersion && checkVersion(cCtx) {
|
||||
ShowVersion(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.After != nil && !cCtx.shellComplete {
|
||||
defer func() {
|
||||
afterErr := c.After(cCtx)
|
||||
if afterErr != nil {
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
if err != nil {
|
||||
err = newMultiError(err, afterErr)
|
||||
} else {
|
||||
err = afterErr
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
cerr := cCtx.checkRequiredFlags(c.Flags)
|
||||
if cerr != nil {
|
||||
_ = helpCommand.Action(cCtx)
|
||||
return cerr
|
||||
}
|
||||
|
||||
if c.Before != nil && !cCtx.shellComplete {
|
||||
beforeErr := c.Before(cCtx)
|
||||
if beforeErr != nil {
|
||||
cCtx.App.handleExitCoder(cCtx, beforeErr)
|
||||
err = beforeErr
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = runFlagActions(cCtx, c.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var cmd *Command
|
||||
args := cCtx.Args()
|
||||
if args.Present() {
|
||||
name := args.First()
|
||||
cmd = c.Command(name)
|
||||
if cmd == nil {
|
||||
hasDefault := cCtx.App.DefaultCommand != ""
|
||||
isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames())
|
||||
|
||||
var (
|
||||
isDefaultSubcommand = false
|
||||
defaultHasSubcommands = false
|
||||
)
|
||||
|
||||
if hasDefault {
|
||||
dc := cCtx.App.Command(cCtx.App.DefaultCommand)
|
||||
defaultHasSubcommands = len(dc.Subcommands) > 0
|
||||
for _, dcSub := range dc.Subcommands {
|
||||
if checkStringSliceIncludes(name, dcSub.Names()) {
|
||||
isDefaultSubcommand = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isFlagName || (hasDefault && (defaultHasSubcommands && isDefaultSubcommand)) {
|
||||
argsWithDefault := cCtx.App.argsWithDefaultCommand(args)
|
||||
if !reflect.DeepEqual(args, argsWithDefault) {
|
||||
cmd = cCtx.App.rootCommand.Command(argsWithDefault.First())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if c.isRoot && cCtx.App.DefaultCommand != "" {
|
||||
if dc := cCtx.App.Command(cCtx.App.DefaultCommand); dc != c {
|
||||
cmd = dc
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
newcCtx := NewContext(cCtx.App, nil, cCtx)
|
||||
newcCtx.Command = cmd
|
||||
return cmd.Run(newcCtx, cCtx.Args().Slice()...)
|
||||
}
|
||||
|
||||
if c.Action == nil {
|
||||
c.Action = helpCommand.Action
|
||||
}
|
||||
|
||||
err = c.Action(cCtx)
|
||||
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Command) newFlagSet() (*flag.FlagSet, error) {
|
||||
return flagSet(c.Name, c.Flags, c.separator)
|
||||
}
|
||||
|
||||
func (c *Command) useShortOptionHandling() bool {
|
||||
return c.UseShortOptionHandling
|
||||
}
|
||||
|
||||
func (c *Command) suggestFlagFromError(err error, command string) (string, error) {
|
||||
flag, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := c.Flags
|
||||
hideHelp := c.HideHelp
|
||||
if command != "" {
|
||||
cmd := c.Command(command)
|
||||
if cmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = cmd.Flags
|
||||
hideHelp = hideHelp || cmd.HideHelp
|
||||
}
|
||||
|
||||
suggestion := SuggestFlag(flags, flag, hideHelp)
|
||||
if len(suggestion) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion) + "\n\n", nil
|
||||
}
|
||||
|
||||
func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) {
|
||||
set, err := c.newFlagSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.SkipFlagParsing {
|
||||
return set, set.Parse(append([]string{"--"}, args.Tail()...))
|
||||
}
|
||||
|
||||
err = parseIter(set, c, args.Tail(), shellComplete)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = normalizeFlags(c.Flags, set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// Names returns the names including short names and aliases.
|
||||
func (c *Command) Names() []string {
|
||||
return append([]string{c.Name}, c.Aliases...)
|
||||
}
|
||||
|
||||
// HasName returns true if Command.Name matches given name
|
||||
func (c *Command) HasName(name string) bool {
|
||||
for _, n := range c.Names() {
|
||||
if n == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// VisibleCategories returns a slice of categories and commands that are
|
||||
// Hidden=false
|
||||
func (c *Command) VisibleCategories() []CommandCategory {
|
||||
ret := []CommandCategory{}
|
||||
for _, category := range c.categories.Categories() {
|
||||
if visible := func() CommandCategory {
|
||||
if len(category.VisibleCommands()) > 0 {
|
||||
return category
|
||||
}
|
||||
return nil
|
||||
}(); visible != nil {
|
||||
ret = append(ret, visible)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (c *Command) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range c.Subcommands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, command)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if c.flagCategories == nil {
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
}
|
||||
return c.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (c *Command) VisibleFlags() []Flag {
|
||||
return visibleFlags(c.Flags)
|
||||
}
|
||||
|
||||
func (c *Command) appendFlag(fl Flag) {
|
||||
if !hasFlag(c.Flags, fl) {
|
||||
c.Flags = append(c.Flags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
func hasCommand(commands []*Command, command *Command) bool {
|
||||
for _, existing := range commands {
|
||||
if command == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkDuplicatedCmds(parent *Command) error {
|
||||
seen := make(map[string]struct{})
|
||||
for _, c := range parent.Subcommands {
|
||||
for _, name := range c.Names() {
|
||||
if _, exists := seen[name]; exists {
|
||||
return fmt.Errorf("parent command [%s] has duplicated subcommand name or alias: %s", parent.Name, name)
|
||||
}
|
||||
seen[name] = struct{}{}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
272
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
272
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
@@ -1,272 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Context is a type that is passed through to
|
||||
// each Handler action in a cli application. Context
|
||||
// can be used to retrieve context-specific args and
|
||||
// parsed command-line options.
|
||||
type Context struct {
|
||||
context.Context
|
||||
App *App
|
||||
Command *Command
|
||||
shellComplete bool
|
||||
flagSet *flag.FlagSet
|
||||
parentContext *Context
|
||||
}
|
||||
|
||||
// NewContext creates a new context. For use in when invoking an App or Command action.
|
||||
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
||||
c := &Context{App: app, flagSet: set, parentContext: parentCtx}
|
||||
if parentCtx != nil {
|
||||
c.Context = parentCtx.Context
|
||||
c.shellComplete = parentCtx.shellComplete
|
||||
if parentCtx.flagSet == nil {
|
||||
parentCtx.flagSet = &flag.FlagSet{}
|
||||
}
|
||||
}
|
||||
|
||||
c.Command = &Command{}
|
||||
|
||||
if c.Context == nil {
|
||||
c.Context = context.Background()
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// NumFlags returns the number of flags set
|
||||
func (cCtx *Context) NumFlags() int {
|
||||
return cCtx.flagSet.NFlag()
|
||||
}
|
||||
|
||||
// Set sets a context flag to a value.
|
||||
func (cCtx *Context) Set(name, value string) error {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return fs.Set(name, value)
|
||||
}
|
||||
|
||||
return fmt.Errorf("no such flag -%s", name)
|
||||
}
|
||||
|
||||
// IsSet determines if the flag was actually set
|
||||
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 {
|
||||
isSet = true
|
||||
}
|
||||
})
|
||||
if isSet {
|
||||
return true
|
||||
}
|
||||
|
||||
f := cCtx.lookupFlag(name)
|
||||
if f == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if f.IsSet() {
|
||||
return true
|
||||
}
|
||||
|
||||
// now redo flagset search on aliases
|
||||
aliases := f.Names()
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
for _, alias := range aliases {
|
||||
if f.Name == alias {
|
||||
isSet = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if isSet {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// LocalFlagNames returns a slice of flag names used in this context.
|
||||
func (cCtx *Context) LocalFlagNames() []string {
|
||||
var names []string
|
||||
cCtx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
// Check the flags which have been set via env or file
|
||||
if cCtx.Command != nil && cCtx.Command.Flags != nil {
|
||||
for _, f := range cCtx.Command.Flags {
|
||||
if f.IsSet() {
|
||||
names = append(names, f.Names()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort out the duplicates since flag could be set via multiple
|
||||
// paths
|
||||
m := map[string]struct{}{}
|
||||
var unames []string
|
||||
for _, name := range names {
|
||||
if _, ok := m[name]; !ok {
|
||||
m[name] = struct{}{}
|
||||
unames = append(unames, name)
|
||||
}
|
||||
}
|
||||
|
||||
return unames
|
||||
}
|
||||
|
||||
// FlagNames returns a slice of flag names used by the this context and all of
|
||||
// its parent contexts.
|
||||
func (cCtx *Context) FlagNames() []string {
|
||||
var names []string
|
||||
for _, pCtx := range cCtx.Lineage() {
|
||||
names = append(names, pCtx.LocalFlagNames()...)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// Lineage returns *this* context and all of its ancestor contexts in order from
|
||||
// child to parent
|
||||
func (cCtx *Context) Lineage() []*Context {
|
||||
var lineage []*Context
|
||||
|
||||
for cur := cCtx; cur != nil; cur = cur.parentContext {
|
||||
lineage = append(lineage, cur)
|
||||
}
|
||||
|
||||
return lineage
|
||||
}
|
||||
|
||||
// Count returns the num of occurrences of this flag
|
||||
func (cCtx *Context) Count(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
if cf, ok := fs.Lookup(name).Value.(Countable); ok {
|
||||
return cf.Count()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Value returns the value of the flag corresponding to `name`
|
||||
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 (cCtx *Context) Args() Args {
|
||||
ret := args(cCtx.flagSet.Args())
|
||||
return &ret
|
||||
}
|
||||
|
||||
// NArg returns the number of the command line arguments.
|
||||
func (cCtx *Context) NArg() int {
|
||||
return cCtx.Args().Len()
|
||||
}
|
||||
|
||||
func (cCtx *Context) lookupFlag(name string) Flag {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.Command == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range c.Command.Flags {
|
||||
for _, n := range f.Names() {
|
||||
if n == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cCtx.App != nil {
|
||||
for _, f := range cCtx.App.Flags {
|
||||
for _, n := range f.Names() {
|
||||
if n == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.flagSet == nil {
|
||||
continue
|
||||
}
|
||||
if f := c.flagSet.Lookup(name); f != nil {
|
||||
return c.flagSet
|
||||
}
|
||||
}
|
||||
cCtx.onInvalidFlag(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
|
||||
var missingFlags []string
|
||||
for _, f := range flags {
|
||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
||||
var flagPresent bool
|
||||
var flagName string
|
||||
|
||||
flagNames := f.Names()
|
||||
flagName = flagNames[0]
|
||||
|
||||
for _, key := range flagNames {
|
||||
if cCtx.IsSet(strings.TrimSpace(key)) {
|
||||
flagPresent = true
|
||||
}
|
||||
}
|
||||
|
||||
if !flagPresent && flagName != "" {
|
||||
missingFlags = append(missingFlags, flagName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingFlags) != 0 {
|
||||
return &errRequiredFlags{missingFlags: missingFlags}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) onInvalidFlag(name string) {
|
||||
for cCtx != nil {
|
||||
if cCtx.App != nil && cCtx.App.InvalidFlagAccessHandler != nil {
|
||||
cCtx.App.InvalidFlagAccessHandler(cCtx, name)
|
||||
break
|
||||
}
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
}
|
||||
|
||||
func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
|
||||
return func(f *flag.Flag) {
|
||||
nameParts := strings.Split(f.Name, ",")
|
||||
name := strings.TrimSpace(nameParts[0])
|
||||
|
||||
for _, part := range nameParts {
|
||||
part = strings.TrimSpace(part)
|
||||
if len(part) > len(name) {
|
||||
name = part
|
||||
}
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
*names = append(*names, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
203
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
203
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
@@ -1,203 +0,0 @@
|
||||
//go:build !urfave_cli_no_docs
|
||||
// +build !urfave_cli_no_docs
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/cpuguy83/go-md2man/v2/md2man"
|
||||
)
|
||||
|
||||
// ToMarkdown creates a markdown string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMarkdown() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w, 0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string with section number for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToManWithSection(sectionNumber int) (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w, sectionNumber); err != nil {
|
||||
return "", err
|
||||
}
|
||||
man := md2man.Render(w.Bytes())
|
||||
return string(man), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMan() (string, error) {
|
||||
man, err := a.ToManWithSection(8)
|
||||
return man, err
|
||||
}
|
||||
|
||||
type cliTemplate struct {
|
||||
App *App
|
||||
SectionNum int
|
||||
Commands []string
|
||||
GlobalArgs []string
|
||||
SynopsisArgs []string
|
||||
}
|
||||
|
||||
func (a *App) writeDocTemplate(w io.Writer, sectionNum int) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.ExecuteTemplate(w, name, &cliTemplate{
|
||||
App: a,
|
||||
SectionNum: sectionNum,
|
||||
Commands: prepareCommands(a.Commands, 0),
|
||||
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
||||
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
||||
})
|
||||
}
|
||||
|
||||
func prepareCommands(commands []*Command, level int) []string {
|
||||
var coms []string
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
usageText := prepareUsageText(command)
|
||||
|
||||
usage := prepareUsage(command, usageText)
|
||||
|
||||
prepared := fmt.Sprintf("%s %s\n\n%s%s",
|
||||
strings.Repeat("#", level+2),
|
||||
strings.Join(command.Names(), ", "),
|
||||
usage,
|
||||
usageText,
|
||||
)
|
||||
|
||||
flags := prepareArgsWithValues(command.VisibleFlags())
|
||||
if len(flags) > 0 {
|
||||
prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n"))
|
||||
}
|
||||
|
||||
coms = append(coms, prepared)
|
||||
|
||||
// recursively iterate subcommands
|
||||
if len(command.Subcommands) > 0 {
|
||||
coms = append(
|
||||
coms,
|
||||
prepareCommands(command.Subcommands, level+1)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return coms
|
||||
}
|
||||
|
||||
func prepareArgsWithValues(flags []Flag) []string {
|
||||
return prepareFlags(flags, ", ", "**", "**", `""`, true)
|
||||
}
|
||||
|
||||
func prepareArgsSynopsis(flags []Flag) []string {
|
||||
return prepareFlags(flags, "|", "[", "]", "[value]", false)
|
||||
}
|
||||
|
||||
func prepareFlags(
|
||||
flags []Flag,
|
||||
sep, opener, closer, value string,
|
||||
addDetails bool,
|
||||
) []string {
|
||||
args := []string{}
|
||||
for _, f := range flags {
|
||||
flag, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
modifiedArg := opener
|
||||
|
||||
for _, s := range flag.Names() {
|
||||
trimmed := strings.TrimSpace(s)
|
||||
if len(modifiedArg) > len(opener) {
|
||||
modifiedArg += sep
|
||||
}
|
||||
if len(trimmed) > 1 {
|
||||
modifiedArg += fmt.Sprintf("--%s", trimmed)
|
||||
} else {
|
||||
modifiedArg += fmt.Sprintf("-%s", trimmed)
|
||||
}
|
||||
}
|
||||
modifiedArg += closer
|
||||
if flag.TakesValue() {
|
||||
modifiedArg += fmt.Sprintf("=%s", value)
|
||||
}
|
||||
|
||||
if addDetails {
|
||||
modifiedArg += flagDetails(flag)
|
||||
}
|
||||
|
||||
args = append(args, modifiedArg+"\n")
|
||||
|
||||
}
|
||||
sort.Strings(args)
|
||||
return args
|
||||
}
|
||||
|
||||
// flagDetails returns a string containing the flags metadata
|
||||
func flagDetails(flag DocGenerationFlag) string {
|
||||
description := flag.GetUsage()
|
||||
if flag.TakesValue() {
|
||||
defaultText := flag.GetDefaultText()
|
||||
if defaultText == "" {
|
||||
defaultText = flag.GetValue()
|
||||
}
|
||||
if defaultText != "" {
|
||||
description += " (default: " + defaultText + ")"
|
||||
}
|
||||
}
|
||||
return ": " + description
|
||||
}
|
||||
|
||||
func prepareUsageText(command *Command) string {
|
||||
if command.UsageText == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Remove leading and trailing newlines
|
||||
preparedUsageText := strings.Trim(command.UsageText, "\n")
|
||||
|
||||
var usageText string
|
||||
if strings.Contains(preparedUsageText, "\n") {
|
||||
// Format multi-line string as a code block using the 4 space schema to allow for embedded markdown such
|
||||
// that it will not break the continuous code block.
|
||||
for _, ln := range strings.Split(preparedUsageText, "\n") {
|
||||
usageText += fmt.Sprintf(" %s\n", ln)
|
||||
}
|
||||
} else {
|
||||
// Style a single line as a note
|
||||
usageText = fmt.Sprintf(">%s\n", preparedUsageText)
|
||||
}
|
||||
|
||||
return usageText
|
||||
}
|
||||
|
||||
func prepareUsage(command *Command, usageText string) string {
|
||||
if command.Usage == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
usage := command.Usage + "\n"
|
||||
// Add a newline to the Usage IFF there is a UsageText
|
||||
if usageText != "" {
|
||||
usage += "\n"
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
196
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
196
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
@@ -1,196 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// ToFishCompletion creates a fish completion string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToFishCompletion() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeFishCompletionTemplate(&w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
type fishCompletionTemplate struct {
|
||||
App *App
|
||||
Completions []string
|
||||
AllCommands []string
|
||||
}
|
||||
|
||||
func (a *App) writeFishCompletionTemplate(w io.Writer) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(FishCompletionTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allCommands := []string{}
|
||||
|
||||
// Add global flags
|
||||
completions := a.prepareFishFlags(a.VisibleFlags(), allCommands)
|
||||
|
||||
// Add help flag
|
||||
if !a.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{HelpFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add version flag
|
||||
if !a.HideVersion {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{VersionFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add commands and their flags
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishCommands(a.VisibleCommands(), &allCommands, []string{})...,
|
||||
)
|
||||
|
||||
return t.ExecuteTemplate(w, name, &fishCompletionTemplate{
|
||||
App: a,
|
||||
Completions: completions,
|
||||
AllCommands: allCommands,
|
||||
})
|
||||
}
|
||||
|
||||
func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
var completion strings.Builder
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -r -c %s -n '%s' -a '%s'",
|
||||
a.Name,
|
||||
a.fishSubcommandHelper(previousCommands),
|
||||
strings.Join(command.Names(), " "),
|
||||
))
|
||||
|
||||
if command.Usage != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(command.Usage)))
|
||||
}
|
||||
|
||||
if !command.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{HelpFlag}, command.Names())...,
|
||||
)
|
||||
}
|
||||
|
||||
*allCommands = append(*allCommands, command.Names()...)
|
||||
completions = append(completions, completion.String())
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags(command.VisibleFlags(), command.Names())...,
|
||||
)
|
||||
|
||||
// recursively iterate subcommands
|
||||
if len(command.Subcommands) > 0 {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishCommands(
|
||||
command.Subcommands, allCommands, command.Names(),
|
||||
)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, f := range flags {
|
||||
flag, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
completion := &strings.Builder{}
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -c %s -n '%s'",
|
||||
a.Name,
|
||||
a.fishSubcommandHelper(previousCommands),
|
||||
))
|
||||
|
||||
fishAddFileFlag(f, completion)
|
||||
|
||||
for idx, opt := range flag.Names() {
|
||||
if idx == 0 {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -l %s", strings.TrimSpace(opt),
|
||||
))
|
||||
} else {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -s %s", strings.TrimSpace(opt),
|
||||
))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if flag.TakesValue() {
|
||||
completion.WriteString(" -r")
|
||||
}
|
||||
|
||||
if flag.GetUsage() != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(flag.GetUsage())))
|
||||
}
|
||||
|
||||
completions = append(completions, completion.String())
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||
switch f := flag.(type) {
|
||||
case *GenericFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringSliceFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *PathFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
}
|
||||
completion.WriteString(" -f")
|
||||
}
|
||||
|
||||
func (a *App) fishSubcommandHelper(allCommands []string) string {
|
||||
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", a.Name)
|
||||
if len(allCommands) > 0 {
|
||||
fishHelper = fmt.Sprintf(
|
||||
"__fish_seen_subcommand_from %s",
|
||||
strings.Join(allCommands, " "),
|
||||
)
|
||||
}
|
||||
return fishHelper
|
||||
|
||||
}
|
||||
|
||||
func escapeSingleQuotes(input string) string {
|
||||
return strings.Replace(input, `'`, `\'`, -1)
|
||||
}
|
||||
131
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
131
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
@@ -1,131 +0,0 @@
|
||||
# NOTE: this file is used by the tool defined in
|
||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||
# `Spec` type that maps to this file structure.
|
||||
flag_types:
|
||||
bool:
|
||||
struct_fields:
|
||||
- name: Count
|
||||
type: int
|
||||
pointer: true
|
||||
- name: DisableDefaultText
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, bool) error"
|
||||
float64:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, float64) error"
|
||||
Float64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []float64) error"
|
||||
int:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int) error"
|
||||
IntSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []int) error"
|
||||
int64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int64) error"
|
||||
Int64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []int64) error"
|
||||
uint:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint) error"
|
||||
UintSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []uint) error"
|
||||
uint64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint64) error"
|
||||
Uint64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []uint64) error"
|
||||
string:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, string) error"
|
||||
StringSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, []string) error"
|
||||
- name: KeepSpace
|
||||
type: bool
|
||||
time.Duration:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, time.Duration) error"
|
||||
Timestamp:
|
||||
value_pointer: true
|
||||
struct_fields:
|
||||
- name: Layout
|
||||
type: string
|
||||
- name: Timezone
|
||||
type: "*time.Location"
|
||||
- name: Action
|
||||
type: "func(*Context, *time.Time) error"
|
||||
Generic:
|
||||
no_destination_pointer: true
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, interface{}) error"
|
||||
Path:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, Path) error"
|
||||
419
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
419
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
@@ -1,419 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const defaultPlaceholder = "value"
|
||||
|
||||
const (
|
||||
defaultSliceFlagSeparator = ","
|
||||
disableSliceFlagSeparator = false
|
||||
)
|
||||
|
||||
var (
|
||||
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||
|
||||
commaWhitespace = regexp.MustCompile("[, ]+.*")
|
||||
)
|
||||
|
||||
// BashCompletionFlag enables bash-completion for all commands and subcommands
|
||||
var BashCompletionFlag Flag = &BoolFlag{
|
||||
Name: "generate-bash-completion",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
// VersionFlag prints the version for the application
|
||||
var VersionFlag Flag = &BoolFlag{
|
||||
Name: "version",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print the version",
|
||||
DisableDefaultText: true,
|
||||
}
|
||||
|
||||
// HelpFlag prints the help for all commands and subcommands.
|
||||
// Set to nil to disable the flag. The subcommand
|
||||
// will still be added unless HideHelp or HideHelpCommand is set to true.
|
||||
var HelpFlag Flag = &BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
Usage: "show help",
|
||||
DisableDefaultText: true,
|
||||
}
|
||||
|
||||
// FlagStringer converts a flag definition to a string. This is used by help
|
||||
// to display a flag.
|
||||
var FlagStringer FlagStringFunc = stringifyFlag
|
||||
|
||||
// Serializer is used to circumvent the limitations of flag.FlagSet.Set
|
||||
type Serializer interface {
|
||||
Serialize() string
|
||||
}
|
||||
|
||||
// FlagNamePrefixer converts a full flag name and its placeholder into the help
|
||||
// message flag prefix. This is used by the default FlagStringer.
|
||||
var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames
|
||||
|
||||
// FlagEnvHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagEnvHinter FlagEnvHintFunc = withEnvHint
|
||||
|
||||
// FlagFileHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagFileHinter FlagFileHintFunc = withFileHint
|
||||
|
||||
// FlagsByName is a slice of Flag.
|
||||
type FlagsByName []Flag
|
||||
|
||||
func (f FlagsByName) Len() int {
|
||||
return len(f)
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
if len(f[j].Names()) == 0 {
|
||||
return false
|
||||
} else if len(f[i].Names()) == 0 {
|
||||
return true
|
||||
}
|
||||
return lexicographicLess(f[i].Names()[0], f[j].Names()[0])
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
f[i], f[j] = f[j], f[i]
|
||||
}
|
||||
|
||||
// ActionableFlag is an interface that wraps Flag interface and RunAction operation.
|
||||
type ActionableFlag interface {
|
||||
Flag
|
||||
RunAction(*Context) error
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
type Flag interface {
|
||||
fmt.Stringer
|
||||
// Apply Flag settings to the given flag set
|
||||
Apply(*flag.FlagSet) error
|
||||
Names() []string
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// RequiredFlag is an interface that allows us to mark flags as required
|
||||
// it allows flags required flags to be backwards compatible with the Flag interface
|
||||
type RequiredFlag interface {
|
||||
Flag
|
||||
|
||||
IsRequired() bool
|
||||
}
|
||||
|
||||
// DocGenerationFlag is an interface that allows documentation generation for the flag
|
||||
type DocGenerationFlag interface {
|
||||
Flag
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
TakesValue() bool
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
GetUsage() string
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||
type DocGenerationSliceFlag interface {
|
||||
DocGenerationFlag
|
||||
|
||||
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||
IsSliceFlag() bool
|
||||
}
|
||||
|
||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||
type VisibleFlag interface {
|
||||
Flag
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
// CategorizableFlag is an interface that allows us to potentially
|
||||
// use a flag in a categorized representation.
|
||||
type CategorizableFlag interface {
|
||||
VisibleFlag
|
||||
|
||||
GetCategory() string
|
||||
}
|
||||
|
||||
// Countable is an interface to enable detection of flag values which support
|
||||
// repetitive flags
|
||||
type Countable interface {
|
||||
Count() int
|
||||
}
|
||||
|
||||
func flagSet(name string, flags []Flag, spec separatorSpec) (*flag.FlagSet, error) {
|
||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||
|
||||
for _, f := range flags {
|
||||
if c, ok := f.(customizedSeparator); ok {
|
||||
c.WithSeparatorSpec(spec)
|
||||
}
|
||||
if err := f.Apply(set); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
set.SetOutput(io.Discard)
|
||||
return set, nil
|
||||
}
|
||||
|
||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||
switch ff.Value.(type) {
|
||||
case Serializer:
|
||||
_ = set.Set(name, ff.Value.(Serializer).Serialize())
|
||||
default:
|
||||
_ = set.Set(name, ff.Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
||||
visited := make(map[string]bool)
|
||||
set.Visit(func(f *flag.Flag) {
|
||||
visited[f.Name] = true
|
||||
})
|
||||
for _, f := range flags {
|
||||
parts := f.Names()
|
||||
if len(parts) == 1 {
|
||||
continue
|
||||
}
|
||||
var ff *flag.Flag
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if visited[name] {
|
||||
if ff != nil {
|
||||
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
||||
}
|
||||
ff = set.Lookup(name)
|
||||
}
|
||||
}
|
||||
if ff == nil {
|
||||
continue
|
||||
}
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if !visited[name] {
|
||||
copyFlag(name, ff, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
|
||||
visible = append(visible, f)
|
||||
}
|
||||
}
|
||||
return visible
|
||||
}
|
||||
|
||||
func prefixFor(name string) (prefix string) {
|
||||
if len(name) == 1 {
|
||||
prefix = "-"
|
||||
} else {
|
||||
prefix = "--"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the placeholder, if any, and the unquoted usage string.
|
||||
func unquoteUsage(usage string) (string, string) {
|
||||
for i := 0; i < len(usage); i++ {
|
||||
if usage[i] == '`' {
|
||||
for j := i + 1; j < len(usage); j++ {
|
||||
if usage[j] == '`' {
|
||||
name := usage[i+1 : j]
|
||||
usage = usage[:i] + name + usage[j+1:]
|
||||
return name, usage
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return "", usage
|
||||
}
|
||||
|
||||
func prefixedNames(names []string, placeholder string) string {
|
||||
var prefixed string
|
||||
for i, name := range names {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
prefixed += prefixFor(name) + name
|
||||
if placeholder != "" {
|
||||
prefixed += " " + placeholder
|
||||
}
|
||||
if i < len(names)-1 {
|
||||
prefixed += ", "
|
||||
}
|
||||
}
|
||||
return prefixed
|
||||
}
|
||||
|
||||
func envFormat(envVars []string, prefix, sep, suffix string) string {
|
||||
if len(envVars) > 0 {
|
||||
return fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultEnvFormat(envVars []string) string {
|
||||
return envFormat(envVars, "$", ", $", "")
|
||||
}
|
||||
|
||||
func withEnvHint(envVars []string, str string) string {
|
||||
envText := ""
|
||||
if runtime.GOOS != "windows" || os.Getenv("PSHOME") != "" {
|
||||
envText = defaultEnvFormat(envVars)
|
||||
} else {
|
||||
envText = envFormat(envVars, "%", "%, %", "%")
|
||||
}
|
||||
return str + envText
|
||||
}
|
||||
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
// v1 -> v2 migration warning zone:
|
||||
// Strip off anything after the first found comma or space, which
|
||||
// *hopefully* makes it a tiny bit more obvious that unexpected behavior is
|
||||
// caused by using the v1 form of stringly typed "Name".
|
||||
ret = append(ret, commaWhitespace.ReplaceAllString(part, ""))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func withFileHint(filePath, str string) string {
|
||||
fileText := ""
|
||||
if filePath != "" {
|
||||
fileText = fmt.Sprintf(" [%s]", filePath)
|
||||
}
|
||||
return str + fileText
|
||||
}
|
||||
|
||||
func formatDefault(format string) string {
|
||||
return " (default: " + format + ")"
|
||||
}
|
||||
|
||||
func stringifyFlag(f Flag) string {
|
||||
// enforce DocGeneration interface on flags to avoid reflection
|
||||
df, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||
needsPlaceholder := df.TakesValue()
|
||||
|
||||
if needsPlaceholder && placeholder == "" {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
|
||||
defaultValueString := ""
|
||||
|
||||
// set default text for all flags except bool flags
|
||||
// for bool flags display default text if DisableDefaultText is not
|
||||
// set
|
||||
if bf, ok := f.(*BoolFlag); !ok || !bf.DisableDefaultText {
|
||||
if s := df.GetDefaultText(); s != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||
}
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||
|
||||
pn := prefixedNames(df.Names(), placeholder)
|
||||
sliceFlag, ok := f.(DocGenerationSliceFlag)
|
||||
if ok && sliceFlag.IsSliceFlag() {
|
||||
pn = pn + " [ " + pn + " ]"
|
||||
}
|
||||
|
||||
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||
}
|
||||
|
||||
func hasFlag(flags []Flag, fl Flag) bool {
|
||||
for _, existing := range flags {
|
||||
if fl == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 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 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 := os.ReadFile(fileVar); err == nil {
|
||||
return string(data), fmt.Sprintf("file %q", filePath), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
type customizedSeparator interface {
|
||||
WithSeparatorSpec(separatorSpec)
|
||||
}
|
||||
|
||||
type separatorSpec struct {
|
||||
sep string
|
||||
disabled bool
|
||||
customized bool
|
||||
}
|
||||
|
||||
func (s separatorSpec) flagSplitMultiValues(val string) []string {
|
||||
var (
|
||||
disabled bool = s.disabled
|
||||
sep string = s.sep
|
||||
)
|
||||
if !s.customized {
|
||||
disabled = disableSliceFlagSeparator
|
||||
sep = defaultSliceFlagSeparator
|
||||
}
|
||||
if disabled {
|
||||
return []string{val}
|
||||
}
|
||||
|
||||
return strings.Split(val, sep)
|
||||
}
|
||||
178
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
178
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
@@ -1,178 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// boolValue needs to implement the boolFlag internal interface in flag
|
||||
// to be able to capture bool fields and values
|
||||
//
|
||||
// type boolFlag interface {
|
||||
// Value
|
||||
// IsBoolFlag() bool
|
||||
// }
|
||||
type boolValue struct {
|
||||
destination *bool
|
||||
count *int
|
||||
}
|
||||
|
||||
func newBoolValue(val bool, p *bool, count *int) *boolValue {
|
||||
*p = val
|
||||
return &boolValue{
|
||||
destination: p,
|
||||
count: count,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
err = errors.New("parse error")
|
||||
return err
|
||||
}
|
||||
*b.destination = v
|
||||
if b.count != nil {
|
||||
*b.count = *b.count + 1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *boolValue) Get() interface{} { return *b.destination }
|
||||
|
||||
func (b *boolValue) String() string {
|
||||
if b.destination != nil {
|
||||
return strconv.FormatBool(*b.destination)
|
||||
}
|
||||
return strconv.FormatBool(false)
|
||||
}
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func (b *boolValue) Count() int {
|
||||
if b.count != nil && *b.count > 0 {
|
||||
return *b.count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *BoolFlag) TakesValue() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *BoolFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%v", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *BoolFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *BoolFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Bool(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
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 from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valBool
|
||||
} else {
|
||||
// empty value implies that the env is defined but set to empty string, we have to assume that this is
|
||||
// what the user wants. If user doesnt want this then the env needs to be deleted or the flag removed from
|
||||
// file
|
||||
f.Value = false
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
count := f.Count
|
||||
dest := f.Destination
|
||||
|
||||
if count == nil {
|
||||
count = new(int)
|
||||
}
|
||||
|
||||
// since count will be incremented for each alias as well
|
||||
// subtract number of aliases from overall count
|
||||
*count -= len(f.Aliases)
|
||||
|
||||
if dest == nil {
|
||||
dest = new(bool)
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
value := newBoolValue(f.Value, dest, count)
|
||||
set.Var(value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s 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 (cCtx *Context) Bool(name string) bool {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupBool(name, fs)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseBool(f.Value.String())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return false
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
108
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *DurationFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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()
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *DurationFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return f.defaultValue.String()
|
||||
}
|
||||
return f.Value.String()
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
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 from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valDuration
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.DurationVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Duration(name, f.Value, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *DurationFlag) Get(ctx *Context) time.Duration {
|
||||
return ctx.Duration(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *DurationFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Duration(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Duration looks up the value of a local DurationFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Duration(name string) time.Duration {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupDuration(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := time.ParseDuration(f.Value.String())
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
107
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
107
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
@@ -1,107 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Float64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Float64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%v", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
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 from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valFloat
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Float64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Float64(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64Flag) Get(ctx *Context) float64 {
|
||||
return ctx.Float64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64 looks up the value of a local Float64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Float64(name string) float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
216
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
216
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
@@ -1,216 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Float64Slice wraps []float64 to satisfy flag.Value
|
||||
type Float64Slice struct {
|
||||
slice []float64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewFloat64Slice makes a *Float64Slice with default values
|
||||
func NewFloat64Slice(defaults ...float64) *Float64Slice {
|
||||
return &Float64Slice{slice: append([]float64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (f *Float64Slice) clone() *Float64Slice {
|
||||
n := &Float64Slice{
|
||||
slice: make([]float64, len(f.slice)),
|
||||
hasBeenSet: f.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, f.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
func (f *Float64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into a float64 and appends it to the list of values
|
||||
func (f *Float64Slice) Set(value string) error {
|
||||
if !f.hasBeenSet {
|
||||
f.slice = []float64{}
|
||||
f.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &f.slice)
|
||||
f.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range f.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.slice = append(f.slice, tmp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Float64Slice) String() string {
|
||||
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
|
||||
func (f *Float64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(f.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of float64s set by this flag
|
||||
func (f *Float64Slice) Value() []float64 {
|
||||
return f.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of float64s set by this flag
|
||||
func (f *Float64Slice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *Float64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Float64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
for _, s := range f.separator.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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Float64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
|
||||
return ctx.Float64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Float64Slice(name string) []float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Float64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
131
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
131
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
@@ -1,131 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Generic is a generic parseable type identified by a specific flag
|
||||
type Generic interface {
|
||||
Set(value string) error
|
||||
String() string
|
||||
}
|
||||
|
||||
type stringGeneric struct {
|
||||
value string
|
||||
}
|
||||
|
||||
func (s *stringGeneric) Set(value string) error {
|
||||
s.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringGeneric) String() string {
|
||||
return s.value
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *GenericFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *GenericFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val != nil {
|
||||
return val.String()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
if f.Value != nil {
|
||||
f.defaultValue = &stringGeneric{value: f.Value.String()}
|
||||
f.defaultValueSet = true
|
||||
}
|
||||
|
||||
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 from %s as value for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *GenericFlag) Get(ctx *Context) interface{} {
|
||||
return ctx.Generic(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *GenericFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Generic(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Generic(name string) interface{} {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupGeneric(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
109
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
109
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *IntFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
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)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.IntVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Int(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntFlag) Get(ctx *Context) int {
|
||||
return ctx.Int(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int looks up the value of a local IntFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupInt(name string, set *flag.FlagSet) int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(parsed)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
108
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Int64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Int64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Int64(name, f.Value, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64Flag) Get(ctx *Context) int64 {
|
||||
return ctx.Int64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64 looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int64(name string) int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
215
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
215
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
@@ -1,215 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Int64Slice wraps []int64 to satisfy flag.Value
|
||||
type Int64Slice struct {
|
||||
slice []int64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewInt64Slice makes an *Int64Slice with default values
|
||||
func NewInt64Slice(defaults ...int64) *Int64Slice {
|
||||
return &Int64Slice{slice: append([]int64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Int64Slice) clone() *Int64Slice {
|
||||
n := &Int64Slice{
|
||||
slice: make([]int64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
func (i *Int64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Int64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int64{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Int64Slice) String() string {
|
||||
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
|
||||
func (i *Int64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *Int64Slice) Value() []int64 {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *Int64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Int64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Int64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
|
||||
return ctx.Int64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Int64Slice(name string) []int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Int64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
226
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
226
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
@@ -1,226 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IntSlice wraps []int to satisfy flag.Value
|
||||
type IntSlice struct {
|
||||
slice []int
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewIntSlice makes an *IntSlice with default values
|
||||
func NewIntSlice(defaults ...int) *IntSlice {
|
||||
return &IntSlice{slice: append([]int{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *IntSlice) clone() *IntSlice {
|
||||
n := &IntSlice{
|
||||
slice: make([]int, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *IntSlice) SetInt(value int) {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, value)
|
||||
}
|
||||
|
||||
func (i *IntSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *IntSlice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
func (i *IntSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *IntSlice) Value() []int {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *IntSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.Itoa(i))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *IntSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *IntSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntSliceFlag) Get(ctx *Context) []int {
|
||||
return ctx.IntSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.IntSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) IntSlice(name string) []int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupIntSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*IntSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
102
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
@@ -1,102 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Path = string
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *PathFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *PathFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.String(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *PathFlag) Get(ctx *Context) string {
|
||||
return ctx.Path(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *PathFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Path(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Path looks up the value of a local PathFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) Path(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupPath(name, fs)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func lookupPath(name string, set *flag.FlagSet) string {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
100
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
100
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
@@ -1,100 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *StringFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.String(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringFlag) Get(ctx *Context) string {
|
||||
return ctx.String(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.String(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String looks up the value of a local StringFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) String(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupString(name, fs)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func lookupString(name string, set *flag.FlagSet) string {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
216
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
216
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
@@ -1,216 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StringSlice wraps a []string to satisfy flag.Value
|
||||
type StringSlice struct {
|
||||
slice []string
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
keepSpace bool
|
||||
}
|
||||
|
||||
// NewStringSlice creates a *StringSlice with default values
|
||||
func NewStringSlice(defaults ...string) *StringSlice {
|
||||
return &StringSlice{slice: append([]string{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (s *StringSlice) clone() *StringSlice {
|
||||
n := &StringSlice{
|
||||
slice: make([]string, len(s.slice)),
|
||||
hasBeenSet: s.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, s.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set appends the string value to the list of values
|
||||
func (s *StringSlice) Set(value string) error {
|
||||
if !s.hasBeenSet {
|
||||
s.slice = []string{}
|
||||
s.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &s.slice)
|
||||
s.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, t := range s.separator.flagSplitMultiValues(value) {
|
||||
if !s.keepSpace {
|
||||
t = strings.TrimSpace(t)
|
||||
}
|
||||
s.slice = append(s.slice, t)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StringSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
s.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (s *StringSlice) String() string {
|
||||
return fmt.Sprintf("%s", s.slice)
|
||||
}
|
||||
|
||||
// Serialize allows StringSlice to fulfill Serializer
|
||||
func (s *StringSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(s.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of strings set by this flag
|
||||
func (s *StringSlice) Value() []string {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of strings set by this flag
|
||||
func (s *StringSlice) Get() interface{} {
|
||||
return *s
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, s := range f.Value.Value() {
|
||||
if len(s) > 0 {
|
||||
defaultVals = append(defaultVals, strconv.Quote(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *StringSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
|
||||
setValue.keepSpace = f.KeepSpace
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if !f.KeepSpace {
|
||||
s = strings.TrimSpace(s)
|
||||
}
|
||||
if err := setValue.Set(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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *StringSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringSliceFlag) Get(ctx *Context) []string {
|
||||
return ctx.StringSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.StringSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) StringSlice(name string) []string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupStringSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*StringSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
205
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
205
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
@@ -1,205 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp wrap to satisfy golang's flag interface.
|
||||
type Timestamp struct {
|
||||
timestamp *time.Time
|
||||
hasBeenSet bool
|
||||
layout string
|
||||
location *time.Location
|
||||
}
|
||||
|
||||
// Timestamp constructor
|
||||
func NewTimestamp(timestamp time.Time) *Timestamp {
|
||||
return &Timestamp{timestamp: ×tamp}
|
||||
}
|
||||
|
||||
// Set the timestamp value directly
|
||||
func (t *Timestamp) SetTimestamp(value time.Time) {
|
||||
if !t.hasBeenSet {
|
||||
t.timestamp = &value
|
||||
t.hasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
// Set the timestamp string layout for future parsing
|
||||
func (t *Timestamp) SetLayout(layout string) {
|
||||
t.layout = layout
|
||||
}
|
||||
|
||||
// Set perceived timezone of the to-be parsed time string
|
||||
func (t *Timestamp) SetLocation(loc *time.Location) {
|
||||
t.location = loc
|
||||
}
|
||||
|
||||
// Parses the string value to timestamp
|
||||
func (t *Timestamp) Set(value string) error {
|
||||
var timestamp time.Time
|
||||
var err error
|
||||
|
||||
if t.location != nil {
|
||||
timestamp, err = time.ParseInLocation(t.layout, value, t.location)
|
||||
} else {
|
||||
timestamp, err = time.Parse(t.layout, value)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.timestamp = ×tamp
|
||||
t.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (t *Timestamp) String() string {
|
||||
return fmt.Sprintf("%#v", t.timestamp)
|
||||
}
|
||||
|
||||
// Value returns the timestamp value stored in the flag
|
||||
func (t *Timestamp) Value() *time.Time {
|
||||
return t.timestamp
|
||||
}
|
||||
|
||||
// Get returns the flag structure
|
||||
func (t *Timestamp) Get() interface{} {
|
||||
return *t
|
||||
}
|
||||
|
||||
// clone timestamp
|
||||
func (t *Timestamp) clone() *Timestamp {
|
||||
tc := &Timestamp{
|
||||
timestamp: nil,
|
||||
hasBeenSet: t.hasBeenSet,
|
||||
layout: t.layout,
|
||||
location: nil,
|
||||
}
|
||||
if t.timestamp != nil {
|
||||
tts := *t.timestamp
|
||||
tc.timestamp = &tts
|
||||
}
|
||||
if t.location != nil {
|
||||
loc := *t.location
|
||||
tc.location = &loc
|
||||
}
|
||||
return tc
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *TimestampFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
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 {
|
||||
if f.Value != nil && f.Value.timestamp != nil {
|
||||
return f.Value.timestamp.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *TimestampFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val != nil && val.timestamp != nil {
|
||||
return val.timestamp.String()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// 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
|
||||
func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||
if f.Layout == "" {
|
||||
return fmt.Errorf("timestamp Layout is required")
|
||||
}
|
||||
if f.Value == nil {
|
||||
f.Value = &Timestamp{}
|
||||
}
|
||||
f.Value.SetLayout(f.Layout)
|
||||
f.Value.SetLocation(f.Timezone)
|
||||
|
||||
f.defaultValue = f.Value.clone()
|
||||
f.defaultValueSet = true
|
||||
|
||||
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 from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
if f.Destination != nil {
|
||||
*f.Destination = *f.Value
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *TimestampFlag) Get(ctx *Context) *time.Time {
|
||||
return ctx.Timestamp(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *TimestampFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Timestamp(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (cCtx *Context) Timestamp(name string) *time.Time {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupTimestamp(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fetches the timestamp value from the local timestampWrap
|
||||
func lookupTimestamp(name string, set *flag.FlagSet) *time.Time {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
return (f.Value.(*Timestamp)).Value()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
108
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *UintFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
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)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.UintVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Uint(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *UintFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
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
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s 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 (cCtx *Context) Uint(name string) uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupUint(name string, set *flag.FlagSet) uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint(parsed)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
108
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
@@ -1,108 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Uint64Flag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Uint64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Uint64(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Uint64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
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
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s 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 (cCtx *Context) Uint64(name string) uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
219
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
219
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
@@ -1,219 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Uint64Slice wraps []int64 to satisfy flag.Value
|
||||
type Uint64Slice struct {
|
||||
slice []uint64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUint64Slice makes an *Uint64Slice with default values
|
||||
func NewUint64Slice(defaults ...uint64) *Uint64Slice {
|
||||
return &Uint64Slice{slice: append([]uint64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Uint64Slice) clone() *Uint64Slice {
|
||||
n := &Uint64Slice{
|
||||
slice: make([]uint64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Uint64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint64{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Uint64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Uint64Slice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint64, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint64%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows Uint64Slice to fulfill Serializer
|
||||
func (i *Uint64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Value() []uint64 {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Uint64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Uint64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Uint64SliceFlag) 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 *Uint64SliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Uint64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Uint64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Uint64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Uint64Slice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Uint64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
|
||||
return ctx.Uint64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Uint64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Uint64Slice(name string) []uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUint64Slice(name string, set *flag.FlagSet) []uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Uint64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
230
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
230
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
@@ -1,230 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// UintSlice wraps []int to satisfy flag.Value
|
||||
type UintSlice struct {
|
||||
slice []uint
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUintSlice makes an *UintSlice with default values
|
||||
func NewUintSlice(defaults ...uint) *UintSlice {
|
||||
return &UintSlice{slice: append([]uint{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *UintSlice) clone() *UintSlice {
|
||||
n := &UintSlice{
|
||||
slice: make([]uint, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *UintSlice) SetUint(value uint) {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, value)
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *UintSlice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, uint(tmp))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *UintSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *UintSlice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows UintSlice to fulfill Serializer
|
||||
func (i *UintSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Value() []uint {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *UintSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *UintSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *UintSliceFlag) 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 *UintSliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *UintSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *UintSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *UintSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(UintSlice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *UintSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintSliceFlag) Get(ctx *Context) []uint {
|
||||
return ctx.UintSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *UintSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.UintSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) UintSlice(name string) []uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUintSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUintSlice(name string, set *flag.FlagSet) []uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*UintSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
2727
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
2727
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
File diff suppressed because it is too large
Load Diff
569
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
569
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
@@ -1,569 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
helpName = "help"
|
||||
helpAlias = "h"
|
||||
)
|
||||
|
||||
// this instance is to avoid recursion in the ShowCommandHelp which can
|
||||
// add a help command again
|
||||
var helpCommandDontUse = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
}
|
||||
|
||||
var helpCommand = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
Action: func(cCtx *Context) error {
|
||||
args := cCtx.Args()
|
||||
argsPresent := args.First() != ""
|
||||
firstArg := args.First()
|
||||
|
||||
// This action can be triggered by a "default" action of a command
|
||||
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||
//
|
||||
// 1 $ app
|
||||
// 2 $ app help
|
||||
// 3 $ app foo
|
||||
// 4 $ app help foo
|
||||
// 5 $ app foo help
|
||||
// 6 $ app foo -h (with no other sub-commands nor flags defined)
|
||||
|
||||
// Case 4. when executing a help command set the context to parent
|
||||
// to allow resolution of subsequent args. This will transform
|
||||
// $ app help foo
|
||||
// to
|
||||
// $ app foo
|
||||
// which will then be handled as case 3
|
||||
if cCtx.Command.Name == helpName || cCtx.Command.Name == helpAlias {
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
|
||||
// Case 4. $ app help foo
|
||||
// foo is the command for which help needs to be shown
|
||||
if argsPresent {
|
||||
return ShowCommandHelp(cCtx, firstArg)
|
||||
}
|
||||
|
||||
// Case 1 & 2
|
||||
// Special case when running help on main app itself as opposed to individual
|
||||
// commands/subcommands
|
||||
if cCtx.parentContext.App == nil {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 3, 5
|
||||
if (len(cCtx.Command.Subcommands) == 1 && !cCtx.Command.HideHelp && !cCtx.Command.HideHelpCommand) ||
|
||||
(len(cCtx.Command.Subcommands) == 0 && cCtx.Command.HideHelp) {
|
||||
templ := cCtx.Command.CustomHelpTemplate
|
||||
if templ == "" {
|
||||
templ = CommandHelpTemplate
|
||||
}
|
||||
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 6, handling incorporated in the callee itself
|
||||
return ShowSubcommandHelp(cCtx)
|
||||
},
|
||||
}
|
||||
|
||||
// Prints help for the App or Command
|
||||
type helpPrinter func(w io.Writer, templ string, data interface{})
|
||||
|
||||
// Prints help for the App or Command with custom template function.
|
||||
type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
|
||||
|
||||
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
||||
// this calls HelpPrinterCustom using only the default template functions.
|
||||
//
|
||||
// If custom logic for printing help is required, this function can be
|
||||
// overridden. If the ExtraInfo field is defined on an App, this function
|
||||
// should not be modified, as HelpPrinterCustom will be used directly in order
|
||||
// to capture the extra information.
|
||||
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
|
||||
var VersionPrinter = printVersion
|
||||
|
||||
// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
|
||||
func ShowAppHelpAndExit(c *Context, exitCode int) {
|
||||
_ = ShowAppHelp(c)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowAppHelp is an action that displays the help.
|
||||
func ShowAppHelp(cCtx *Context) error {
|
||||
tpl := cCtx.App.CustomAppHelpTemplate
|
||||
if tpl == "" {
|
||||
tpl = AppHelpTemplate
|
||||
}
|
||||
|
||||
if cCtx.App.ExtraInfo == nil {
|
||||
HelpPrinter(cCtx.App.Writer, tpl, cCtx.App)
|
||||
return nil
|
||||
}
|
||||
|
||||
customAppData := func() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ExtraInfo": cCtx.App.ExtraInfo,
|
||||
}
|
||||
}
|
||||
HelpPrinterCustom(cCtx.App.Writer, tpl, cCtx.App, customAppData())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
||||
func DefaultAppComplete(cCtx *Context) {
|
||||
DefaultCompleteWithFlags(nil)(cCtx)
|
||||
}
|
||||
|
||||
func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(os.Getenv("0"), "zsh") {
|
||||
for _, name := range command.Names() {
|
||||
_, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage)
|
||||
}
|
||||
} else {
|
||||
for _, name := range command.Names() {
|
||||
_, _ = fmt.Fprintf(writer, "%s\n", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cliArgContains(flagName string) bool {
|
||||
for _, name := range strings.Split(flagName, ",") {
|
||||
name = strings.TrimSpace(name)
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
for _, a := range os.Args {
|
||||
if a == flag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
|
||||
cur := strings.TrimPrefix(lastArg, "-")
|
||||
cur = strings.TrimPrefix(cur, "-")
|
||||
for _, flag := range flags {
|
||||
if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden {
|
||||
continue
|
||||
}
|
||||
for _, name := range flag.Names() {
|
||||
name = strings.TrimSpace(name)
|
||||
// this will get total count utf8 letters in flag name
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2 // reuse this count to generate single - or -- in flag completion
|
||||
}
|
||||
// if flag name has more than one utf8 letter and last argument in cli has -- prefix then
|
||||
// skip flag completion for short flags example -v or -x
|
||||
if strings.HasPrefix(lastArg, "--") && count == 1 {
|
||||
continue
|
||||
}
|
||||
// match if last argument matches this flag and it is not repeated
|
||||
if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) {
|
||||
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
_, _ = fmt.Fprintln(writer, flagCompletion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) {
|
||||
return func(cCtx *Context) {
|
||||
var lastArg string
|
||||
|
||||
// TODO: This shouldnt depend on os.Args rather it should
|
||||
// depend on root arguments passed to App
|
||||
if len(os.Args) > 2 {
|
||||
lastArg = os.Args[len(os.Args)-2]
|
||||
}
|
||||
|
||||
if lastArg != "" {
|
||||
if strings.HasPrefix(lastArg, "-") {
|
||||
if cmd != nil {
|
||||
printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
printFlagSuggestions(lastArg, cCtx.App.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
printCommandSuggestions(cmd.Subcommands, cCtx.App.Writer)
|
||||
return
|
||||
}
|
||||
|
||||
printCommandSuggestions(cCtx.Command.Subcommands, cCtx.App.Writer)
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandHelpAndExit - exits with code after showing help
|
||||
func ShowCommandHelpAndExit(c *Context, command string, code int) {
|
||||
_ = ShowCommandHelp(c, command)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ShowCommandHelp prints help for the given command
|
||||
func ShowCommandHelp(ctx *Context, command string) error {
|
||||
commands := ctx.App.Commands
|
||||
if ctx.Command.Subcommands != nil {
|
||||
commands = ctx.Command.Subcommands
|
||||
}
|
||||
for _, c := range commands {
|
||||
if c.HasName(command) {
|
||||
if !ctx.App.HideHelpCommand && !c.HasName(helpName) && len(c.Subcommands) != 0 && c.Command(helpName) == nil {
|
||||
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
||||
}
|
||||
if !ctx.App.HideHelp && HelpFlag != nil {
|
||||
c.appendFlag(HelpFlag)
|
||||
}
|
||||
templ := c.CustomHelpTemplate
|
||||
if templ == "" {
|
||||
if len(c.Subcommands) == 0 {
|
||||
templ = CommandHelpTemplate
|
||||
} else {
|
||||
templ = SubcommandHelpTemplate
|
||||
}
|
||||
}
|
||||
|
||||
HelpPrinter(ctx.App.Writer, templ, c)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.App.CommandNotFound == nil {
|
||||
errMsg := fmt.Sprintf("No help topic for '%v'", command)
|
||||
if ctx.App.Suggest && SuggestCommand != nil {
|
||||
if suggestion := SuggestCommand(ctx.Command.Subcommands, command); suggestion != "" {
|
||||
errMsg += ". " + suggestion
|
||||
}
|
||||
}
|
||||
return Exit(errMsg, 3)
|
||||
}
|
||||
|
||||
ctx.App.CommandNotFound(ctx, command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||
func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
|
||||
_ = ShowSubcommandHelp(c)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowSubcommandHelp prints help for the given subcommand
|
||||
func ShowSubcommandHelp(cCtx *Context) error {
|
||||
if cCtx == nil {
|
||||
return nil
|
||||
}
|
||||
// use custom template when provided (fixes #1703)
|
||||
templ := SubcommandHelpTemplate
|
||||
if cCtx.Command != nil && cCtx.Command.CustomHelpTemplate != "" {
|
||||
templ = cCtx.Command.CustomHelpTemplate
|
||||
}
|
||||
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowVersion prints the version number of the App
|
||||
func ShowVersion(cCtx *Context) {
|
||||
VersionPrinter(cCtx)
|
||||
}
|
||||
|
||||
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(cCtx *Context) {
|
||||
c := cCtx.Command
|
||||
if c != nil && c.BashComplete != nil {
|
||||
c.BashComplete(cCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandCompletions prints the custom completions for a given command
|
||||
func ShowCommandCompletions(ctx *Context, command string) {
|
||||
c := ctx.Command.Command(command)
|
||||
if c != nil {
|
||||
if c.BashComplete != nil {
|
||||
c.BashComplete(ctx)
|
||||
} else {
|
||||
DefaultCompleteWithFlags(c)(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printHelpCustom is the default implementation of HelpPrinterCustom.
|
||||
//
|
||||
// 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,
|
||||
"subtract": subtract,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
|
||||
"offset": offset,
|
||||
"offsetCommands": offsetCommands,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||
templates := map[string]string{
|
||||
"helpNameTemplate": helpNameTemplate,
|
||||
"usageTemplate": usageTemplate,
|
||||
"descriptionTemplate": descriptionTemplate,
|
||||
"visibleCommandTemplate": visibleCommandTemplate,
|
||||
"copyrightTemplate": copyrightTemplate,
|
||||
"versionTemplate": versionTemplate,
|
||||
"visibleFlagCategoryTemplate": visibleFlagCategoryTemplate,
|
||||
"visibleFlagTemplate": visibleFlagTemplate,
|
||||
"visibleGlobalFlagCategoryTemplate": strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1),
|
||||
"authorsTemplate": authorsTemplate,
|
||||
"visibleCommandCategoryTemplate": visibleCommandCategoryTemplate,
|
||||
}
|
||||
for name, value := range templates {
|
||||
if _, err := t.New(name).Parse(value); err != nil {
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := t.Execute(w, data)
|
||||
if err != nil {
|
||||
// If the writer is closed, t.Execute will fail, and there's nothing
|
||||
// we can do to recover.
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
_ = w.Flush()
|
||||
}
|
||||
|
||||
func printHelp(out io.Writer, templ string, data interface{}) {
|
||||
HelpPrinterCustom(out, templ, data, nil)
|
||||
}
|
||||
|
||||
func checkVersion(cCtx *Context) bool {
|
||||
found := false
|
||||
for _, name := range VersionFlag.Names() {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func checkHelp(cCtx *Context) bool {
|
||||
if HelpFlag == nil {
|
||||
return false
|
||||
}
|
||||
found := false
|
||||
for _, name := range HelpFlag.Names() {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
|
||||
if !a.EnableBashCompletion {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
pos := len(arguments) - 1
|
||||
lastArg := arguments[pos]
|
||||
|
||||
if lastArg != "--generate-bash-completion" {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
for _, arg := range arguments {
|
||||
// If arguments include "--", shell completion is disabled
|
||||
// because after "--" only positional arguments are accepted.
|
||||
// https://unix.stackexchange.com/a/11382
|
||||
if arg == "--" {
|
||||
return false, arguments
|
||||
}
|
||||
}
|
||||
|
||||
return true, arguments[:pos]
|
||||
}
|
||||
|
||||
func checkCompletions(cCtx *Context) bool {
|
||||
if !cCtx.shellComplete {
|
||||
return false
|
||||
}
|
||||
|
||||
if args := cCtx.Args(); args.Present() {
|
||||
name := args.First()
|
||||
if cmd := cCtx.Command.Command(name); cmd != nil {
|
||||
// let the command handle the completion
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ShowCompletions(cCtx)
|
||||
return true
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func indent(spaces int, v string) string {
|
||||
pad := strings.Repeat(" ", spaces)
|
||||
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||
}
|
||||
|
||||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func wrap(input string, offset int, wrapAt int) string {
|
||||
var ss []string
|
||||
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
padding := strings.Repeat(" ", offset)
|
||||
|
||||
for i, line := range lines {
|
||||
if line == "" {
|
||||
ss = append(ss, line)
|
||||
} else {
|
||||
wrapped := wrapLine(line, offset, wrapAt, padding)
|
||||
if i == 0 {
|
||||
ss = append(ss, wrapped)
|
||||
} else {
|
||||
ss = append(ss, padding+wrapped)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(ss, "\n")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// this function tries to find the max width of the names column
|
||||
// so say we have the following rows for help
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// We want to offset the 2nd row usage by some amount so that everything
|
||||
// is aligned
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// to find that offset we find the length of all the rows and use the max
|
||||
// to calculate the offset
|
||||
func offsetCommands(cmds []*Command, fixed int) int {
|
||||
var max int = 0
|
||||
for _, cmd := range cmds {
|
||||
s := strings.Join(cmd.Names(), ", ")
|
||||
if len(s) > max {
|
||||
max = len(s)
|
||||
}
|
||||
}
|
||||
return max + fixed
|
||||
}
|
||||
5
vendor/github.com/urfave/cli/v2/mkdocs-reqs.txt
generated
vendored
5
vendor/github.com/urfave/cli/v2/mkdocs-reqs.txt
generated
vendored
@@ -1,5 +0,0 @@
|
||||
mkdocs-git-revision-date-localized-plugin~=1.0
|
||||
mkdocs-material-extensions~=1.0
|
||||
mkdocs-material~=8.2
|
||||
mkdocs~=1.3
|
||||
pygments~=2.12
|
||||
102
vendor/github.com/urfave/cli/v2/parse.go
generated
vendored
102
vendor/github.com/urfave/cli/v2/parse.go
generated
vendored
@@ -1,102 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type iterativeParser interface {
|
||||
newFlagSet() (*flag.FlagSet, error)
|
||||
useShortOptionHandling() bool
|
||||
}
|
||||
|
||||
// To enable short-option handling (e.g., "-it" vs "-i -t") we have to
|
||||
// iteratively catch parsing errors. This way we achieve LR parsing without
|
||||
// transforming any arguments. Otherwise, there is no way we can discriminate
|
||||
// combined short options from common arguments that should be left untouched.
|
||||
// Pass `shellComplete` to continue parsing options on failure during shell
|
||||
// completion when, the user-supplied options may be incomplete.
|
||||
func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComplete bool) error {
|
||||
for {
|
||||
err := set.Parse(args)
|
||||
if !ip.useShortOptionHandling() || err == nil {
|
||||
if shellComplete {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
trimmed, trimErr := flagFromError(err)
|
||||
if trimErr != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// regenerate the initial args with the split short opts
|
||||
argsWereSplit := false
|
||||
for i, arg := range args {
|
||||
// skip args that are not part of the error message
|
||||
if name := strings.TrimLeft(arg, "-"); name != trimmed {
|
||||
continue
|
||||
}
|
||||
|
||||
// if we can't split, the error was accurate
|
||||
shortOpts := splitShortOptions(set, arg)
|
||||
if len(shortOpts) == 1 {
|
||||
return err
|
||||
}
|
||||
|
||||
// swap current argument with the split version
|
||||
// do not include args that parsed correctly so far as it would
|
||||
// trigger Value.Set() on those args and would result in
|
||||
// duplicates for slice type flags
|
||||
args = append(shortOpts, args[i+1:]...)
|
||||
argsWereSplit = true
|
||||
break
|
||||
}
|
||||
|
||||
// This should be an impossible to reach code path, but in case the arg
|
||||
// splitting failed to happen, this will prevent infinite loops
|
||||
if !argsWereSplit {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:] {
|
||||
if f := set.Lookup(string(c)); f == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if !isSplittable(arg) || !shortFlagsExist(arg) {
|
||||
return []string{arg}
|
||||
}
|
||||
|
||||
separated := make([]string, 0, len(arg)-1)
|
||||
for _, flagChar := range arg[1:] {
|
||||
separated = append(separated, "-"+string(flagChar))
|
||||
}
|
||||
|
||||
return separated
|
||||
}
|
||||
|
||||
func isSplittable(flagArg string) bool {
|
||||
return strings.HasPrefix(flagArg, "-") && !strings.HasPrefix(flagArg, "--") && len(flagArg) > 2
|
||||
}
|
||||
290
vendor/github.com/urfave/cli/v2/sliceflag.go
generated
vendored
290
vendor/github.com/urfave/cli/v2/sliceflag.go
generated
vendored
@@ -1,290 +0,0 @@
|
||||
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
|
||||
}
|
||||
68
vendor/github.com/urfave/cli/v2/suggestions.go
generated
vendored
68
vendor/github.com/urfave/cli/v2/suggestions.go
generated
vendored
@@ -1,68 +0,0 @@
|
||||
//go:build !urfave_cli_no_suggest
|
||||
// +build !urfave_cli_no_suggest
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/xrash/smetrics"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SuggestFlag = suggestFlag
|
||||
SuggestCommand = suggestCommand
|
||||
}
|
||||
|
||||
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 && HelpFlag != nil {
|
||||
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)
|
||||
}
|
||||
865
vendor/github.com/urfave/cli/v2/zz_generated.flags.go
generated
vendored
865
vendor/github.com/urfave/cli/v2/zz_generated.flags.go
generated
vendored
@@ -1,865 +0,0 @@
|
||||
// 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
|
||||
|
||||
defaultValue *Float64Slice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
Action func(*Context, []float64) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue Generic
|
||||
defaultValueSet bool
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, interface{}) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue *Int64Slice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
Action func(*Context, []int64) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue *IntSlice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
Action func(*Context, []int) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue Path
|
||||
defaultValueSet bool
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, Path) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue *StringSlice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, []string) error
|
||||
|
||||
KeepSpace 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
|
||||
|
||||
defaultValue *Timestamp
|
||||
defaultValueSet bool
|
||||
|
||||
Layout string
|
||||
|
||||
Timezone *time.Location
|
||||
|
||||
Action func(*Context, *time.Time) error
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// Uint64SliceFlag is a flag with type *Uint64Slice
|
||||
type Uint64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Uint64Slice
|
||||
Destination *Uint64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
defaultValue *Uint64Slice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
Action func(*Context, []uint64) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Uint64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Uint64SliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// UintSliceFlag is a flag with type *UintSlice
|
||||
type UintSliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *UintSlice
|
||||
Destination *UintSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
defaultValue *UintSlice
|
||||
defaultValueSet bool
|
||||
|
||||
separator separatorSpec
|
||||
|
||||
Action func(*Context, []uint) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *UintSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *UintSliceFlag) 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
|
||||
|
||||
defaultValue bool
|
||||
defaultValueSet bool
|
||||
|
||||
Count *int
|
||||
|
||||
DisableDefaultText bool
|
||||
|
||||
Action func(*Context, bool) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue float64
|
||||
defaultValueSet bool
|
||||
|
||||
Action func(*Context, float64) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue int
|
||||
defaultValueSet bool
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, int) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue int64
|
||||
defaultValueSet bool
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, int64) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue string
|
||||
defaultValueSet bool
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, string) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue time.Duration
|
||||
defaultValueSet bool
|
||||
|
||||
Action func(*Context, time.Duration) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue uint
|
||||
defaultValueSet bool
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, uint) error
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
defaultValue uint64
|
||||
defaultValueSet bool
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, uint64) error
|
||||
}
|
||||
|
||||
// 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
|
||||
11
vendor/github.com/urfave/cli/v3/.gitignore
generated
vendored
Normal file
11
vendor/github.com/urfave/cli/v3/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
*.coverprofile
|
||||
*.exe
|
||||
*.orig
|
||||
.*envrc
|
||||
.envrc
|
||||
.idea
|
||||
/.local/
|
||||
/site/
|
||||
coverage.txt
|
||||
examples/*/built-example
|
||||
vendor
|
||||
13
vendor/github.com/urfave/cli/v3/.golangci.yaml
generated
vendored
Normal file
13
vendor/github.com/urfave/cli/v3/.golangci.yaml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
version: "2"
|
||||
|
||||
formatters:
|
||||
enable:
|
||||
- gofumpt
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- makezero
|
||||
- misspell
|
||||
exclusions:
|
||||
presets:
|
||||
- std-error-handling
|
||||
2
vendor/github.com/urfave/cli/v2/LICENSE → vendor/github.com/urfave/cli/v3/LICENSE
generated
vendored
2
vendor/github.com/urfave/cli/v2/LICENSE → vendor/github.com/urfave/cli/v3/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 urfave/cli maintainers
|
||||
Copyright (c) 2023 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
|
||||
6
vendor/github.com/urfave/cli/v2/Makefile → vendor/github.com/urfave/cli/v3/Makefile
generated
vendored
6
vendor/github.com/urfave/cli/v2/Makefile → vendor/github.com/urfave/cli/v3/Makefile
generated
vendored
@@ -4,13 +4,13 @@
|
||||
# are very important so that maintainers and contributors can focus their
|
||||
# attention on files that are primarily Go.
|
||||
|
||||
GO_RUN_BUILD := go run internal/build/build.go
|
||||
GO_RUN_BUILD := go run scripts/build.go
|
||||
|
||||
.PHONY: all
|
||||
all: generate vet test check-binary-size gfmrun yamlfmt v2diff
|
||||
all: generate vet test check-binary-size gfmrun
|
||||
|
||||
# NOTE: this is a special catch-all rule to run any of the commands
|
||||
# defined in internal/build/build.go with optional arguments passed
|
||||
# defined in scripts/build.go with optional arguments passed
|
||||
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
|
||||
#
|
||||
# $ make test GFLAGS='--packages cli'
|
||||
56
vendor/github.com/urfave/cli/v3/README.md
generated
vendored
Normal file
56
vendor/github.com/urfave/cli/v3/README.md
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# Welcome to urfave/cli
|
||||
|
||||
[![Go Reference][goreference_badge]][goreference_link]
|
||||
[![Go Report Card][goreportcard_badge]][goreportcard_link]
|
||||
[![codecov][codecov_badge]][codecov_link]
|
||||
[![Tests status][test_badge]][test_link]
|
||||
|
||||
urfave/cli is a **declarative**, simple, fast, and fun package for building
|
||||
command line tools in Go featuring:
|
||||
|
||||
- commands and subcommands with alias and prefix match support
|
||||
- flexible and permissive help system
|
||||
- dynamic shell completion for `bash`, `zsh`, `fish`, and `powershell`
|
||||
- no dependencies except Go standard library
|
||||
- input flags for simple types, slices of simple types, time, duration, and
|
||||
others
|
||||
- compound short flag support (`-a` `-b` `-c` can be shortened to `-abc`)
|
||||
- documentation generation in `man` and Markdown (supported via the
|
||||
[`urfave/cli-docs`][urfave/cli-docs] module)
|
||||
- input lookup from:
|
||||
- environment variables
|
||||
- plain text files
|
||||
- structured file formats (supported via the
|
||||
[`urfave/cli-altsrc`][urfave/cli-altsrc] module)
|
||||
|
||||
## Documentation
|
||||
|
||||
See the hosted documentation website at <https://cli.urfave.org>. Contents of
|
||||
this website are built from the [`./docs`](./docs) directory.
|
||||
|
||||
## Support
|
||||
|
||||
Check the [Q&A discussions]. If you don't find answer to your question, [create
|
||||
a new discussion].
|
||||
|
||||
If you found a bug or have a feature request, [create a new issue].
|
||||
|
||||
Please keep in mind that this project is run by unpaid volunteers.
|
||||
|
||||
### License
|
||||
|
||||
See [`LICENSE`](./LICENSE).
|
||||
|
||||
[test_badge]: https://github.com/urfave/cli/actions/workflows/test.yml/badge.svg
|
||||
[test_link]: https://github.com/urfave/cli/actions/workflows/test.yml
|
||||
[goreference_badge]: https://pkg.go.dev/badge/github.com/urfave/cli/v3.svg
|
||||
[goreference_link]: https://pkg.go.dev/github.com/urfave/cli/v3
|
||||
[goreportcard_badge]: https://goreportcard.com/badge/github.com/urfave/cli/v3
|
||||
[goreportcard_link]: https://goreportcard.com/report/github.com/urfave/cli/v3
|
||||
[codecov_badge]: https://codecov.io/gh/urfave/cli/branch/main/graph/badge.svg?token=t9YGWLh05g
|
||||
[codecov_link]: https://codecov.io/gh/urfave/cli
|
||||
[Q&A discussions]: https://github.com/urfave/cli/discussions/categories/q-a
|
||||
[create a new discussion]: https://github.com/urfave/cli/discussions/new?category=q-a
|
||||
[urfave/cli-docs]: https://github.com/urfave/cli-docs
|
||||
[urfave/cli-altsrc]: https://github.com/urfave/cli-altsrc
|
||||
[create a new issue]: https://github.com/urfave/cli/issues/new/choose
|
||||
402
vendor/github.com/urfave/cli/v3/args.go
generated
vendored
Normal file
402
vendor/github.com/urfave/cli/v3/args.go
generated
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Args interface {
|
||||
// Get returns the nth argument, or else a blank string
|
||||
Get(n int) string
|
||||
// First returns the first argument, or else a blank string
|
||||
First() string
|
||||
// Tail returns the rest of the arguments (not the first one)
|
||||
// or else an empty string slice
|
||||
Tail() []string
|
||||
// Len returns the length of the wrapped slice
|
||||
Len() int
|
||||
// Present checks if there are any arguments present
|
||||
Present() bool
|
||||
// Slice returns a copy of the internal slice
|
||||
Slice() []string
|
||||
}
|
||||
|
||||
type stringSliceArgs struct {
|
||||
v []string
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Get(n int) string {
|
||||
if len(a.v) > n {
|
||||
return a.v[n]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) First() string {
|
||||
return a.Get(0)
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Tail() []string {
|
||||
if a.Len() >= 2 {
|
||||
tail := a.v[1:]
|
||||
ret := make([]string, len(tail))
|
||||
copy(ret, tail)
|
||||
return ret
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Len() int {
|
||||
return len(a.v)
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Present() bool {
|
||||
return a.Len() != 0
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Slice() []string {
|
||||
ret := make([]string, len(a.v))
|
||||
copy(ret, a.v)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Argument captures a positional argument that can
|
||||
// be parsed
|
||||
type Argument interface {
|
||||
// which this argument can be accessed using the given name
|
||||
HasName(string) bool
|
||||
|
||||
// Parse the given args and return unparsed args and/or error
|
||||
Parse([]string) ([]string, error)
|
||||
|
||||
// The usage template for this argument to use in help
|
||||
Usage() string
|
||||
|
||||
// The Value of this Arg
|
||||
Get() any
|
||||
}
|
||||
|
||||
// AnyArguments to differentiate between no arguments(nil) vs aleast one
|
||||
var AnyArguments = []Argument{
|
||||
&StringArgs{
|
||||
Max: -1,
|
||||
},
|
||||
}
|
||||
|
||||
type ArgumentBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
Name string `json:"name"` // the name of this argument
|
||||
Value T `json:"value"` // the default value of this argument
|
||||
Destination *T `json:"-"` // the destination point for this argument
|
||||
UsageText string `json:"usageText"` // the usage text to show
|
||||
Config C `json:"config"` // config for this argument similar to Flag Config
|
||||
|
||||
value *T
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) HasName(s string) bool {
|
||||
return s == a.Name
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) Usage() string {
|
||||
if a.UsageText != "" {
|
||||
return a.UsageText
|
||||
}
|
||||
|
||||
usageFormat := "%[1]s"
|
||||
return fmt.Sprintf(usageFormat, a.Name)
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) Parse(s []string) ([]string, error) {
|
||||
tracef("calling arg%[1] parse with args %[2]", a.Name, s)
|
||||
|
||||
var vc VC
|
||||
var t T
|
||||
value := vc.Create(a.Value, &t, a.Config)
|
||||
a.value = &t
|
||||
|
||||
tracef("attempting arg%[1] parse", &a.Name)
|
||||
if len(s) > 0 {
|
||||
if err := value.Set(s[0]); err != nil {
|
||||
return s, err
|
||||
}
|
||||
*a.value = value.Get().(T)
|
||||
tracef("set arg%[1] one value", a.Name, *a.value)
|
||||
}
|
||||
|
||||
if a.Destination != nil {
|
||||
tracef("setting destination")
|
||||
*a.Destination = *a.value
|
||||
}
|
||||
|
||||
if len(s) > 0 {
|
||||
return s[1:], nil
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) Get() any {
|
||||
if a.value != nil {
|
||||
return *a.value
|
||||
}
|
||||
return a.Value
|
||||
}
|
||||
|
||||
// ArgumentsBase is a base type for slice arguments
|
||||
type ArgumentsBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
Name string `json:"name"` // the name of this argument
|
||||
Value T `json:"value"` // the default value of this argument
|
||||
Destination *[]T `json:"-"` // the destination point for this argument
|
||||
UsageText string `json:"usageText"` // the usage text to show
|
||||
Min int `json:"minTimes"` // the min num of occurrences of this argument
|
||||
Max int `json:"maxTimes"` // the max num of occurrences of this argument, set to -1 for unlimited
|
||||
Config C `json:"config"` // config for this argument similar to Flag Config
|
||||
|
||||
values []T
|
||||
}
|
||||
|
||||
func (a *ArgumentsBase[T, C, VC]) HasName(s string) bool {
|
||||
return s == a.Name
|
||||
}
|
||||
|
||||
func (a *ArgumentsBase[T, C, VC]) Usage() string {
|
||||
if a.UsageText != "" {
|
||||
return a.UsageText
|
||||
}
|
||||
|
||||
usageFormat := ""
|
||||
if a.Min == 0 {
|
||||
if a.Max == 1 {
|
||||
usageFormat = "[%[1]s]"
|
||||
} else {
|
||||
usageFormat = "[%[1]s ...]"
|
||||
}
|
||||
} else {
|
||||
usageFormat = "%[1]s [%[1]s ...]"
|
||||
}
|
||||
return fmt.Sprintf(usageFormat, a.Name)
|
||||
}
|
||||
|
||||
func (a *ArgumentsBase[T, C, VC]) Parse(s []string) ([]string, error) {
|
||||
tracef("calling arg%[1] parse with args %[2]", &a.Name, s)
|
||||
if a.Max == 0 {
|
||||
fmt.Printf("WARNING args %s has max 0, not parsing argument\n", a.Name)
|
||||
return s, nil
|
||||
}
|
||||
if a.Max != -1 && a.Min > a.Max {
|
||||
fmt.Printf("WARNING args %s has min[%d] > max[%d], not parsing argument\n", a.Name, a.Min, a.Max)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
count := 0
|
||||
var vc VC
|
||||
var t T
|
||||
value := vc.Create(a.Value, &t, a.Config)
|
||||
a.values = []T{}
|
||||
|
||||
tracef("attempting arg%[1] parse", &a.Name)
|
||||
for _, arg := range s {
|
||||
if err := value.Set(arg); err != nil {
|
||||
return s, err
|
||||
}
|
||||
tracef("set arg%[1] one value", &a.Name, value.Get().(T))
|
||||
a.values = append(a.values, value.Get().(T))
|
||||
count++
|
||||
if count >= a.Max && a.Max > -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if count < a.Min {
|
||||
return s, fmt.Errorf("sufficient count of arg %s not provided, given %d expected %d", a.Name, count, a.Min)
|
||||
}
|
||||
|
||||
if a.Destination != nil {
|
||||
tracef("appending destination")
|
||||
*a.Destination = a.values // append(*a.Destination, a.values...)
|
||||
}
|
||||
|
||||
return s[count:], nil
|
||||
}
|
||||
|
||||
func (a *ArgumentsBase[T, C, VC]) Get() any {
|
||||
if a.values != nil {
|
||||
return a.values
|
||||
}
|
||||
return []T{}
|
||||
}
|
||||
|
||||
type (
|
||||
FloatArg = ArgumentBase[float64, NoConfig, floatValue[float64]]
|
||||
Float32Arg = ArgumentBase[float32, NoConfig, floatValue[float32]]
|
||||
Float64Arg = ArgumentBase[float64, NoConfig, floatValue[float64]]
|
||||
IntArg = ArgumentBase[int, IntegerConfig, intValue[int]]
|
||||
Int8Arg = ArgumentBase[int8, IntegerConfig, intValue[int8]]
|
||||
Int16Arg = ArgumentBase[int16, IntegerConfig, intValue[int16]]
|
||||
Int32Arg = ArgumentBase[int32, IntegerConfig, intValue[int32]]
|
||||
Int64Arg = ArgumentBase[int64, IntegerConfig, intValue[int64]]
|
||||
StringArg = ArgumentBase[string, StringConfig, stringValue]
|
||||
StringMapArgs = ArgumentBase[map[string]string, StringConfig, StringMap]
|
||||
TimestampArg = ArgumentBase[time.Time, TimestampConfig, timestampValue]
|
||||
UintArg = ArgumentBase[uint, IntegerConfig, uintValue[uint]]
|
||||
Uint8Arg = ArgumentBase[uint8, IntegerConfig, uintValue[uint8]]
|
||||
Uint16Arg = ArgumentBase[uint16, IntegerConfig, uintValue[uint16]]
|
||||
Uint32Arg = ArgumentBase[uint32, IntegerConfig, uintValue[uint32]]
|
||||
Uint64Arg = ArgumentBase[uint64, IntegerConfig, uintValue[uint64]]
|
||||
|
||||
FloatArgs = ArgumentsBase[float64, NoConfig, floatValue[float64]]
|
||||
Float32Args = ArgumentsBase[float32, NoConfig, floatValue[float32]]
|
||||
Float64Args = ArgumentsBase[float64, NoConfig, floatValue[float64]]
|
||||
IntArgs = ArgumentsBase[int, IntegerConfig, intValue[int]]
|
||||
Int8Args = ArgumentsBase[int8, IntegerConfig, intValue[int8]]
|
||||
Int16Args = ArgumentsBase[int16, IntegerConfig, intValue[int16]]
|
||||
Int32Args = ArgumentsBase[int32, IntegerConfig, intValue[int32]]
|
||||
Int64Args = ArgumentsBase[int64, IntegerConfig, intValue[int64]]
|
||||
StringArgs = ArgumentsBase[string, StringConfig, stringValue]
|
||||
TimestampArgs = ArgumentsBase[time.Time, TimestampConfig, timestampValue]
|
||||
UintArgs = ArgumentsBase[uint, IntegerConfig, uintValue[uint]]
|
||||
Uint8Args = ArgumentsBase[uint8, IntegerConfig, uintValue[uint8]]
|
||||
Uint16Args = ArgumentsBase[uint16, IntegerConfig, uintValue[uint16]]
|
||||
Uint32Args = ArgumentsBase[uint32, IntegerConfig, uintValue[uint32]]
|
||||
Uint64Args = ArgumentsBase[uint64, IntegerConfig, uintValue[uint64]]
|
||||
)
|
||||
|
||||
func (c *Command) getArgValue(name string) any {
|
||||
tracef("command %s looking for args %s", c.Name, name)
|
||||
for _, arg := range c.Arguments {
|
||||
if arg.HasName(name) {
|
||||
tracef("command %s found args %s", c.Name, name)
|
||||
return arg.Get()
|
||||
}
|
||||
}
|
||||
tracef("command %s did not find args %s", c.Name, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func arg[T any](name string, c *Command) T {
|
||||
val := c.getArgValue(name)
|
||||
if a, ok := val.(T); ok {
|
||||
return a
|
||||
}
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
|
||||
func (c *Command) StringArg(name string) string {
|
||||
return arg[string](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) StringArgs(name string) []string {
|
||||
return arg[[]string](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) FloatArg(name string) float64 {
|
||||
return arg[float64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) FloatArgs(name string) []float64 {
|
||||
return arg[[]float64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Float32Arg(name string) float32 {
|
||||
return arg[float32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Float32Args(name string) []float32 {
|
||||
return arg[[]float32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Float64Arg(name string) float64 {
|
||||
return arg[float64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Float64Args(name string) []float64 {
|
||||
return arg[[]float64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) IntArg(name string) int {
|
||||
return arg[int](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) IntArgs(name string) []int {
|
||||
return arg[[]int](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int8Arg(name string) int8 {
|
||||
return arg[int8](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int8Args(name string) []int8 {
|
||||
return arg[[]int8](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int16Arg(name string) int16 {
|
||||
return arg[int16](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int16Args(name string) []int16 {
|
||||
return arg[[]int16](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int32Arg(name string) int32 {
|
||||
return arg[int32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int32Args(name string) []int32 {
|
||||
return arg[[]int32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int64Arg(name string) int64 {
|
||||
return arg[int64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Int64Args(name string) []int64 {
|
||||
return arg[[]int64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) UintArg(name string) uint {
|
||||
return arg[uint](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint8Arg(name string) uint8 {
|
||||
return arg[uint8](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint16Arg(name string) uint16 {
|
||||
return arg[uint16](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint32Arg(name string) uint32 {
|
||||
return arg[uint32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint64Arg(name string) uint64 {
|
||||
return arg[uint64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) UintArgs(name string) []uint {
|
||||
return arg[[]uint](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint8Args(name string) []uint8 {
|
||||
return arg[[]uint8](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint16Args(name string) []uint16 {
|
||||
return arg[[]uint16](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint32Args(name string) []uint32 {
|
||||
return arg[[]uint32](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) Uint64Args(name string) []uint64 {
|
||||
return arg[[]uint64](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) TimestampArg(name string) time.Time {
|
||||
return arg[time.Time](name, c)
|
||||
}
|
||||
|
||||
func (c *Command) TimestampArgs(name string) []time.Time {
|
||||
return arg[[]time.Time](name, c)
|
||||
}
|
||||
34
vendor/github.com/urfave/cli/v3/autocomplete/bash_autocomplete
generated
vendored
Normal file
34
vendor/github.com/urfave/cli/v3/autocomplete/bash_autocomplete
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This is a shell completion script auto-generated by https://github.com/urfave/cli for bash.
|
||||
|
||||
# Macs have bash3 for which the bash-completion package doesn't include
|
||||
# _init_completion. This is a minimal version of that function.
|
||||
__%[1]s_init_completion() {
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref "$@" cur prev words cword
|
||||
}
|
||||
|
||||
__%[1]s_bash_autocomplete() {
|
||||
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
|
||||
local cur opts base words
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -n "=:" || return
|
||||
else
|
||||
__%[1]s_init_completion -n "=:" || return
|
||||
fi
|
||||
words=("${words[@]:0:$cword}")
|
||||
if [[ "$cur" == "-"* ]]; then
|
||||
requestComp="${words[*]} ${cur} --generate-shell-completion"
|
||||
else
|
||||
requestComp="${words[*]} --generate-shell-completion"
|
||||
fi
|
||||
opts=$(eval "${requestComp}" 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
complete -o bashdefault -o default -o nospace -F __%[1]s_bash_autocomplete %[1]s
|
||||
9
vendor/github.com/urfave/cli/v3/autocomplete/powershell_autocomplete.ps1
generated
vendored
Normal file
9
vendor/github.com/urfave/cli/v3/autocomplete/powershell_autocomplete.ps1
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
$fn = $($MyInvocation.MyCommand.Name)
|
||||
$name = $fn -replace "(.*)\.ps1$", '$1'
|
||||
Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock {
|
||||
param($commandName, $wordToComplete, $cursorPosition)
|
||||
$other = "$wordToComplete --generate-shell-completion"
|
||||
Invoke-Expression $other | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
29
vendor/github.com/urfave/cli/v3/autocomplete/zsh_autocomplete
generated
vendored
Normal file
29
vendor/github.com/urfave/cli/v3/autocomplete/zsh_autocomplete
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
#compdef %[1]s
|
||||
compdef _%[1]s %[1]s
|
||||
|
||||
# This is a shell completion script auto-generated by https://github.com/urfave/cli for zsh.
|
||||
|
||||
_%[1]s() {
|
||||
local -a opts # Declare a local array
|
||||
local current
|
||||
current=${words[-1]} # -1 means "the last element"
|
||||
if [[ "$current" == "-"* ]]; then
|
||||
# Current word starts with a hyphen, so complete flags/options
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${current} --generate-shell-completion)}")
|
||||
else
|
||||
# Current word does not start with a hyphen, so complete subcommands
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
|
||||
fi
|
||||
|
||||
if [[ "${opts[1]}" != "" ]]; then
|
||||
_describe 'values' opts
|
||||
else
|
||||
_files
|
||||
fi
|
||||
}
|
||||
|
||||
# Don't run the completion function when being source-ed or eval-ed.
|
||||
# See https://github.com/urfave/cli/issues/1874 for discussion.
|
||||
if [ "$funcstack[1]" = "_%[1]s" ]; then
|
||||
_%[1]s
|
||||
fi
|
||||
@@ -102,10 +102,15 @@ func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
|
||||
fc := newFlagCategories()
|
||||
|
||||
var categorized bool
|
||||
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cat := cf.GetCategory(); cat != "" && cf.IsVisible() {
|
||||
fc.AddFlag(cat, cf)
|
||||
visible := false
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
visible = vf.IsVisible()
|
||||
}
|
||||
if cat := cf.GetCategory(); cat != "" && visible {
|
||||
fc.AddFlag(cat, fl)
|
||||
categorized = true
|
||||
}
|
||||
}
|
||||
@@ -114,7 +119,11 @@ func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
|
||||
if categorized {
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cf.GetCategory() == "" && cf.IsVisible() {
|
||||
visible := false
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
visible = vf.IsVisible()
|
||||
}
|
||||
if cf.GetCategory() == "" && visible {
|
||||
fc.AddFlag("", fl)
|
||||
}
|
||||
}
|
||||
@@ -153,7 +162,7 @@ type VisibleFlagCategory interface {
|
||||
// Name returns the category name string
|
||||
Name() string
|
||||
// Flags returns a slice of VisibleFlag sorted by name
|
||||
Flags() []VisibleFlag
|
||||
Flags() []Flag
|
||||
}
|
||||
|
||||
type defaultVisibleFlagCategory struct {
|
||||
@@ -165,7 +174,7 @@ func (fc *defaultVisibleFlagCategory) Name() string {
|
||||
return fc.name
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
|
||||
func (fc *defaultVisibleFlagCategory) Flags() []Flag {
|
||||
vfNames := []string{}
|
||||
for flName, fl := range fc.m {
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
@@ -177,9 +186,9 @@ func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
|
||||
|
||||
sort.Strings(vfNames)
|
||||
|
||||
ret := make([]VisibleFlag, len(vfNames))
|
||||
ret := make([]Flag, len(vfNames))
|
||||
for i, flName := range vfNames {
|
||||
ret[i] = fc.m[flName].(VisibleFlag)
|
||||
ret[i] = fc.m[flName]
|
||||
}
|
||||
|
||||
return ret
|
||||
60
vendor/github.com/urfave/cli/v3/cli.go
generated
vendored
Normal file
60
vendor/github.com/urfave/cli/v3/cli.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Package cli provides a minimal framework for creating and organizing command line
|
||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
||||
// cli application can be written as follows:
|
||||
//
|
||||
// func main() {
|
||||
// (&cli.Command{}).Run(context.Background(), os.Args)
|
||||
// }
|
||||
//
|
||||
// Of course this application does not do much, so let's make this an actual application:
|
||||
//
|
||||
// func main() {
|
||||
// cmd := &cli.Command{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// cmd.Run(context.Background(), os.Args)
|
||||
// }
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var isTracingOn = os.Getenv("URFAVE_CLI_TRACING") == "on"
|
||||
|
||||
func tracef(format string, a ...any) {
|
||||
if !isTracingOn {
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format = format + "\n"
|
||||
}
|
||||
|
||||
pc, file, line, _ := runtime.Caller(1)
|
||||
cf := runtime.FuncForPC(pc)
|
||||
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
strings.Join([]string{
|
||||
"## URFAVE CLI TRACE ",
|
||||
file,
|
||||
":",
|
||||
fmt.Sprintf("%v", line),
|
||||
" ",
|
||||
fmt.Sprintf("(%s)", cf.Name()),
|
||||
" ",
|
||||
format,
|
||||
}, ""),
|
||||
a...,
|
||||
)
|
||||
}
|
||||
563
vendor/github.com/urfave/cli/v3/command.go
generated
vendored
Normal file
563
vendor/github.com/urfave/cli/v3/command.go
generated
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// ignoreFlagPrefix is to ignore test flags when adding flags from other packages
|
||||
ignoreFlagPrefix = "test."
|
||||
|
||||
commandContextKey = contextKey("cli.context")
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
// Command contains everything needed to run an application that
|
||||
// accepts a string slice of arguments such as os.Args. A given
|
||||
// Command may contain Flags and sub-commands in Commands.
|
||||
type Command struct {
|
||||
// The name of the command
|
||||
Name string `json:"name"`
|
||||
// A list of aliases for the command
|
||||
Aliases []string `json:"aliases"`
|
||||
// A short description of the usage of this command
|
||||
Usage string `json:"usage"`
|
||||
// Text to override the USAGE section of help
|
||||
UsageText string `json:"usageText"`
|
||||
// A short description of the arguments of this command
|
||||
ArgsUsage string `json:"argsUsage"`
|
||||
// Version of the command
|
||||
Version string `json:"version"`
|
||||
// Longer explanation of how the command works
|
||||
Description string `json:"description"`
|
||||
// DefaultCommand is the (optional) name of a command
|
||||
// to run if no command names are passed as CLI arguments.
|
||||
DefaultCommand string `json:"defaultCommand"`
|
||||
// The category the command is part of
|
||||
Category string `json:"category"`
|
||||
// List of child commands
|
||||
Commands []*Command `json:"commands"`
|
||||
// List of flags to parse
|
||||
Flags []Flag `json:"flags"`
|
||||
// Boolean to hide built-in help command and help flag
|
||||
HideHelp bool `json:"hideHelp"`
|
||||
// Ignored if HideHelp is true.
|
||||
HideHelpCommand bool `json:"hideHelpCommand"`
|
||||
// Boolean to hide built-in version flag and the VERSION section of help
|
||||
HideVersion bool `json:"hideVersion"`
|
||||
// Boolean to enable shell completion commands
|
||||
EnableShellCompletion bool `json:"-"`
|
||||
// Shell Completion generation command name
|
||||
ShellCompletionCommandName string `json:"-"`
|
||||
// The function to call when checking for shell command completions
|
||||
ShellComplete ShellCompleteFunc `json:"-"`
|
||||
// The function to configure a shell completion command
|
||||
ConfigureShellCompletionCommand ConfigureShellCompletionCommand `json:"-"`
|
||||
// An action to execute before any subcommands are run, but after the context is ready
|
||||
// If a non-nil error is returned, no subcommands are run
|
||||
Before BeforeFunc `json:"-"`
|
||||
// An action to execute after any subcommands are run, but after the subcommand has finished
|
||||
// It is run even if Action() panics
|
||||
After AfterFunc `json:"-"`
|
||||
// The function to call when this command is invoked
|
||||
Action ActionFunc `json:"-"`
|
||||
// Execute this function if the proper command cannot be found
|
||||
CommandNotFound CommandNotFoundFunc `json:"-"`
|
||||
// Execute this function if a usage error occurs.
|
||||
OnUsageError OnUsageErrorFunc `json:"-"`
|
||||
// Execute this function when an invalid flag is accessed from the context
|
||||
InvalidFlagAccessHandler InvalidFlagAccessFunc `json:"-"`
|
||||
// Boolean to hide this command from help or completion
|
||||
Hidden bool `json:"hidden"`
|
||||
// List of all authors who contributed (string or fmt.Stringer)
|
||||
// TODO: ~string | fmt.Stringer when interface unions are available
|
||||
Authors []any `json:"authors"`
|
||||
// Copyright of the binary if any
|
||||
Copyright string `json:"copyright"`
|
||||
// Reader reader to write input to (useful for tests)
|
||||
Reader io.Reader `json:"-"`
|
||||
// Writer writer to write output to
|
||||
Writer io.Writer `json:"-"`
|
||||
// ErrWriter writes error output
|
||||
ErrWriter io.Writer `json:"-"`
|
||||
// ExitErrHandler processes any error encountered while running an App before
|
||||
// it is returned to the caller. If no function is provided, HandleExitCoder
|
||||
// is used as the default behavior.
|
||||
ExitErrHandler ExitErrHandlerFunc `json:"-"`
|
||||
// Other custom info
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
// Carries a function which returns app specific info.
|
||||
ExtraInfo func() map[string]string `json:"-"`
|
||||
// CustomRootCommandHelpTemplate the text template for app help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
CustomRootCommandHelpTemplate string `json:"-"`
|
||||
// SliceFlagSeparator is used to customize the separator for SliceFlag, the default is ","
|
||||
SliceFlagSeparator string `json:"sliceFlagSeparator"`
|
||||
// DisableSliceFlagSeparator is used to disable SliceFlagSeparator, the default is false
|
||||
DisableSliceFlagSeparator bool `json:"disableSliceFlagSeparator"`
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool `json:"useShortOptionHandling"`
|
||||
// Enable suggestions for commands and flags
|
||||
Suggest bool `json:"suggest"`
|
||||
// Allows global flags set by libraries which use flag.XXXVar(...) directly
|
||||
// to be parsed through this library
|
||||
AllowExtFlags bool `json:"allowExtFlags"`
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool `json:"skipFlagParsing"`
|
||||
// CustomHelpTemplate 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.
|
||||
CustomHelpTemplate string `json:"-"`
|
||||
// Use longest prefix match for commands
|
||||
PrefixMatchCommands bool `json:"prefixMatchCommands"`
|
||||
// Custom suggest command for matching
|
||||
SuggestCommandFunc SuggestCommandFunc `json:"-"`
|
||||
// Flag exclusion group
|
||||
MutuallyExclusiveFlags []MutuallyExclusiveFlags `json:"mutuallyExclusiveFlags"`
|
||||
// Arguments to parse for this command
|
||||
Arguments []Argument `json:"arguments"`
|
||||
// Whether to read arguments from stdin
|
||||
// applicable to root command only
|
||||
ReadArgsFromStdin bool `json:"readArgsFromStdin"`
|
||||
|
||||
// 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
|
||||
// flags that have been applied in current parse
|
||||
appliedFlags []Flag
|
||||
// flags that have been set
|
||||
setFlags map[Flag]struct{}
|
||||
// The parent of this command. This value will be nil for the
|
||||
// command at the root of the graph.
|
||||
parent *Command
|
||||
// parsed args
|
||||
parsedArgs Args
|
||||
// track state of error handling
|
||||
isInError bool
|
||||
// track state of defaults
|
||||
didSetupDefaults bool
|
||||
// whether in shell completion mode
|
||||
shellCompletion bool
|
||||
}
|
||||
|
||||
// FullName returns the full name of the command.
|
||||
// For commands with parents this ensures that the parent commands
|
||||
// are part of the command path.
|
||||
func (cmd *Command) FullName() string {
|
||||
namePath := []string{}
|
||||
|
||||
if cmd.parent != nil {
|
||||
namePath = append(namePath, cmd.parent.FullName())
|
||||
}
|
||||
|
||||
return strings.Join(append(namePath, cmd.Name), " ")
|
||||
}
|
||||
|
||||
func (cmd *Command) Command(name string) *Command {
|
||||
for _, subCmd := range cmd.Commands {
|
||||
if subCmd.HasName(name) {
|
||||
return subCmd
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) checkHelp() bool {
|
||||
tracef("checking if help is wanted (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
return HelpFlag != nil && slices.ContainsFunc(HelpFlag.Names(), cmd.Bool)
|
||||
}
|
||||
|
||||
func (cmd *Command) allFlags() []Flag {
|
||||
var flags []Flag
|
||||
flags = append(flags, cmd.Flags...)
|
||||
for _, grpf := range cmd.MutuallyExclusiveFlags {
|
||||
for _, f1 := range grpf.Flags {
|
||||
flags = append(flags, f1...)
|
||||
}
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
// useShortOptionHandling traverses Lineage() for *any* ancestors
|
||||
// with UseShortOptionHandling
|
||||
func (cmd *Command) useShortOptionHandling() bool {
|
||||
for _, pCmd := range cmd.Lineage() {
|
||||
if pCmd.UseShortOptionHandling {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (cmd *Command) suggestFlagFromError(err error, commandName string) (string, error) {
|
||||
fl, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := cmd.Flags
|
||||
hideHelp := cmd.hideHelp()
|
||||
|
||||
if commandName != "" {
|
||||
subCmd := cmd.Command(commandName)
|
||||
if subCmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = subCmd.Flags
|
||||
hideHelp = hideHelp || subCmd.HideHelp
|
||||
}
|
||||
|
||||
suggestion := SuggestFlag(flags, fl, hideHelp)
|
||||
if len(suggestion) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion) + "\n\n", nil
|
||||
}
|
||||
|
||||
// Names returns the names including short names and aliases.
|
||||
func (cmd *Command) Names() []string {
|
||||
return append([]string{cmd.Name}, cmd.Aliases...)
|
||||
}
|
||||
|
||||
// HasName returns true if Command.Name matches given name
|
||||
func (cmd *Command) HasName(name string) bool {
|
||||
return slices.Contains(cmd.Names(), name)
|
||||
}
|
||||
|
||||
// VisibleCategories returns a slice of categories and commands that are
|
||||
// Hidden=false
|
||||
func (cmd *Command) VisibleCategories() []CommandCategory {
|
||||
ret := []CommandCategory{}
|
||||
for _, category := range cmd.categories.Categories() {
|
||||
if visible := func() CommandCategory {
|
||||
if len(category.VisibleCommands()) > 0 {
|
||||
return category
|
||||
}
|
||||
return nil
|
||||
}(); visible != nil {
|
||||
ret = append(ret, visible)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (cmd *Command) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range cmd.Commands {
|
||||
if command.Hidden || command.Name == helpName {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, command)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||
func (cmd *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if cmd.flagCategories == nil {
|
||||
cmd.flagCategories = newFlagCategoriesFromFlags(cmd.allFlags())
|
||||
}
|
||||
return cmd.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (cmd *Command) VisibleFlags() []Flag {
|
||||
return visibleFlags(cmd.allFlags())
|
||||
}
|
||||
|
||||
func (cmd *Command) appendFlag(fl Flag) {
|
||||
if !hasFlag(cmd.Flags, fl) {
|
||||
cmd.Flags = append(cmd.Flags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
// VisiblePersistentFlags returns a slice of [LocalFlag] with Persistent=true and Hidden=false.
|
||||
func (cmd *Command) VisiblePersistentFlags() []Flag {
|
||||
var flags []Flag
|
||||
for _, fl := range cmd.Root().Flags {
|
||||
pfl, ok := fl.(LocalFlag)
|
||||
if !ok || pfl.IsLocal() {
|
||||
continue
|
||||
}
|
||||
flags = append(flags, fl)
|
||||
}
|
||||
return visibleFlags(flags)
|
||||
}
|
||||
|
||||
func (cmd *Command) appendCommand(aCmd *Command) {
|
||||
if !slices.Contains(cmd.Commands, aCmd) {
|
||||
aCmd.parent = cmd
|
||||
cmd.Commands = append(cmd.Commands, aCmd)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *Command) handleExitCoder(ctx context.Context, err error) error {
|
||||
if cmd.parent != nil {
|
||||
return cmd.parent.handleExitCoder(ctx, err)
|
||||
}
|
||||
|
||||
if cmd.ExitErrHandler != nil {
|
||||
cmd.ExitErrHandler(ctx, cmd, err)
|
||||
return err
|
||||
}
|
||||
|
||||
HandleExitCoder(err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *Command) argsWithDefaultCommand(oldArgs Args) Args {
|
||||
if cmd.DefaultCommand != "" {
|
||||
rawArgs := append([]string{cmd.DefaultCommand}, oldArgs.Slice()...)
|
||||
newArgs := &stringSliceArgs{v: rawArgs}
|
||||
|
||||
return newArgs
|
||||
}
|
||||
|
||||
return oldArgs
|
||||
}
|
||||
|
||||
// Root returns the Command at the root of the graph
|
||||
func (cmd *Command) Root() *Command {
|
||||
if cmd.parent == nil {
|
||||
return cmd
|
||||
}
|
||||
|
||||
return cmd.parent.Root()
|
||||
}
|
||||
|
||||
func (cmd *Command) set(fName string, f Flag, val string) error {
|
||||
cmd.setFlags[f] = struct{}{}
|
||||
if err := f.Set(fName, val); err != nil {
|
||||
return fmt.Errorf("invalid value %q for flag -%s: %v", val, fName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) lFlag(name string) Flag {
|
||||
for _, f := range cmd.allFlags() {
|
||||
if slices.Contains(f.Names(), name) {
|
||||
tracef("flag found for name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) lookupFlag(name string) Flag {
|
||||
for _, pCmd := range cmd.Lineage() {
|
||||
if f := pCmd.lFlag(name); f != nil {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
tracef("flag NOT found for name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
cmd.onInvalidFlag(context.TODO(), name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) checkRequiredFlag(f Flag) (bool, string) {
|
||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
||||
flagName := f.Names()[0]
|
||||
if !f.IsSet() {
|
||||
return false, flagName
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (cmd *Command) checkAllRequiredFlags() requiredFlagsErr {
|
||||
for pCmd := cmd; pCmd != nil; pCmd = pCmd.parent {
|
||||
if err := pCmd.checkRequiredFlags(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) checkRequiredFlags() requiredFlagsErr {
|
||||
tracef("checking for required flags (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
missingFlags := []string{}
|
||||
|
||||
for _, f := range cmd.appliedFlags {
|
||||
if ok, name := cmd.checkRequiredFlag(f); !ok {
|
||||
missingFlags = append(missingFlags, name)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingFlags) != 0 {
|
||||
tracef("found missing required flags %[1]q (cmd=%[2]q)", missingFlags, cmd.Name)
|
||||
|
||||
return &errRequiredFlags{missingFlags: missingFlags}
|
||||
}
|
||||
|
||||
tracef("all required flags set (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *Command) onInvalidFlag(ctx context.Context, name string) {
|
||||
for cmd != nil {
|
||||
if cmd.InvalidFlagAccessHandler != nil {
|
||||
cmd.InvalidFlagAccessHandler(ctx, cmd, name)
|
||||
break
|
||||
}
|
||||
cmd = cmd.parent
|
||||
}
|
||||
}
|
||||
|
||||
// NumFlags returns the number of flags set
|
||||
func (cmd *Command) NumFlags() int {
|
||||
tracef("numFlags numAppliedFlags %d", len(cmd.appliedFlags))
|
||||
count := 0
|
||||
for _, f := range cmd.appliedFlags {
|
||||
if f.IsSet() {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count // cmd.flagSet.NFlag()
|
||||
}
|
||||
|
||||
// Set sets a context flag to a value.
|
||||
func (cmd *Command) Set(name, value string) error {
|
||||
if f := cmd.lookupFlag(name); f != nil {
|
||||
return f.Set(name, value)
|
||||
}
|
||||
|
||||
return fmt.Errorf("no such flag -%s", name)
|
||||
}
|
||||
|
||||
// IsSet determines if the flag was actually set
|
||||
func (cmd *Command) IsSet(name string) bool {
|
||||
fl := cmd.lookupFlag(name)
|
||||
if fl == nil {
|
||||
tracef("flag with name %[1]q NOT found; assuming not set (cmd=%[2]q)", name, cmd.Name)
|
||||
return false
|
||||
}
|
||||
|
||||
isSet := fl.IsSet()
|
||||
if isSet {
|
||||
tracef("flag with name %[1]q is set (cmd=%[2]q)", name, cmd.Name)
|
||||
} else {
|
||||
tracef("flag with name %[1]q is no set (cmd=%[2]q)", name, cmd.Name)
|
||||
}
|
||||
|
||||
return isSet
|
||||
}
|
||||
|
||||
// LocalFlagNames returns a slice of flag names used in this
|
||||
// command.
|
||||
func (cmd *Command) LocalFlagNames() []string {
|
||||
names := []string{}
|
||||
|
||||
// Check the flags which have been set via env or file
|
||||
for _, f := range cmd.allFlags() {
|
||||
if f.IsSet() {
|
||||
names = append(names, f.Names()...)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort out the duplicates since flag could be set via multiple
|
||||
// paths
|
||||
m := map[string]struct{}{}
|
||||
uniqNames := []string{}
|
||||
|
||||
for _, name := range names {
|
||||
if _, ok := m[name]; !ok {
|
||||
m[name] = struct{}{}
|
||||
uniqNames = append(uniqNames, name)
|
||||
}
|
||||
}
|
||||
|
||||
return uniqNames
|
||||
}
|
||||
|
||||
// FlagNames returns a slice of flag names used by the this command
|
||||
// and all of its parent commands.
|
||||
func (cmd *Command) FlagNames() []string {
|
||||
names := cmd.LocalFlagNames()
|
||||
|
||||
if cmd.parent != nil {
|
||||
names = append(cmd.parent.FlagNames(), names...)
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
// Lineage returns *this* command and all of its ancestor commands
|
||||
// in order from child to parent
|
||||
func (cmd *Command) Lineage() []*Command {
|
||||
lineage := []*Command{cmd}
|
||||
|
||||
if cmd.parent != nil {
|
||||
lineage = append(lineage, cmd.parent.Lineage()...)
|
||||
}
|
||||
|
||||
return lineage
|
||||
}
|
||||
|
||||
// Count returns the num of occurrences of this flag
|
||||
func (cmd *Command) Count(name string) int {
|
||||
if cf, ok := cmd.lookupFlag(name).(Countable); ok {
|
||||
return cf.Count()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Value returns the value of the flag corresponding to `name`
|
||||
func (cmd *Command) Value(name string) interface{} {
|
||||
if fs := cmd.lookupFlag(name); fs != nil {
|
||||
tracef("value found for name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return fs.Get()
|
||||
}
|
||||
|
||||
tracef("value NOT found for name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Args returns the command line arguments associated with the
|
||||
// command.
|
||||
func (cmd *Command) Args() Args {
|
||||
return cmd.parsedArgs
|
||||
}
|
||||
|
||||
// NArg returns the number of the command line arguments.
|
||||
func (cmd *Command) NArg() int {
|
||||
return cmd.Args().Len()
|
||||
}
|
||||
|
||||
func (cmd *Command) runFlagActions(ctx context.Context) error {
|
||||
tracef("runFlagActions")
|
||||
for fl := range cmd.setFlags {
|
||||
/*tracef("checking %v:%v", fl.Names(), fl.IsSet())
|
||||
if !fl.IsSet() {
|
||||
continue
|
||||
}*/
|
||||
|
||||
//if pf, ok := fl.(LocalFlag); ok && !pf.IsLocal() {
|
||||
// continue
|
||||
//}
|
||||
|
||||
if af, ok := fl.(ActionableFlag); ok {
|
||||
if err := af.RunAction(ctx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
213
vendor/github.com/urfave/cli/v3/command_parse.go
generated
vendored
Normal file
213
vendor/github.com/urfave/cli/v3/command_parse.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
providedButNotDefinedErrMsg = "flag provided but not defined: -"
|
||||
argumentNotProvidedErrMsg = "flag needs an argument: "
|
||||
)
|
||||
|
||||
// flagFromError tries to parse a provided flag from an error message. If the
|
||||
// parsing fails, 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 (cmd *Command) parseFlags(args Args) (Args, error) {
|
||||
tracef("parsing flags from arguments %[1]q (cmd=%[2]q)", args, cmd.Name)
|
||||
|
||||
cmd.setFlags = map[Flag]struct{}{}
|
||||
cmd.appliedFlags = cmd.allFlags()
|
||||
|
||||
tracef("walking command lineage for persistent flags (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
for pCmd := cmd.parent; pCmd != nil; pCmd = pCmd.parent {
|
||||
tracef(
|
||||
"checking ancestor command=%[1]q for persistent flags (cmd=%[2]q)",
|
||||
pCmd.Name, cmd.Name,
|
||||
)
|
||||
|
||||
for _, fl := range pCmd.Flags {
|
||||
flNames := fl.Names()
|
||||
|
||||
pfl, ok := fl.(LocalFlag)
|
||||
if !ok || pfl.IsLocal() {
|
||||
tracef("skipping non-persistent flag %[1]q (cmd=%[2]q)", flNames, cmd.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
tracef(
|
||||
"checking for applying persistent flag=%[1]q pCmd=%[2]q (cmd=%[3]q)",
|
||||
flNames, pCmd.Name, cmd.Name,
|
||||
)
|
||||
|
||||
applyPersistentFlag := true
|
||||
|
||||
for _, name := range flNames {
|
||||
if cmd.lFlag(name) != nil {
|
||||
applyPersistentFlag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !applyPersistentFlag {
|
||||
tracef("not applying as persistent flag=%[1]q (cmd=%[2]q)", flNames, cmd.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
tracef("applying as persistent flag=%[1]q (cmd=%[2]q)", flNames, cmd.Name)
|
||||
|
||||
tracef("appending to applied flags flag=%[1]q (cmd=%[2]q)", flNames, cmd.Name)
|
||||
cmd.appliedFlags = append(cmd.appliedFlags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
tracef("parsing flags iteratively tail=%[1]q (cmd=%[2]q)", args.Tail(), cmd.Name)
|
||||
defer tracef("done parsing flags (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
posArgs := []string{}
|
||||
for rargs := args.Slice(); len(rargs) > 0; rargs = rargs[1:] {
|
||||
tracef("rearrange:1 (cmd=%[1]q) %[2]q", cmd.Name, rargs)
|
||||
|
||||
firstArg := strings.TrimSpace(rargs[0])
|
||||
if len(firstArg) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// stop parsing once we see a "--"
|
||||
if firstArg == "--" {
|
||||
posArgs = append(posArgs, rargs[1:]...)
|
||||
return &stringSliceArgs{posArgs}, nil
|
||||
}
|
||||
|
||||
// handle positional args
|
||||
if firstArg[0] != '-' {
|
||||
// positional argument probably
|
||||
tracef("rearrange-3 (cmd=%[1]q) check %[2]q", cmd.Name, firstArg)
|
||||
|
||||
// if there is a command by that name let the command handle the
|
||||
// rest of the parsing
|
||||
if cmd.Command(firstArg) != nil {
|
||||
posArgs = append(posArgs, rargs...)
|
||||
return &stringSliceArgs{posArgs}, nil
|
||||
}
|
||||
|
||||
posArgs = append(posArgs, firstArg)
|
||||
continue
|
||||
}
|
||||
|
||||
numMinuses := 1
|
||||
// this is same as firstArg == "-"
|
||||
if len(firstArg) == 1 {
|
||||
posArgs = append(posArgs, firstArg)
|
||||
break
|
||||
}
|
||||
|
||||
shortOptionHandling := cmd.useShortOptionHandling()
|
||||
|
||||
// stop parsing -- as short flags
|
||||
if firstArg[1] == '-' {
|
||||
numMinuses++
|
||||
shortOptionHandling = false
|
||||
} else if !unicode.IsLetter(rune(firstArg[1])) {
|
||||
// this is not a flag
|
||||
tracef("parseFlags not a unicode letter. Stop parsing")
|
||||
posArgs = append(posArgs, rargs...)
|
||||
return &stringSliceArgs{posArgs}, nil
|
||||
}
|
||||
|
||||
tracef("parseFlags (shortOptionHandling=%[1]q)", shortOptionHandling)
|
||||
|
||||
flagName := firstArg[numMinuses:]
|
||||
flagVal := ""
|
||||
tracef("flagName:1 (fName=%[1]q)", flagName)
|
||||
if index := strings.Index(flagName, "="); index != -1 {
|
||||
flagVal = flagName[index+1:]
|
||||
flagName = flagName[:index]
|
||||
}
|
||||
|
||||
tracef("flagName:2 (fName=%[1]q) (fVal=%[2]q)", flagName, flagVal)
|
||||
|
||||
f := cmd.lookupFlag(flagName)
|
||||
// found a flag matching given flagName
|
||||
if f != nil {
|
||||
tracef("Trying flag type (fName=%[1]q) (type=%[2]T)", flagName, f)
|
||||
if fb, ok := f.(boolFlag); ok && fb.IsBoolFlag() {
|
||||
if flagVal == "" {
|
||||
flagVal = "true"
|
||||
}
|
||||
tracef("parse Apply bool flag (fName=%[1]q) (fVal=%[2]q)", flagName, flagVal)
|
||||
if err := cmd.set(flagName, f, flagVal); err != nil {
|
||||
return &stringSliceArgs{posArgs}, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
tracef("processing non bool flag (fName=%[1]q)", flagName)
|
||||
// not a bool flag so need to get the next arg
|
||||
if flagVal == "" {
|
||||
if len(rargs) == 1 {
|
||||
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", argumentNotProvidedErrMsg, firstArg)
|
||||
}
|
||||
flagVal = rargs[1]
|
||||
rargs = rargs[1:]
|
||||
}
|
||||
|
||||
tracef("setting non bool flag (fName=%[1]q) (fVal=%[2]q)", flagName, flagVal)
|
||||
if err := cmd.set(flagName, f, flagVal); err != nil {
|
||||
return &stringSliceArgs{posArgs}, err
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// no flag lookup found and short handling is disabled
|
||||
if !shortOptionHandling {
|
||||
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", providedButNotDefinedErrMsg, flagName)
|
||||
}
|
||||
|
||||
// try to split the flags
|
||||
for index, c := range flagName {
|
||||
tracef("processing flag (fName=%[1]q)", string(c))
|
||||
if sf := cmd.lookupFlag(string(c)); sf == nil {
|
||||
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", providedButNotDefinedErrMsg, flagName)
|
||||
} else if fb, ok := sf.(boolFlag); ok && fb.IsBoolFlag() {
|
||||
fv := flagVal
|
||||
if index == (len(flagName)-1) && flagVal == "" {
|
||||
fv = "true"
|
||||
}
|
||||
if fv == "" {
|
||||
fv = "true"
|
||||
}
|
||||
if err := cmd.set(flagName, sf, fv); err != nil {
|
||||
tracef("processing flag.2 (fName=%[1]q)", string(c))
|
||||
return &stringSliceArgs{posArgs}, err
|
||||
}
|
||||
} else if index == len(flagName)-1 { // last flag can take an arg
|
||||
if flagVal == "" {
|
||||
if len(rargs) == 1 {
|
||||
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", argumentNotProvidedErrMsg, string(c))
|
||||
}
|
||||
flagVal = rargs[1]
|
||||
}
|
||||
tracef("parseFlags (flagName %[1]q) (flagVal %[2]q)", flagName, flagVal)
|
||||
if err := cmd.set(flagName, sf, flagVal); err != nil {
|
||||
tracef("processing flag.4 (fName=%[1]q)", string(c))
|
||||
return &stringSliceArgs{posArgs}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracef("returning-2 (cmd=%[1]q) args %[2]q", cmd.Name, posArgs)
|
||||
return &stringSliceArgs{posArgs}, nil
|
||||
}
|
||||
347
vendor/github.com/urfave/cli/v3/command_run.go
generated
vendored
Normal file
347
vendor/github.com/urfave/cli/v3/command_run.go
generated
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"slices"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func (cmd *Command) parseArgsFromStdin() ([]string, error) {
|
||||
type state int
|
||||
const (
|
||||
stateSearchForToken state = -1
|
||||
stateSearchForString state = 0
|
||||
)
|
||||
|
||||
st := stateSearchForToken
|
||||
linenum := 1
|
||||
token := ""
|
||||
args := []string{}
|
||||
|
||||
breader := bufio.NewReader(cmd.Reader)
|
||||
|
||||
outer:
|
||||
for {
|
||||
ch, _, err := breader.ReadRune()
|
||||
if err == io.EOF {
|
||||
switch st {
|
||||
case stateSearchForToken:
|
||||
if token != "--" {
|
||||
args = append(args, token)
|
||||
}
|
||||
case stateSearchForString:
|
||||
// make sure string is not empty
|
||||
for _, t := range token {
|
||||
if !unicode.IsSpace(t) {
|
||||
args = append(args, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
break outer
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch st {
|
||||
case stateSearchForToken:
|
||||
if unicode.IsSpace(ch) || ch == '"' {
|
||||
if ch == '\n' {
|
||||
linenum++
|
||||
}
|
||||
if token != "" {
|
||||
// end the processing here
|
||||
if token == "--" {
|
||||
break outer
|
||||
}
|
||||
args = append(args, token)
|
||||
token = ""
|
||||
}
|
||||
if ch == '"' {
|
||||
st = stateSearchForString
|
||||
}
|
||||
continue
|
||||
}
|
||||
token += string(ch)
|
||||
case stateSearchForString:
|
||||
if ch != '"' {
|
||||
token += string(ch)
|
||||
} else {
|
||||
if token != "" {
|
||||
args = append(args, token)
|
||||
token = ""
|
||||
}
|
||||
/*else {
|
||||
//TODO. Should we pass in empty strings ?
|
||||
}*/
|
||||
st = stateSearchForToken
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracef("parsed stdin args as %v (cmd=%[2]q)", args, cmd.Name)
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// Run is the entry point to the command graph. The positional
|
||||
// arguments are parsed according to the Flag and Command
|
||||
// definitions and the matching Action functions are run.
|
||||
func (cmd *Command) Run(ctx context.Context, osArgs []string) (deferErr error) {
|
||||
_, deferErr = cmd.run(ctx, osArgs)
|
||||
return
|
||||
}
|
||||
|
||||
func (cmd *Command) run(ctx context.Context, osArgs []string) (_ context.Context, deferErr error) {
|
||||
tracef("running with arguments %[1]q (cmd=%[2]q)", osArgs, cmd.Name)
|
||||
cmd.setupDefaults(osArgs)
|
||||
|
||||
if v, ok := ctx.Value(commandContextKey).(*Command); ok {
|
||||
tracef("setting parent (cmd=%[1]q) command from context.Context value (cmd=%[2]q)", v.Name, cmd.Name)
|
||||
cmd.parent = v
|
||||
}
|
||||
|
||||
if cmd.parent == nil {
|
||||
if cmd.ReadArgsFromStdin {
|
||||
if args, err := cmd.parseArgsFromStdin(); err != nil {
|
||||
return ctx, err
|
||||
} else {
|
||||
osArgs = append(osArgs, args...)
|
||||
}
|
||||
}
|
||||
// handle the completion flag separately from the flagset since
|
||||
// completion could be attempted after a flag, but before its value was put
|
||||
// on the command line. this causes the flagset to interpret the completion
|
||||
// flag name as the value of the flag before it which is undesirable
|
||||
// note that we can only do this because the shell autocomplete function
|
||||
// always appends the completion flag at the end of the command
|
||||
tracef("checking osArgs %v (cmd=%[2]q)", osArgs, cmd.Name)
|
||||
cmd.shellCompletion, osArgs = checkShellCompleteFlag(cmd, osArgs)
|
||||
|
||||
tracef("setting cmd.shellCompletion=%[1]v from checkShellCompleteFlag (cmd=%[2]q)", cmd.shellCompletion && cmd.EnableShellCompletion, cmd.Name)
|
||||
cmd.shellCompletion = cmd.EnableShellCompletion && cmd.shellCompletion
|
||||
}
|
||||
|
||||
tracef("using post-checkShellCompleteFlag arguments %[1]q (cmd=%[2]q)", osArgs, cmd.Name)
|
||||
|
||||
tracef("setting self as cmd in context (cmd=%[1]q)", cmd.Name)
|
||||
ctx = context.WithValue(ctx, commandContextKey, cmd)
|
||||
|
||||
if cmd.parent == nil {
|
||||
cmd.setupCommandGraph()
|
||||
}
|
||||
|
||||
var rargs Args = &stringSliceArgs{v: osArgs}
|
||||
for _, f := range cmd.allFlags() {
|
||||
if err := f.PreParse(); err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
var args Args = &stringSliceArgs{rargs.Tail()}
|
||||
var err error
|
||||
|
||||
if cmd.SkipFlagParsing {
|
||||
tracef("skipping flag parsing (cmd=%[1]q)", cmd.Name)
|
||||
cmd.parsedArgs = args
|
||||
} else {
|
||||
cmd.parsedArgs, err = cmd.parseFlags(args)
|
||||
}
|
||||
|
||||
tracef("using post-parse arguments %[1]q (cmd=%[2]q)", args, cmd.Name)
|
||||
|
||||
if checkCompletions(ctx, cmd) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
tracef("setting deferErr from %[1]q (cmd=%[2]q)", err, cmd.Name)
|
||||
deferErr = err
|
||||
|
||||
cmd.isInError = true
|
||||
if cmd.OnUsageError != nil {
|
||||
err = cmd.OnUsageError(ctx, cmd, err, cmd.parent != nil)
|
||||
err = cmd.handleExitCoder(ctx, err)
|
||||
return ctx, err
|
||||
}
|
||||
fmt.Fprintf(cmd.Root().ErrWriter, "Incorrect Usage: %s\n\n", err.Error())
|
||||
if cmd.Suggest {
|
||||
if suggestion, err := cmd.suggestFlagFromError(err, ""); err == nil {
|
||||
fmt.Fprintf(cmd.Root().ErrWriter, "%s", suggestion)
|
||||
}
|
||||
}
|
||||
if !cmd.hideHelp() {
|
||||
if cmd.parent == nil {
|
||||
tracef("running ShowAppHelp")
|
||||
if err := ShowAppHelp(cmd); err != nil {
|
||||
tracef("SILENTLY IGNORING ERROR running ShowAppHelp %[1]v (cmd=%[2]q)", err, cmd.Name)
|
||||
}
|
||||
} else {
|
||||
tracef("running ShowCommandHelp with %[1]q", cmd.Name)
|
||||
if err := ShowCommandHelp(ctx, cmd, cmd.Name); err != nil {
|
||||
tracef("SILENTLY IGNORING ERROR running ShowCommandHelp with %[1]q %[2]v", cmd.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
if cmd.checkHelp() {
|
||||
return ctx, helpCommandAction(ctx, cmd)
|
||||
} else {
|
||||
tracef("no help is wanted (cmd=%[1]q)", cmd.Name)
|
||||
}
|
||||
|
||||
if cmd.parent == nil && !cmd.HideVersion && checkVersion(cmd) {
|
||||
ShowVersion(cmd)
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
for _, flag := range cmd.allFlags() {
|
||||
if err := flag.PostParse(); err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.After != nil && !cmd.Root().shellCompletion {
|
||||
defer func() {
|
||||
if err := cmd.After(ctx, cmd); err != nil {
|
||||
err = cmd.handleExitCoder(ctx, err)
|
||||
|
||||
if deferErr != nil {
|
||||
deferErr = newMultiError(deferErr, err)
|
||||
} else {
|
||||
deferErr = err
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for _, grp := range cmd.MutuallyExclusiveFlags {
|
||||
if err := grp.check(cmd); err != nil {
|
||||
if cmd.OnUsageError != nil {
|
||||
err = cmd.OnUsageError(ctx, cmd, err, cmd.parent != nil)
|
||||
} else {
|
||||
_ = ShowSubcommandHelp(cmd)
|
||||
}
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
var subCmd *Command
|
||||
if cmd.parsedArgs.Present() {
|
||||
tracef("checking positional args %[1]q (cmd=%[2]q)", cmd.parsedArgs, cmd.Name)
|
||||
|
||||
name := cmd.parsedArgs.First()
|
||||
|
||||
tracef("using first positional argument as sub-command name=%[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
|
||||
if cmd.SuggestCommandFunc != nil && name != "--" {
|
||||
name = cmd.SuggestCommandFunc(cmd.Commands, name)
|
||||
}
|
||||
subCmd = cmd.Command(name)
|
||||
if subCmd == nil {
|
||||
hasDefault := cmd.DefaultCommand != ""
|
||||
isFlagName := slices.Contains(cmd.FlagNames(), name)
|
||||
|
||||
if hasDefault {
|
||||
tracef("using default command=%[1]q (cmd=%[2]q)", cmd.DefaultCommand, cmd.Name)
|
||||
}
|
||||
|
||||
if isFlagName || hasDefault {
|
||||
argsWithDefault := cmd.argsWithDefaultCommand(args)
|
||||
tracef("using default command args=%[1]q (cmd=%[2]q)", argsWithDefault, cmd.Name)
|
||||
if !reflect.DeepEqual(args, argsWithDefault) {
|
||||
subCmd = cmd.Command(argsWithDefault.First())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if cmd.parent == nil && cmd.DefaultCommand != "" {
|
||||
tracef("no positional args present; checking default command %[1]q (cmd=%[2]q)", cmd.DefaultCommand, cmd.Name)
|
||||
|
||||
if dc := cmd.Command(cmd.DefaultCommand); dc != cmd {
|
||||
subCmd = dc
|
||||
}
|
||||
}
|
||||
|
||||
// If a subcommand has been resolved, let it handle the remaining execution.
|
||||
if subCmd != nil {
|
||||
tracef("running sub-command %[1]q with arguments %[2]q (cmd=%[3]q)", subCmd.Name, cmd.Args(), cmd.Name)
|
||||
|
||||
// It is important that we overwrite the ctx variable in the current
|
||||
// function so any defer'd functions use the new context returned
|
||||
// from the sub command.
|
||||
ctx, err = subCmd.run(ctx, cmd.Args().Slice())
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// This code path is the innermost command execution. Here we actually
|
||||
// perform the command action.
|
||||
//
|
||||
// First, resolve the chain of nested commands up to the parent.
|
||||
var cmdChain []*Command
|
||||
for p := cmd; p != nil; p = p.parent {
|
||||
cmdChain = append(cmdChain, p)
|
||||
}
|
||||
slices.Reverse(cmdChain)
|
||||
|
||||
// Run Before actions in order.
|
||||
for _, cmd := range cmdChain {
|
||||
if cmd.Before == nil {
|
||||
continue
|
||||
}
|
||||
if bctx, err := cmd.Before(ctx, cmd); err != nil {
|
||||
deferErr = cmd.handleExitCoder(ctx, err)
|
||||
return ctx, deferErr
|
||||
} else if bctx != nil {
|
||||
ctx = bctx
|
||||
}
|
||||
}
|
||||
|
||||
// Run flag actions in order.
|
||||
// These take a context, so this has to happen after Before actions.
|
||||
for _, cmd := range cmdChain {
|
||||
tracef("running flag actions (cmd=%[1]q)", cmd.Name)
|
||||
if err := cmd.runFlagActions(ctx); err != nil {
|
||||
deferErr = cmd.handleExitCoder(ctx, err)
|
||||
return ctx, deferErr
|
||||
}
|
||||
}
|
||||
|
||||
if err := cmd.checkAllRequiredFlags(); err != nil {
|
||||
cmd.isInError = true
|
||||
_ = ShowSubcommandHelp(cmd)
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// Run the command action.
|
||||
if len(cmd.Arguments) > 0 {
|
||||
rargs := cmd.Args().Slice()
|
||||
tracef("calling argparse with %[1]v", rargs)
|
||||
for _, arg := range cmd.Arguments {
|
||||
var err error
|
||||
rargs, err = arg.Parse(rargs)
|
||||
if err != nil {
|
||||
tracef("calling with %[1]v (cmd=%[2]q)", err, cmd.Name)
|
||||
if cmd.OnUsageError != nil {
|
||||
err = cmd.OnUsageError(ctx, cmd, err, cmd.parent != nil)
|
||||
}
|
||||
err = cmd.handleExitCoder(ctx, err)
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
cmd.parsedArgs = &stringSliceArgs{v: rargs}
|
||||
}
|
||||
|
||||
if err := cmd.Action(ctx, cmd); err != nil {
|
||||
tracef("calling handleExitCoder with %[1]v (cmd=%[2]q)", err, cmd.Name)
|
||||
deferErr = cmd.handleExitCoder(ctx, err)
|
||||
}
|
||||
|
||||
tracef("returning deferErr (cmd=%[1]q) %[2]q", cmd.Name, deferErr)
|
||||
return ctx, deferErr
|
||||
}
|
||||
214
vendor/github.com/urfave/cli/v3/command_setup.go
generated
vendored
Normal file
214
vendor/github.com/urfave/cli/v3/command_setup.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (cmd *Command) setupDefaults(osArgs []string) {
|
||||
if cmd.didSetupDefaults {
|
||||
tracef("already did setup (cmd=%[1]q)", cmd.Name)
|
||||
return
|
||||
}
|
||||
|
||||
cmd.didSetupDefaults = true
|
||||
|
||||
isRoot := cmd.parent == nil
|
||||
tracef("isRoot? %[1]v (cmd=%[2]q)", isRoot, cmd.Name)
|
||||
|
||||
if cmd.ShellComplete == nil {
|
||||
tracef("setting default ShellComplete (cmd=%[1]q)", cmd.Name)
|
||||
cmd.ShellComplete = DefaultCompleteWithFlags
|
||||
}
|
||||
|
||||
if cmd.Name == "" && isRoot {
|
||||
name := filepath.Base(osArgs[0])
|
||||
tracef("setting cmd.Name from first arg basename (cmd=%[1]q)", name)
|
||||
cmd.Name = name
|
||||
}
|
||||
|
||||
if cmd.Usage == "" && isRoot {
|
||||
tracef("setting default Usage (cmd=%[1]q)", cmd.Name)
|
||||
cmd.Usage = "A new cli application"
|
||||
}
|
||||
|
||||
if cmd.Version == "" {
|
||||
tracef("setting HideVersion=true due to empty Version (cmd=%[1]q)", cmd.Name)
|
||||
cmd.HideVersion = true
|
||||
}
|
||||
|
||||
if cmd.Action == nil {
|
||||
tracef("setting default Action as help command action (cmd=%[1]q)", cmd.Name)
|
||||
cmd.Action = helpCommandAction
|
||||
}
|
||||
|
||||
if cmd.Reader == nil {
|
||||
tracef("setting default Reader as os.Stdin (cmd=%[1]q)", cmd.Name)
|
||||
cmd.Reader = os.Stdin
|
||||
}
|
||||
|
||||
if cmd.Writer == nil {
|
||||
tracef("setting default Writer as os.Stdout (cmd=%[1]q)", cmd.Name)
|
||||
cmd.Writer = os.Stdout
|
||||
}
|
||||
|
||||
if cmd.ErrWriter == nil {
|
||||
tracef("setting default ErrWriter as os.Stderr (cmd=%[1]q)", cmd.Name)
|
||||
cmd.ErrWriter = os.Stderr
|
||||
}
|
||||
|
||||
if cmd.AllowExtFlags {
|
||||
tracef("visiting all flags given AllowExtFlags=true (cmd=%[1]q)", cmd.Name)
|
||||
// add global flags added by other packages
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
// skip test flags
|
||||
if !strings.HasPrefix(f.Name, ignoreFlagPrefix) {
|
||||
cmd.Flags = append(cmd.Flags, &extFlag{f})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for _, subCmd := range cmd.Commands {
|
||||
tracef("setting sub-command (cmd=%[1]q) parent as self (cmd=%[2]q)", subCmd.Name, cmd.Name)
|
||||
subCmd.parent = cmd
|
||||
}
|
||||
|
||||
cmd.ensureHelp()
|
||||
|
||||
if !cmd.HideVersion && isRoot {
|
||||
tracef("appending version flag (cmd=%[1]q)", cmd.Name)
|
||||
cmd.appendFlag(VersionFlag)
|
||||
}
|
||||
|
||||
if cmd.PrefixMatchCommands && cmd.SuggestCommandFunc == nil {
|
||||
tracef("setting default SuggestCommandFunc (cmd=%[1]q)", cmd.Name)
|
||||
cmd.SuggestCommandFunc = suggestCommand
|
||||
}
|
||||
|
||||
if isRoot && cmd.EnableShellCompletion || cmd.ConfigureShellCompletionCommand != nil {
|
||||
completionCommand := buildCompletionCommand(cmd.Name)
|
||||
|
||||
if cmd.ShellCompletionCommandName != "" {
|
||||
tracef(
|
||||
"setting completion command name (%[1]q) from "+
|
||||
"cmd.ShellCompletionCommandName (cmd=%[2]q)",
|
||||
cmd.ShellCompletionCommandName, cmd.Name,
|
||||
)
|
||||
completionCommand.Name = cmd.ShellCompletionCommandName
|
||||
}
|
||||
|
||||
tracef("appending completionCommand (cmd=%[1]q)", cmd.Name)
|
||||
cmd.appendCommand(completionCommand)
|
||||
if cmd.ConfigureShellCompletionCommand != nil {
|
||||
cmd.ConfigureShellCompletionCommand(completionCommand)
|
||||
}
|
||||
}
|
||||
|
||||
tracef("setting command categories (cmd=%[1]q)", cmd.Name)
|
||||
cmd.categories = newCommandCategories()
|
||||
|
||||
for _, subCmd := range cmd.Commands {
|
||||
cmd.categories.AddCommand(subCmd.Category, subCmd)
|
||||
}
|
||||
|
||||
tracef("sorting command categories (cmd=%[1]q)", cmd.Name)
|
||||
sort.Sort(cmd.categories.(*commandCategories))
|
||||
|
||||
tracef("setting category on mutually exclusive flags (cmd=%[1]q)", cmd.Name)
|
||||
for _, grp := range cmd.MutuallyExclusiveFlags {
|
||||
grp.propagateCategory()
|
||||
}
|
||||
|
||||
tracef("setting flag categories (cmd=%[1]q)", cmd.Name)
|
||||
cmd.flagCategories = newFlagCategoriesFromFlags(cmd.allFlags())
|
||||
|
||||
if cmd.Metadata == nil {
|
||||
tracef("setting default Metadata (cmd=%[1]q)", cmd.Name)
|
||||
cmd.Metadata = map[string]any{}
|
||||
}
|
||||
|
||||
if len(cmd.SliceFlagSeparator) != 0 {
|
||||
tracef("setting defaultSliceFlagSeparator from cmd.SliceFlagSeparator (cmd=%[1]q)", cmd.Name)
|
||||
defaultSliceFlagSeparator = cmd.SliceFlagSeparator
|
||||
}
|
||||
|
||||
tracef("setting disableSliceFlagSeparator from cmd.DisableSliceFlagSeparator (cmd=%[1]q)", cmd.Name)
|
||||
disableSliceFlagSeparator = cmd.DisableSliceFlagSeparator
|
||||
|
||||
cmd.setFlags = map[Flag]struct{}{}
|
||||
}
|
||||
|
||||
func (cmd *Command) setupCommandGraph() {
|
||||
tracef("setting up command graph (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
for _, subCmd := range cmd.Commands {
|
||||
subCmd.parent = cmd
|
||||
subCmd.setupSubcommand()
|
||||
subCmd.setupCommandGraph()
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *Command) setupSubcommand() {
|
||||
tracef("setting up self as sub-command (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
cmd.ensureHelp()
|
||||
|
||||
tracef("setting command categories (cmd=%[1]q)", cmd.Name)
|
||||
cmd.categories = newCommandCategories()
|
||||
|
||||
for _, subCmd := range cmd.Commands {
|
||||
cmd.categories.AddCommand(subCmd.Category, subCmd)
|
||||
}
|
||||
|
||||
tracef("sorting command categories (cmd=%[1]q)", cmd.Name)
|
||||
sort.Sort(cmd.categories.(*commandCategories))
|
||||
|
||||
tracef("setting category on mutually exclusive flags (cmd=%[1]q)", cmd.Name)
|
||||
for _, grp := range cmd.MutuallyExclusiveFlags {
|
||||
grp.propagateCategory()
|
||||
}
|
||||
|
||||
tracef("setting flag categories (cmd=%[1]q)", cmd.Name)
|
||||
cmd.flagCategories = newFlagCategoriesFromFlags(cmd.allFlags())
|
||||
}
|
||||
|
||||
func (cmd *Command) hideHelp() bool {
|
||||
tracef("hide help (cmd=%[1]q)", cmd.Name)
|
||||
for c := cmd; c != nil; c = c.parent {
|
||||
if c.HideHelp {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (cmd *Command) ensureHelp() {
|
||||
tracef("ensuring help (cmd=%[1]q)", cmd.Name)
|
||||
|
||||
helpCommand := buildHelpCommand(true)
|
||||
|
||||
if !cmd.hideHelp() {
|
||||
if cmd.Command(helpCommand.Name) == nil {
|
||||
if !cmd.HideHelpCommand {
|
||||
tracef("appending helpCommand (cmd=%[1]q)", cmd.Name)
|
||||
cmd.appendCommand(helpCommand)
|
||||
}
|
||||
}
|
||||
|
||||
if HelpFlag != nil {
|
||||
// TODO need to remove hack
|
||||
if hf, ok := HelpFlag.(*BoolFlag); ok {
|
||||
hf.applied = false
|
||||
hf.hasBeenSet = false
|
||||
hf.Value = false
|
||||
hf.value = nil
|
||||
}
|
||||
tracef("appending HelpFlag (cmd=%[1]q)", cmd.Name)
|
||||
cmd.appendFlag(HelpFlag)
|
||||
}
|
||||
}
|
||||
}
|
||||
100
vendor/github.com/urfave/cli/v3/completion.go
generated
vendored
Normal file
100
vendor/github.com/urfave/cli/v3/completion.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
completionCommandName = "completion"
|
||||
|
||||
// This flag is supposed to only be used by the completion script itself to generate completions on the fly.
|
||||
completionFlag = "--generate-shell-completion"
|
||||
)
|
||||
|
||||
type renderCompletion func(cmd *Command, appName string) (string, error)
|
||||
|
||||
var (
|
||||
//go:embed autocomplete
|
||||
autoCompleteFS embed.FS
|
||||
|
||||
shellCompletions = map[string]renderCompletion{
|
||||
"bash": func(c *Command, appName string) (string, error) {
|
||||
b, err := autoCompleteFS.ReadFile("autocomplete/bash_autocomplete")
|
||||
return fmt.Sprintf(string(b), appName), err
|
||||
},
|
||||
"zsh": func(c *Command, appName string) (string, error) {
|
||||
b, err := autoCompleteFS.ReadFile("autocomplete/zsh_autocomplete")
|
||||
return fmt.Sprintf(string(b), appName), err
|
||||
},
|
||||
"fish": func(c *Command, appName string) (string, error) {
|
||||
return c.Root().ToFishCompletion()
|
||||
},
|
||||
"pwsh": func(c *Command, appName string) (string, error) {
|
||||
b, err := autoCompleteFS.ReadFile("autocomplete/powershell_autocomplete.ps1")
|
||||
return string(b), err
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const completionDescription = `Output shell completion script for bash, zsh, fish, or Powershell.
|
||||
Source the output to enable completion.
|
||||
|
||||
# .bashrc
|
||||
source <($COMMAND completion bash)
|
||||
|
||||
# .zshrc
|
||||
source <($COMMAND completion zsh)
|
||||
|
||||
# fish
|
||||
$COMMAND completion fish > ~/.config/fish/completions/$COMMAND.fish
|
||||
|
||||
# Powershell
|
||||
Output the script to path/to/autocomplete/$COMMAND.ps1 an run it.
|
||||
`
|
||||
|
||||
func buildCompletionCommand(appName string) *Command {
|
||||
return &Command{
|
||||
Name: completionCommandName,
|
||||
Hidden: true,
|
||||
Usage: "Output shell completion script for bash, zsh, fish, or Powershell",
|
||||
Description: strings.ReplaceAll(completionDescription, "$COMMAND", appName),
|
||||
Action: func(ctx context.Context, cmd *Command) error {
|
||||
return printShellCompletion(ctx, cmd, appName)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func printShellCompletion(_ context.Context, cmd *Command, appName string) error {
|
||||
var shells []string
|
||||
for k := range shellCompletions {
|
||||
shells = append(shells, k)
|
||||
}
|
||||
|
||||
sort.Strings(shells)
|
||||
|
||||
if cmd.Args().Len() == 0 {
|
||||
return Exit(fmt.Sprintf("no shell provided for completion command. available shells are %+v", shells), 1)
|
||||
}
|
||||
s := cmd.Args().First()
|
||||
|
||||
renderCompletion, ok := shellCompletions[s]
|
||||
if !ok {
|
||||
return Exit(fmt.Sprintf("unknown shell %s, available shells are %+v", s, shells), 1)
|
||||
}
|
||||
|
||||
completionScript, err := renderCompletion(cmd, appName)
|
||||
if err != nil {
|
||||
return Exit(err, 1)
|
||||
}
|
||||
|
||||
_, err = cmd.Writer.Write([]byte(completionScript))
|
||||
if err != nil {
|
||||
return Exit(err, 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
125
vendor/github.com/urfave/cli/v3/docs.go
generated
vendored
Normal file
125
vendor/github.com/urfave/cli/v3/docs.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func prefixFor(name string) (prefix string) {
|
||||
if len(name) == 1 {
|
||||
prefix = "-"
|
||||
} else {
|
||||
prefix = "--"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the placeholder, if any, and the unquoted usage string.
|
||||
func unquoteUsage(usage string) (string, string) {
|
||||
for i := 0; i < len(usage); i++ {
|
||||
if usage[i] == '`' {
|
||||
for j := i + 1; j < len(usage); j++ {
|
||||
if usage[j] == '`' {
|
||||
name := usage[i+1 : j]
|
||||
usage = usage[:i] + name + usage[j+1:]
|
||||
return name, usage
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return "", usage
|
||||
}
|
||||
|
||||
func prefixedNames(names []string, placeholder string) string {
|
||||
var prefixed string
|
||||
for i, name := range names {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
prefixed += prefixFor(name) + name
|
||||
if placeholder != "" {
|
||||
prefixed += " " + placeholder
|
||||
}
|
||||
if i < len(names)-1 {
|
||||
prefixed += ", "
|
||||
}
|
||||
}
|
||||
return prefixed
|
||||
}
|
||||
|
||||
func envFormat(envVars []string, prefix, sep, suffix string) string {
|
||||
if len(envVars) > 0 {
|
||||
return fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultEnvFormat(envVars []string) string {
|
||||
return envFormat(envVars, "$", ", $", "")
|
||||
}
|
||||
|
||||
func withEnvHint(envVars []string, str string) string {
|
||||
envText := ""
|
||||
if runtime.GOOS != "windows" || os.Getenv("PSHOME") != "" {
|
||||
envText = defaultEnvFormat(envVars)
|
||||
} else {
|
||||
envText = envFormat(envVars, "%", "%, %", "%")
|
||||
}
|
||||
return str + envText
|
||||
}
|
||||
|
||||
func withFileHint(filePath, str string) string {
|
||||
fileText := ""
|
||||
if filePath != "" {
|
||||
fileText = fmt.Sprintf(" [%s]", filePath)
|
||||
}
|
||||
return str + fileText
|
||||
}
|
||||
|
||||
func formatDefault(format string) string {
|
||||
return " (default: " + format + ")"
|
||||
}
|
||||
|
||||
func stringifyFlag(f Flag) string {
|
||||
// enforce DocGeneration interface on flags to avoid reflection
|
||||
df, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||
needsPlaceholder := df.TakesValue()
|
||||
// if needsPlaceholder is true, placeholder is empty
|
||||
if needsPlaceholder && placeholder == "" {
|
||||
// try to get type from flag
|
||||
if tname := df.TypeName(); tname != "" {
|
||||
placeholder = tname
|
||||
} else {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
}
|
||||
|
||||
defaultValueString := ""
|
||||
|
||||
// don't print default text for required flags
|
||||
if rf, ok := f.(RequiredFlag); !ok || !rf.IsRequired() {
|
||||
isVisible := df.IsDefaultVisible()
|
||||
if s := df.GetDefaultText(); isVisible && s != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||
}
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||
|
||||
pn := prefixedNames(f.Names(), placeholder)
|
||||
sliceFlag, ok := f.(DocGenerationMultiValueFlag)
|
||||
if ok && sliceFlag.IsMultiValueFlag() {
|
||||
pn = pn + " [ " + pn + " ]"
|
||||
}
|
||||
|
||||
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||
}
|
||||
45
vendor/github.com/urfave/cli/v2/errors.go → vendor/github.com/urfave/cli/v3/errors.go
generated
vendored
45
vendor/github.com/urfave/cli/v2/errors.go → vendor/github.com/urfave/cli/v3/errors.go
generated
vendored
@@ -41,15 +41,12 @@ func (m *multiError) Error() string {
|
||||
// Errors returns a copy of the errors slice
|
||||
func (m *multiError) Errors() []error {
|
||||
errs := make([]error, len(*m))
|
||||
for _, err := range *m {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
copy(errs, *m)
|
||||
return errs
|
||||
}
|
||||
|
||||
type requiredFlagsErr interface {
|
||||
error
|
||||
getMissingFlags() []string
|
||||
}
|
||||
|
||||
type errRequiredFlags struct {
|
||||
@@ -57,16 +54,37 @@ type errRequiredFlags struct {
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) Error() string {
|
||||
numberOfMissingFlags := len(e.missingFlags)
|
||||
if numberOfMissingFlags == 1 {
|
||||
if len(e.missingFlags) == 1 {
|
||||
return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
|
||||
}
|
||||
joinedMissingFlags := strings.Join(e.missingFlags, ", ")
|
||||
return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) getMissingFlags() []string {
|
||||
return e.missingFlags
|
||||
type mutuallyExclusiveGroup struct {
|
||||
flag1Name string
|
||||
flag2Name string
|
||||
}
|
||||
|
||||
func (e *mutuallyExclusiveGroup) Error() string {
|
||||
return fmt.Sprintf("option %s cannot be set along with option %s", e.flag1Name, e.flag2Name)
|
||||
}
|
||||
|
||||
type mutuallyExclusiveGroupRequiredFlag struct {
|
||||
flags *MutuallyExclusiveFlags
|
||||
}
|
||||
|
||||
func (e *mutuallyExclusiveGroupRequiredFlag) Error() string {
|
||||
var missingFlags []string
|
||||
for _, grpf := range e.flags.Flags {
|
||||
var grpString []string
|
||||
for _, f := range grpf {
|
||||
grpString = append(grpString, f.Names()...)
|
||||
}
|
||||
missingFlags = append(missingFlags, strings.Join(grpString, " "))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("one of these flags needs to be provided: %s", strings.Join(missingFlags, ", "))
|
||||
}
|
||||
|
||||
// ErrorFormatter is the interface that will suitably format the error output
|
||||
@@ -86,13 +104,6 @@ type exitError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
// NewExitError calls Exit to create a new ExitCoder.
|
||||
//
|
||||
// Deprecated: This function is a duplicate of Exit and will eventually be removed.
|
||||
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
||||
return Exit(message, exitCode)
|
||||
}
|
||||
|
||||
// Exit wraps a message and exit code into an error, which by default is
|
||||
// handled with a call to os.Exit during default error handling.
|
||||
//
|
||||
@@ -126,10 +137,6 @@ func (ee *exitError) ExitCode() int {
|
||||
return ee.exitCode
|
||||
}
|
||||
|
||||
func (ee *exitError) Unwrap() error {
|
||||
return ee.err
|
||||
}
|
||||
|
||||
// HandleExitCoder handles errors implementing ExitCoder by printing their
|
||||
// message and calling OsExiter with the given exit code.
|
||||
//
|
||||
189
vendor/github.com/urfave/cli/v3/fish.go
generated
vendored
Normal file
189
vendor/github.com/urfave/cli/v3/fish.go
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// ToFishCompletion creates a fish completion string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (cmd *Command) ToFishCompletion() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := cmd.writeFishCompletionTemplate(&w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
type fishCommandCompletionTemplate struct {
|
||||
Command *Command
|
||||
Completions []string
|
||||
AllCommands []string
|
||||
}
|
||||
|
||||
func (cmd *Command) writeFishCompletionTemplate(w io.Writer) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(FishCompletionTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add global flags
|
||||
completions := prepareFishFlags(cmd.Name, cmd)
|
||||
|
||||
// Add commands and their flags
|
||||
completions = append(
|
||||
completions,
|
||||
prepareFishCommands(cmd.Name, cmd)...,
|
||||
)
|
||||
|
||||
toplevelCommandNames := []string{}
|
||||
for _, child := range cmd.Commands {
|
||||
toplevelCommandNames = append(toplevelCommandNames, child.Names()...)
|
||||
}
|
||||
|
||||
return t.ExecuteTemplate(w, name, &fishCommandCompletionTemplate{
|
||||
Command: cmd,
|
||||
Completions: completions,
|
||||
AllCommands: toplevelCommandNames,
|
||||
})
|
||||
}
|
||||
|
||||
func prepareFishCommands(binary string, parent *Command) []string {
|
||||
commands := parent.Commands
|
||||
completions := []string{}
|
||||
for _, command := range commands {
|
||||
if !command.Hidden {
|
||||
var completion strings.Builder
|
||||
fmt.Fprintf(&completion,
|
||||
"complete -x -c %s -n '%s' -a '%s'",
|
||||
binary,
|
||||
fishSubcommandHelper(binary, parent, commands),
|
||||
command.Name,
|
||||
)
|
||||
|
||||
if command.Usage != "" {
|
||||
fmt.Fprintf(&completion,
|
||||
" -d '%s'",
|
||||
escapeSingleQuotes(command.Usage))
|
||||
}
|
||||
completions = append(completions, completion.String())
|
||||
}
|
||||
completions = append(
|
||||
completions,
|
||||
prepareFishFlags(binary, command)...,
|
||||
)
|
||||
|
||||
// recursively iterate subcommands
|
||||
completions = append(
|
||||
completions,
|
||||
prepareFishCommands(binary, command)...,
|
||||
)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func prepareFishFlags(binary string, owner *Command) []string {
|
||||
flags := owner.VisibleFlags()
|
||||
completions := []string{}
|
||||
for _, f := range flags {
|
||||
completion := &strings.Builder{}
|
||||
fmt.Fprintf(completion,
|
||||
"complete -c %s -n '%s'",
|
||||
binary,
|
||||
fishFlagHelper(binary, owner),
|
||||
)
|
||||
|
||||
fishAddFileFlag(f, completion)
|
||||
|
||||
for idx, opt := range f.Names() {
|
||||
if idx == 0 {
|
||||
fmt.Fprintf(completion,
|
||||
" -l %s", strings.TrimSpace(opt),
|
||||
)
|
||||
} else {
|
||||
fmt.Fprintf(completion,
|
||||
" -s %s", strings.TrimSpace(opt),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if flag, ok := f.(DocGenerationFlag); ok {
|
||||
if flag.TakesValue() {
|
||||
completion.WriteString(" -r")
|
||||
}
|
||||
|
||||
if flag.GetUsage() != "" {
|
||||
fmt.Fprintf(completion,
|
||||
" -d '%s'",
|
||||
escapeSingleQuotes(flag.GetUsage()))
|
||||
}
|
||||
}
|
||||
|
||||
completions = append(completions, completion.String())
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||
switch f := flag.(type) {
|
||||
case *StringFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringSliceFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
}
|
||||
completion.WriteString(" -f")
|
||||
}
|
||||
|
||||
func fishSubcommandHelper(binary string, command *Command, siblings []*Command) string {
|
||||
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", binary)
|
||||
if len(command.Lineage()) > 1 {
|
||||
var siblingNames []string
|
||||
for _, sibling := range siblings {
|
||||
siblingNames = append(siblingNames, sibling.Names()...)
|
||||
}
|
||||
ancestry := commandAncestry(command)
|
||||
fishHelper = fmt.Sprintf(
|
||||
"%s; and not __fish_seen_subcommand_from %s",
|
||||
ancestry,
|
||||
strings.Join(siblingNames, " "),
|
||||
)
|
||||
}
|
||||
return fishHelper
|
||||
}
|
||||
|
||||
func fishFlagHelper(binary string, command *Command) string {
|
||||
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", binary)
|
||||
if len(command.Lineage()) > 1 {
|
||||
fishHelper = commandAncestry(command)
|
||||
}
|
||||
return fishHelper
|
||||
}
|
||||
|
||||
func commandAncestry(command *Command) string {
|
||||
var ancestry []string
|
||||
ancestors := command.Lineage()
|
||||
for i := len(ancestors) - 2; i >= 0; i-- {
|
||||
ancestry = append(
|
||||
ancestry,
|
||||
fmt.Sprintf(
|
||||
"__fish_seen_subcommand_from %s",
|
||||
strings.Join(ancestors[i].Names(), " "),
|
||||
),
|
||||
)
|
||||
}
|
||||
return strings.Join(ancestry, "; and ")
|
||||
}
|
||||
|
||||
func escapeSingleQuotes(input string) string {
|
||||
return strings.ReplaceAll(input, `'`, `\'`)
|
||||
}
|
||||
231
vendor/github.com/urfave/cli/v3/flag.go
generated
vendored
Normal file
231
vendor/github.com/urfave/cli/v3/flag.go
generated
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const defaultPlaceholder = "value"
|
||||
|
||||
var (
|
||||
defaultSliceFlagSeparator = ","
|
||||
defaultMapFlagKeyValueSeparator = "="
|
||||
disableSliceFlagSeparator = false
|
||||
)
|
||||
|
||||
var (
|
||||
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||
|
||||
commaWhitespace = regexp.MustCompile("[, ]+.*")
|
||||
)
|
||||
|
||||
// GenerateShellCompletionFlag enables shell completion
|
||||
var GenerateShellCompletionFlag Flag = &BoolFlag{
|
||||
Name: "generate-shell-completion",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
// VersionFlag prints the version for the application
|
||||
var VersionFlag Flag = &BoolFlag{
|
||||
Name: "version",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print the version",
|
||||
HideDefault: true,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
// HelpFlag prints the help for all commands and subcommands.
|
||||
// Set to nil to disable the flag. The subcommand
|
||||
// will still be added unless HideHelp or HideHelpCommand is set to true.
|
||||
var HelpFlag Flag = &BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
Usage: "show help",
|
||||
HideDefault: true,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
// FlagStringer converts a flag definition to a string. This is used by help
|
||||
// to display a flag.
|
||||
var FlagStringer FlagStringFunc = stringifyFlag
|
||||
|
||||
// Serializer is used to circumvent the limitations of flag.FlagSet.Set
|
||||
type Serializer interface {
|
||||
Serialize() string
|
||||
}
|
||||
|
||||
// FlagNamePrefixer converts a full flag name and its placeholder into the help
|
||||
// message flag prefix. This is used by the default FlagStringer.
|
||||
var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames
|
||||
|
||||
// FlagEnvHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagEnvHinter FlagEnvHintFunc = withEnvHint
|
||||
|
||||
// FlagFileHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagFileHinter FlagFileHintFunc = withFileHint
|
||||
|
||||
// FlagsByName is a slice of Flag.
|
||||
type FlagsByName []Flag
|
||||
|
||||
func (f FlagsByName) Len() int {
|
||||
return len(f)
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
if len(f[j].Names()) == 0 {
|
||||
return false
|
||||
} else if len(f[i].Names()) == 0 {
|
||||
return true
|
||||
}
|
||||
return lexicographicLess(f[i].Names()[0], f[j].Names()[0])
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
f[i], f[j] = f[j], f[i]
|
||||
}
|
||||
|
||||
// ActionableFlag is an interface that wraps Flag interface and RunAction operation.
|
||||
type ActionableFlag interface {
|
||||
RunAction(context.Context, *Command) error
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
type Flag interface {
|
||||
fmt.Stringer
|
||||
|
||||
// Retrieve the value of the Flag
|
||||
Get() any
|
||||
|
||||
// Lifecycle methods.
|
||||
// flag callback prior to parsing
|
||||
PreParse() error
|
||||
|
||||
// flag callback post parsing
|
||||
PostParse() error
|
||||
|
||||
// Apply Flag settings to the given flag set
|
||||
Set(string, string) error
|
||||
|
||||
// All possible names for this flag
|
||||
Names() []string
|
||||
|
||||
// Whether the flag has been set or not
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// RequiredFlag is an interface that allows us to mark flags as required
|
||||
// it allows flags required flags to be backwards compatible with the Flag interface
|
||||
type RequiredFlag interface {
|
||||
// whether the flag is a required flag or not
|
||||
IsRequired() bool
|
||||
}
|
||||
|
||||
// DocGenerationFlag is an interface that allows documentation generation for the flag
|
||||
type DocGenerationFlag interface {
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
TakesValue() bool
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
GetUsage() string
|
||||
|
||||
// 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
|
||||
|
||||
// IsDefaultVisible returns whether the default value should be shown in
|
||||
// help text
|
||||
IsDefaultVisible() bool
|
||||
// TypeName to detect if a flag is a string, bool, etc.
|
||||
TypeName() string
|
||||
}
|
||||
|
||||
// DocGenerationMultiValueFlag extends DocGenerationFlag for slice/map based flags.
|
||||
type DocGenerationMultiValueFlag interface {
|
||||
DocGenerationFlag
|
||||
|
||||
// IsMultiValueFlag returns true for flags that can be given multiple times.
|
||||
IsMultiValueFlag() bool
|
||||
}
|
||||
|
||||
// Countable is an interface to enable detection of flag values which support
|
||||
// repetitive flags
|
||||
type Countable interface {
|
||||
Count() int
|
||||
}
|
||||
|
||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||
type VisibleFlag interface {
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
// CategorizableFlag is an interface that allows us to potentially
|
||||
// use a flag in a categorized representation.
|
||||
type CategorizableFlag interface {
|
||||
// Returns the category of the flag
|
||||
GetCategory() string
|
||||
|
||||
// Sets the category of the flag
|
||||
SetCategory(string)
|
||||
}
|
||||
|
||||
// LocalFlag is an interface to enable detection of flags which are local
|
||||
// to current command
|
||||
type LocalFlag interface {
|
||||
IsLocal() bool
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
|
||||
visible = append(visible, f)
|
||||
}
|
||||
}
|
||||
return visible
|
||||
}
|
||||
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
// v1 -> v2 migration warning zone:
|
||||
// Strip off anything after the first found comma or space, which
|
||||
// *hopefully* makes it a tiny bit more obvious that unexpected behavior is
|
||||
// caused by using the v1 form of stringly typed "Name".
|
||||
ret = append(ret, commaWhitespace.ReplaceAllString(part, ""))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func hasFlag(flags []Flag, fl Flag) bool {
|
||||
for _, existing := range flags {
|
||||
if fl == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func flagSplitMultiValues(val string) []string {
|
||||
if disableSliceFlagSeparator {
|
||||
return []string{val}
|
||||
}
|
||||
|
||||
return strings.Split(val, defaultSliceFlagSeparator)
|
||||
}
|
||||
81
vendor/github.com/urfave/cli/v3/flag_bool.go
generated
vendored
Normal file
81
vendor/github.com/urfave/cli/v3/flag_bool.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type BoolFlag = FlagBase[bool, BoolConfig, boolValue]
|
||||
|
||||
// BoolConfig defines the configuration for bool flags
|
||||
type BoolConfig struct {
|
||||
Count *int
|
||||
}
|
||||
|
||||
// boolValue needs to implement the boolFlag internal interface in flag
|
||||
// to be able to capture bool fields and values
|
||||
//
|
||||
// type boolFlag interface {
|
||||
// Value
|
||||
// IsBoolFlag() bool
|
||||
// }
|
||||
type boolValue struct {
|
||||
destination *bool
|
||||
count *int
|
||||
}
|
||||
|
||||
func (cmd *Command) Bool(name string) bool {
|
||||
if v, ok := cmd.Value(name).(bool); ok {
|
||||
tracef("bool available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("bool NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
// Create creates the bool value
|
||||
func (b boolValue) Create(val bool, p *bool, c BoolConfig) Value {
|
||||
*p = val
|
||||
if c.Count == nil {
|
||||
c.Count = new(int)
|
||||
}
|
||||
return &boolValue{
|
||||
destination: p,
|
||||
count: c.Count,
|
||||
}
|
||||
}
|
||||
|
||||
// ToString formats the bool value
|
||||
func (b boolValue) ToString(value bool) string {
|
||||
return strconv.FormatBool(value)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
err = errors.New("parse error")
|
||||
return err
|
||||
}
|
||||
*b.destination = v
|
||||
if b.count != nil {
|
||||
*b.count = *b.count + 1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *boolValue) Get() interface{} { return *b.destination }
|
||||
|
||||
func (b *boolValue) String() string {
|
||||
return strconv.FormatBool(*b.destination)
|
||||
}
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func (b *boolValue) Count() int {
|
||||
return *b.count
|
||||
}
|
||||
240
vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go
generated
vendored
Normal file
240
vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var DefaultInverseBoolPrefix = "no-"
|
||||
|
||||
type BoolWithInverseFlag struct {
|
||||
Name string `json:"name"` // name of the flag
|
||||
Category string `json:"category"` // category of the flag, if any
|
||||
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
|
||||
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
|
||||
Usage string `json:"usage"` // usage string for help output
|
||||
Sources ValueSourceChain `json:"-"` // sources to load flag value from
|
||||
Required bool `json:"required"` // whether the flag is required or not
|
||||
Hidden bool `json:"hidden"` // whether to hide the flag in help output
|
||||
Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well
|
||||
Value bool `json:"defaultValue"` // default value for this flag if not set by from any source
|
||||
Destination *bool `json:"-"` // destination pointer for value when set
|
||||
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
|
||||
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
|
||||
Action func(context.Context, *Command, bool) error `json:"-"` // Action callback to be called when flag is set
|
||||
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
|
||||
Validator func(bool) error `json:"-"` // custom function to validate this flag value
|
||||
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
|
||||
Config BoolConfig `json:"config"` // Additional/Custom configuration associated with this flag type
|
||||
InversePrefix string `json:"invPrefix"` // The prefix used to indicate a negative value. Default: `env` becomes `no-env`
|
||||
|
||||
// unexported fields for internal use
|
||||
count int // number of times the flag has been set
|
||||
hasBeenSet bool // whether the flag has been set from env or file
|
||||
applied bool // whether the flag has been applied to a flag set already
|
||||
value Value // value representing this flag's value
|
||||
pset bool
|
||||
nset bool
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) IsSet() bool {
|
||||
return bif.hasBeenSet
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) Get() any {
|
||||
return bif.value.Get()
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) RunAction(ctx context.Context, cmd *Command) error {
|
||||
if bif.Action != nil {
|
||||
return bif.Action(ctx, cmd, bif.Get().(bool))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) IsLocal() bool {
|
||||
return bif.Local
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) inversePrefix() string {
|
||||
if bif.InversePrefix == "" {
|
||||
bif.InversePrefix = DefaultInverseBoolPrefix
|
||||
}
|
||||
|
||||
return bif.InversePrefix
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) PreParse() error {
|
||||
count := bif.Config.Count
|
||||
if count == nil {
|
||||
count = &bif.count
|
||||
}
|
||||
dest := bif.Destination
|
||||
if dest == nil {
|
||||
dest = new(bool)
|
||||
}
|
||||
*dest = bif.Value
|
||||
bif.value = &boolValue{
|
||||
destination: dest,
|
||||
count: count,
|
||||
}
|
||||
|
||||
// Validate the given default or values set from external sources as well
|
||||
if bif.Validator != nil && bif.ValidateDefaults {
|
||||
if err := bif.Validator(bif.value.Get().(bool)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
bif.applied = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) PostParse() error {
|
||||
tracef("postparse (flag=%[1]q)", bif.Name)
|
||||
|
||||
if !bif.hasBeenSet {
|
||||
if val, source, found := bif.Sources.LookupWithSource(); found {
|
||||
if val == "" {
|
||||
val = "false"
|
||||
}
|
||||
if err := bif.Set(bif.Name, val); err != nil {
|
||||
return fmt.Errorf(
|
||||
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
|
||||
val, bif.Value, source, bif.Name, err,
|
||||
)
|
||||
}
|
||||
|
||||
bif.hasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) Set(name, val string) error {
|
||||
if bif.count > 0 && bif.OnlyOnce {
|
||||
return fmt.Errorf("cant duplicate this flag")
|
||||
}
|
||||
|
||||
bif.hasBeenSet = true
|
||||
|
||||
if slices.Contains(append([]string{bif.Name}, bif.Aliases...), name) {
|
||||
if bif.nset {
|
||||
return fmt.Errorf("cannot set both flags `--%s` and `--%s`", bif.Name, bif.inversePrefix()+bif.Name)
|
||||
}
|
||||
if err := bif.value.Set(val); err != nil {
|
||||
return err
|
||||
}
|
||||
bif.pset = true
|
||||
} else {
|
||||
if bif.pset {
|
||||
return fmt.Errorf("cannot set both flags `--%s` and `--%s`", bif.Name, bif.inversePrefix()+bif.Name)
|
||||
}
|
||||
if err := bif.value.Set("false"); err != nil {
|
||||
return err
|
||||
}
|
||||
bif.nset = true
|
||||
}
|
||||
|
||||
if bif.Validator != nil {
|
||||
return bif.Validator(bif.value.Get().(bool))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) Names() []string {
|
||||
names := append([]string{bif.Name}, bif.Aliases...)
|
||||
|
||||
for _, name := range names {
|
||||
names = append(names, bif.inversePrefix()+name)
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) IsRequired() bool {
|
||||
return bif.Required
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) IsVisible() bool {
|
||||
return !bif.Hidden
|
||||
}
|
||||
|
||||
// String implements the standard Stringer interface.
|
||||
//
|
||||
// Example for BoolFlag{Name: "env"}
|
||||
// --[no-]env (default: false)
|
||||
func (bif *BoolWithInverseFlag) String() string {
|
||||
out := FlagStringer(bif)
|
||||
|
||||
i := strings.Index(out, "\t")
|
||||
|
||||
prefix := "--"
|
||||
|
||||
// single character flags are prefixed with `-` instead of `--`
|
||||
if len(bif.Name) == 1 {
|
||||
prefix = "-"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s[%s]%s%s", prefix, bif.inversePrefix(), bif.Name, out[i:])
|
||||
}
|
||||
|
||||
// IsBoolFlag returns whether the flag doesnt need to accept args
|
||||
func (bif *BoolWithInverseFlag) IsBoolFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Count returns the number of times this flag has been invoked
|
||||
func (bif *BoolWithInverseFlag) Count() int {
|
||||
return bif.count
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (bif *BoolWithInverseFlag) GetDefaultText() string {
|
||||
if bif.Required {
|
||||
return bif.DefaultText
|
||||
}
|
||||
return boolValue{}.ToString(bif.Value)
|
||||
}
|
||||
|
||||
// GetCategory returns the category of the flag
|
||||
func (bif *BoolWithInverseFlag) GetCategory() string {
|
||||
return bif.Category
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) SetCategory(c string) {
|
||||
bif.Category = c
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (bif *BoolWithInverseFlag) GetUsage() string {
|
||||
return bif.Usage
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (bif *BoolWithInverseFlag) GetEnvVars() []string {
|
||||
return bif.Sources.EnvKeys()
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (bif *BoolWithInverseFlag) GetValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (bif *BoolWithInverseFlag) TakesValue() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDefaultVisible returns true if the flag is not hidden, otherwise false
|
||||
func (bif *BoolWithInverseFlag) IsDefaultVisible() bool {
|
||||
return !bif.HideDefault
|
||||
}
|
||||
|
||||
// TypeName is used for stringify/docs. For bool its a no-op
|
||||
func (bif *BoolWithInverseFlag) TypeName() string {
|
||||
return "bool"
|
||||
}
|
||||
47
vendor/github.com/urfave/cli/v3/flag_duration.go
generated
vendored
Normal file
47
vendor/github.com/urfave/cli/v3/flag_duration.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DurationFlag = FlagBase[time.Duration, NoConfig, durationValue]
|
||||
|
||||
// -- time.Duration Value
|
||||
type durationValue time.Duration
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (d durationValue) Create(val time.Duration, p *time.Duration, c NoConfig) Value {
|
||||
*p = val
|
||||
return (*durationValue)(p)
|
||||
}
|
||||
|
||||
func (d durationValue) ToString(val time.Duration) string {
|
||||
return fmt.Sprintf("%v", val)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (d *durationValue) Set(s string) error {
|
||||
v, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = durationValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *durationValue) Get() any { return time.Duration(*d) }
|
||||
|
||||
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
|
||||
|
||||
func (cmd *Command) Duration(name string) time.Duration {
|
||||
if v, ok := cmd.Value(name).(time.Duration); ok {
|
||||
tracef("duration available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("bool NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
||||
@@ -6,11 +6,26 @@ type extFlag struct {
|
||||
f *flag.Flag
|
||||
}
|
||||
|
||||
func (e *extFlag) Apply(fs *flag.FlagSet) error {
|
||||
fs.Var(e.f.Value, e.f.Name, e.f.Usage)
|
||||
func (e *extFlag) PreParse() error {
|
||||
if e.f.DefValue != "" {
|
||||
return e.Set("", e.f.DefValue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *extFlag) PostParse() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *extFlag) Set(_ string, val string) error {
|
||||
return e.f.Value.Set(val)
|
||||
}
|
||||
|
||||
func (e *extFlag) Get() any {
|
||||
return e.f.Value.(flag.Getter).Get()
|
||||
}
|
||||
|
||||
func (e *extFlag) Names() []string {
|
||||
return []string{e.f.Name}
|
||||
}
|
||||
75
vendor/github.com/urfave/cli/v3/flag_float.go
generated
vendored
Normal file
75
vendor/github.com/urfave/cli/v3/flag_float.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
FloatFlag = FlagBase[float64, NoConfig, floatValue[float64]]
|
||||
Float32Flag = FlagBase[float32, NoConfig, floatValue[float32]]
|
||||
Float64Flag = FlagBase[float64, NoConfig, floatValue[float64]]
|
||||
)
|
||||
|
||||
// -- float Value
|
||||
type floatValue[T float32 | float64] struct {
|
||||
val *T
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (f floatValue[T]) Create(val T, p *T, c NoConfig) Value {
|
||||
*p = val
|
||||
|
||||
return &floatValue[T]{val: p}
|
||||
}
|
||||
|
||||
func (f floatValue[T]) ToString(b T) string {
|
||||
return strconv.FormatFloat(float64(b), 'g', -1, int(unsafe.Sizeof(T(0))*8))
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (f *floatValue[T]) Set(s string) error {
|
||||
v, err := strconv.ParseFloat(s, int(unsafe.Sizeof(T(0))*8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*f.val = T(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *floatValue[T]) Get() any { return *f.val }
|
||||
|
||||
func (f *floatValue[T]) String() string {
|
||||
return strconv.FormatFloat(float64(*f.val), 'g', -1, int(unsafe.Sizeof(T(0))*8))
|
||||
}
|
||||
|
||||
// Float looks up the value of a local FloatFlag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Float(name string) float64 {
|
||||
return getFloat[float64](cmd, name)
|
||||
}
|
||||
|
||||
// Float32 looks up the value of a local Float32Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Float32(name string) float32 {
|
||||
return getFloat[float32](cmd, name)
|
||||
}
|
||||
|
||||
// Float64 looks up the value of a local Float64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Float64(name string) float64 {
|
||||
return getFloat[float64](cmd, name)
|
||||
}
|
||||
|
||||
func getFloat[T float32 | float64](cmd *Command, name string) T {
|
||||
if v, ok := cmd.Value(name).(T); ok {
|
||||
tracef("float available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("float NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
||||
34
vendor/github.com/urfave/cli/v3/flag_float_slice.go
generated
vendored
Normal file
34
vendor/github.com/urfave/cli/v3/flag_float_slice.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
FloatSlice = SliceBase[float64, NoConfig, floatValue[float64]]
|
||||
Float32Slice = SliceBase[float32, NoConfig, floatValue[float32]]
|
||||
Float64Slice = SliceBase[float64, NoConfig, floatValue[float64]]
|
||||
FloatSliceFlag = FlagBase[[]float64, NoConfig, FloatSlice]
|
||||
Float32SliceFlag = FlagBase[[]float32, NoConfig, Float32Slice]
|
||||
Float64SliceFlag = FlagBase[[]float64, NoConfig, Float64Slice]
|
||||
)
|
||||
|
||||
var (
|
||||
NewFloatSlice = NewSliceBase[float64, NoConfig, floatValue[float64]]
|
||||
NewFloat32Slice = NewSliceBase[float32, NoConfig, floatValue[float32]]
|
||||
NewFloat64Slice = NewSliceBase[float64, NoConfig, floatValue[float64]]
|
||||
)
|
||||
|
||||
// FloatSlice looks up the value of a local FloatSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) FloatSlice(name string) []float64 {
|
||||
return getNumberSlice[float64](cmd, name)
|
||||
}
|
||||
|
||||
// Float32Slice looks up the value of a local Float32Slice, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Float32Slice(name string) []float32 {
|
||||
return getNumberSlice[float32](cmd, name)
|
||||
}
|
||||
|
||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Float64Slice(name string) []float64 {
|
||||
return getNumberSlice[float64](cmd, name)
|
||||
}
|
||||
67
vendor/github.com/urfave/cli/v3/flag_generic.go
generated
vendored
Normal file
67
vendor/github.com/urfave/cli/v3/flag_generic.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package cli
|
||||
|
||||
type GenericFlag = FlagBase[Value, NoConfig, genericValue]
|
||||
|
||||
// -- Value Value
|
||||
type genericValue struct {
|
||||
val Value
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (f genericValue) Create(val Value, p *Value, c NoConfig) Value {
|
||||
*p = val
|
||||
return &genericValue{
|
||||
val: *p,
|
||||
}
|
||||
}
|
||||
|
||||
func (f genericValue) ToString(b Value) string {
|
||||
if b != nil {
|
||||
return b.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (f *genericValue) Set(s string) error {
|
||||
if f.val != nil {
|
||||
return f.val.Set(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *genericValue) Get() any {
|
||||
if f.val != nil {
|
||||
return f.val.Get()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *genericValue) String() string {
|
||||
if f.val != nil {
|
||||
return f.val.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *genericValue) IsBoolFlag() bool {
|
||||
if f.val == nil {
|
||||
return false
|
||||
}
|
||||
bf, ok := f.val.(boolFlag)
|
||||
return ok && bf.IsBoolFlag()
|
||||
}
|
||||
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Generic(name string) Value {
|
||||
if v, ok := cmd.Value(name).(Value); ok {
|
||||
tracef("generic available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("generic NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
297
vendor/github.com/urfave/cli/v3/flag_impl.go
generated
vendored
Normal file
297
vendor/github.com/urfave/cli/v3/flag_impl.go
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Value represents a value as used by cli.
|
||||
// For now it implements the golang flag.Value interface
|
||||
type Value interface {
|
||||
flag.Value
|
||||
flag.Getter
|
||||
}
|
||||
|
||||
type boolFlag interface {
|
||||
IsBoolFlag() bool
|
||||
}
|
||||
|
||||
// ValueCreator is responsible for creating a flag.Value emulation
|
||||
// as well as custom formatting
|
||||
//
|
||||
// T specifies the type
|
||||
// C specifies the config for the type
|
||||
type ValueCreator[T any, C any] interface {
|
||||
Create(T, *T, C) Value
|
||||
ToString(T) string
|
||||
}
|
||||
|
||||
// NoConfig is for flags which dont need a custom configuration
|
||||
type NoConfig struct{}
|
||||
|
||||
// FlagBase [T,C,VC] is a generic flag base which can be used
|
||||
// as a boilerplate to implement the most common interfaces
|
||||
// used by urfave/cli.
|
||||
//
|
||||
// T specifies the type
|
||||
// C specifies the configuration required(if any for that flag type)
|
||||
// VC specifies the value creator which creates the flag.Value emulation
|
||||
type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
Name string `json:"name"` // name of the flag
|
||||
Category string `json:"category"` // category of the flag, if any
|
||||
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
|
||||
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
|
||||
Usage string `json:"usage"` // usage string for help output
|
||||
Sources ValueSourceChain `json:"-"` // sources to load flag value from
|
||||
Required bool `json:"required"` // whether the flag is required or not
|
||||
Hidden bool `json:"hidden"` // whether to hide the flag in help output
|
||||
Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well
|
||||
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
|
||||
Destination *T `json:"-"` // destination pointer for value when set
|
||||
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
|
||||
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
|
||||
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
|
||||
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
|
||||
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
|
||||
Validator func(T) error `json:"-"` // custom function to validate this flag value
|
||||
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
|
||||
|
||||
// unexported fields for internal use
|
||||
count int // number of times the flag has been set
|
||||
hasBeenSet bool // whether the flag has been set from env or file
|
||||
applied bool // whether the flag has been applied to a flag set already
|
||||
creator VC // value creator for this flag type
|
||||
value Value // value representing this flag's value
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *FlagBase[T, C, V]) GetValue() string {
|
||||
if !f.TakesValue() {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// TypeName returns the type of the flag.
|
||||
func (f *FlagBase[T, C, V]) TypeName() string {
|
||||
ty := reflect.TypeOf(f.Value)
|
||||
if ty == nil {
|
||||
return ""
|
||||
}
|
||||
// convert the typename to generic type
|
||||
convertToGenericType := func(name string) string {
|
||||
prefixMap := map[string]string{
|
||||
"float": "float",
|
||||
"int": "int",
|
||||
"uint": "uint",
|
||||
}
|
||||
for prefix, genericType := range prefixMap {
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
return genericType
|
||||
}
|
||||
}
|
||||
return strings.ToLower(name)
|
||||
}
|
||||
|
||||
switch ty.Kind() {
|
||||
// if it is a Slice, then return the slice's inner type. Will nested slices be used in the future?
|
||||
case reflect.Slice:
|
||||
elemType := ty.Elem()
|
||||
return convertToGenericType(elemType.Name())
|
||||
// if it is a Map, then return the map's key and value types.
|
||||
case reflect.Map:
|
||||
keyType := ty.Key()
|
||||
valueType := ty.Elem()
|
||||
return fmt.Sprintf("%s=%s", convertToGenericType(keyType.Name()), convertToGenericType(valueType.Name()))
|
||||
default:
|
||||
return convertToGenericType(ty.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// PostParse populates the flag given the flag set and environment
|
||||
func (f *FlagBase[T, C, V]) PostParse() error {
|
||||
tracef("postparse (flag=%[1]q)", f.Name)
|
||||
|
||||
if !f.hasBeenSet {
|
||||
if val, source, found := f.Sources.LookupWithSource(); found {
|
||||
if val != "" || reflect.TypeOf(f.Value).Kind() == reflect.String {
|
||||
if err := f.Set(f.Name, val); err != nil {
|
||||
return fmt.Errorf(
|
||||
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
|
||||
val, f.Value, source, f.Name, err,
|
||||
)
|
||||
}
|
||||
} else if val == "" && reflect.TypeOf(f.Value).Kind() == reflect.Bool {
|
||||
_ = f.Set(f.Name, "false")
|
||||
}
|
||||
|
||||
f.hasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FlagBase[T, C, V]) PreParse() error {
|
||||
newVal := f.Value
|
||||
|
||||
if f.Destination == nil {
|
||||
f.value = f.creator.Create(newVal, new(T), f.Config)
|
||||
} else {
|
||||
f.value = f.creator.Create(newVal, f.Destination, f.Config)
|
||||
}
|
||||
|
||||
// Validate the given default or values set from external sources as well
|
||||
if f.Validator != nil && f.ValidateDefaults {
|
||||
if err := f.Validator(f.value.Get().(T)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
f.applied = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set applies given value from string
|
||||
func (f *FlagBase[T, C, V]) Set(_ string, val string) error {
|
||||
tracef("apply (flag=%[1]q)", f.Name)
|
||||
|
||||
// TODO move this phase into a separate flag initialization function
|
||||
// if flag has been applied previously then it would have already been set
|
||||
// from env or file. So no need to apply the env set again. However
|
||||
// lots of units tests prior to persistent flags assumed that the
|
||||
// flag can be applied to different flag sets multiple times while still
|
||||
// keeping the env set.
|
||||
if !f.applied || f.Local {
|
||||
if err := f.PreParse(); err != nil {
|
||||
return err
|
||||
}
|
||||
f.applied = true
|
||||
}
|
||||
|
||||
if f.count == 1 && f.OnlyOnce {
|
||||
return fmt.Errorf("cant duplicate this flag")
|
||||
}
|
||||
|
||||
f.count++
|
||||
if err := f.value.Set(val); err != nil {
|
||||
return err
|
||||
}
|
||||
f.hasBeenSet = true
|
||||
if f.Validator != nil {
|
||||
if err := f.Validator(f.value.Get().(T)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FlagBase[T, C, V]) Get() any {
|
||||
if f.value != nil {
|
||||
return f.value.Get()
|
||||
}
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// IsDefaultVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *FlagBase[T, C, V]) IsDefaultVisible() bool {
|
||||
return !f.HideDefault
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *FlagBase[T, C, V]) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *FlagBase[T, C, V]) IsSet() bool {
|
||||
return f.hasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *FlagBase[T, C, V]) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *FlagBase[T, C, V]) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *FlagBase[T, C, V]) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// GetCategory returns the category of the flag
|
||||
func (f *FlagBase[T, C, V]) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
func (f *FlagBase[T, C, V]) SetCategory(c string) {
|
||||
f.Category = c
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *FlagBase[T, C, V]) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *FlagBase[T, C, V]) GetEnvVars() []string {
|
||||
return f.Sources.EnvKeys()
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *FlagBase[T, C, V]) TakesValue() bool {
|
||||
var t T
|
||||
return reflect.TypeOf(t) == nil || reflect.TypeOf(t).Kind() != reflect.Bool
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *FlagBase[T, C, V]) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
var v V
|
||||
return v.ToString(f.Value)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *FlagBase[T, C, V]) RunAction(ctx context.Context, cmd *Command) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(ctx, cmd, f.value.Get().(T))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsMultiValueFlag returns true if the value type T can take multiple
|
||||
// values from cmd line. This is true for slice and map type flags
|
||||
func (f *FlagBase[T, C, VC]) IsMultiValueFlag() bool {
|
||||
// TBD how to specify
|
||||
if reflect.TypeOf(f.Value) == nil {
|
||||
return false
|
||||
}
|
||||
kind := reflect.TypeOf(f.Value).Kind()
|
||||
return kind == reflect.Slice || kind == reflect.Map
|
||||
}
|
||||
|
||||
// IsLocal returns false if flag needs to be persistent across subcommands
|
||||
func (f *FlagBase[T, C, VC]) IsLocal() bool {
|
||||
return f.Local
|
||||
}
|
||||
|
||||
// IsBoolFlag returns whether the flag doesnt need to accept args
|
||||
func (f *FlagBase[T, C, VC]) IsBoolFlag() bool {
|
||||
bf, ok := f.value.(boolFlag)
|
||||
return ok && bf.IsBoolFlag()
|
||||
}
|
||||
|
||||
// Count returns the number of times this flag has been invoked
|
||||
func (f *FlagBase[T, C, VC]) Count() int {
|
||||
return f.count
|
||||
}
|
||||
107
vendor/github.com/urfave/cli/v3/flag_int.go
generated
vendored
Normal file
107
vendor/github.com/urfave/cli/v3/flag_int.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
IntFlag = FlagBase[int, IntegerConfig, intValue[int]]
|
||||
Int8Flag = FlagBase[int8, IntegerConfig, intValue[int8]]
|
||||
Int16Flag = FlagBase[int16, IntegerConfig, intValue[int16]]
|
||||
Int32Flag = FlagBase[int32, IntegerConfig, intValue[int32]]
|
||||
Int64Flag = FlagBase[int64, IntegerConfig, intValue[int64]]
|
||||
)
|
||||
|
||||
// IntegerConfig is the configuration for all integer type flags
|
||||
type IntegerConfig struct {
|
||||
Base int
|
||||
}
|
||||
|
||||
// -- int Value
|
||||
type intValue[T int | int8 | int16 | int32 | int64] struct {
|
||||
val *T
|
||||
base int
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (i intValue[T]) Create(val T, p *T, c IntegerConfig) Value {
|
||||
*p = val
|
||||
|
||||
return &intValue[T]{
|
||||
val: p,
|
||||
base: c.Base,
|
||||
}
|
||||
}
|
||||
|
||||
func (i intValue[T]) ToString(b T) string {
|
||||
if i.base == 0 {
|
||||
i.base = 10
|
||||
}
|
||||
|
||||
return strconv.FormatInt(int64(b), i.base)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (i *intValue[T]) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, i.base, int(unsafe.Sizeof(T(0))*8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i.val = T(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *intValue[T]) Get() any { return *i.val }
|
||||
|
||||
func (i *intValue[T]) String() string {
|
||||
base := i.base
|
||||
if base == 0 {
|
||||
base = 10
|
||||
}
|
||||
|
||||
return strconv.FormatInt(int64(*i.val), base)
|
||||
}
|
||||
|
||||
// Int looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int(name string) int {
|
||||
return getInt[int](cmd, name)
|
||||
}
|
||||
|
||||
// Int8 looks up the value of a local Int8Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int8(name string) int8 {
|
||||
return getInt[int8](cmd, name)
|
||||
}
|
||||
|
||||
// Int16 looks up the value of a local Int16Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int16(name string) int16 {
|
||||
return getInt[int16](cmd, name)
|
||||
}
|
||||
|
||||
// Int32 looks up the value of a local Int32Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int32(name string) int32 {
|
||||
return getInt[int32](cmd, name)
|
||||
}
|
||||
|
||||
// Int64 looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int64(name string) int64 {
|
||||
return getInt[int64](cmd, name)
|
||||
}
|
||||
|
||||
func getInt[T int | int8 | int16 | int32 | int64](cmd *Command, name string) T {
|
||||
if v, ok := cmd.Value(name).(T); ok {
|
||||
tracef("int available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("int NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
||||
52
vendor/github.com/urfave/cli/v3/flag_int_slice.go
generated
vendored
Normal file
52
vendor/github.com/urfave/cli/v3/flag_int_slice.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
IntSlice = SliceBase[int, IntegerConfig, intValue[int]]
|
||||
Int8Slice = SliceBase[int8, IntegerConfig, intValue[int8]]
|
||||
Int16Slice = SliceBase[int16, IntegerConfig, intValue[int16]]
|
||||
Int32Slice = SliceBase[int32, IntegerConfig, intValue[int32]]
|
||||
Int64Slice = SliceBase[int64, IntegerConfig, intValue[int64]]
|
||||
IntSliceFlag = FlagBase[[]int, IntegerConfig, IntSlice]
|
||||
Int8SliceFlag = FlagBase[[]int8, IntegerConfig, Int8Slice]
|
||||
Int16SliceFlag = FlagBase[[]int16, IntegerConfig, Int16Slice]
|
||||
Int32SliceFlag = FlagBase[[]int32, IntegerConfig, Int32Slice]
|
||||
Int64SliceFlag = FlagBase[[]int64, IntegerConfig, Int64Slice]
|
||||
)
|
||||
|
||||
var (
|
||||
NewIntSlice = NewSliceBase[int, IntegerConfig, intValue[int]]
|
||||
NewInt8Slice = NewSliceBase[int8, IntegerConfig, intValue[int8]]
|
||||
NewInt16Slice = NewSliceBase[int16, IntegerConfig, intValue[int16]]
|
||||
NewInt32Slice = NewSliceBase[int32, IntegerConfig, intValue[int32]]
|
||||
NewInt64Slice = NewSliceBase[int64, IntegerConfig, intValue[int64]]
|
||||
)
|
||||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) IntSlice(name string) []int {
|
||||
return getNumberSlice[int](cmd, name)
|
||||
}
|
||||
|
||||
// Int8Slice looks up the value of a local Int8SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Int8Slice(name string) []int8 {
|
||||
return getNumberSlice[int8](cmd, name)
|
||||
}
|
||||
|
||||
// Int16Slice looks up the value of a local Int16SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Int16Slice(name string) []int16 {
|
||||
return getNumberSlice[int16](cmd, name)
|
||||
}
|
||||
|
||||
// Int32Slice looks up the value of a local Int32SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Int32Slice(name string) []int32 {
|
||||
return getNumberSlice[int32](cmd, name)
|
||||
}
|
||||
|
||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Int64Slice(name string) []int64 {
|
||||
return getNumberSlice[int64](cmd, name)
|
||||
}
|
||||
112
vendor/github.com/urfave/cli/v3/flag_map_impl.go
generated
vendored
Normal file
112
vendor/github.com/urfave/cli/v3/flag_map_impl.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MapBase wraps map[string]T to satisfy flag.Value
|
||||
type MapBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
dict *map[string]T
|
||||
hasBeenSet bool
|
||||
value Value
|
||||
}
|
||||
|
||||
func (i MapBase[T, C, VC]) Create(val map[string]T, p *map[string]T, c C) Value {
|
||||
*p = map[string]T{}
|
||||
for k, v := range val {
|
||||
(*p)[k] = v
|
||||
}
|
||||
var t T
|
||||
np := new(T)
|
||||
var vc VC
|
||||
return &MapBase[T, C, VC]{
|
||||
dict: p,
|
||||
value: vc.Create(t, np, c),
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapBase makes a *MapBase with default values
|
||||
func NewMapBase[T any, C any, VC ValueCreator[T, C]](defaults map[string]T) *MapBase[T, C, VC] {
|
||||
return &MapBase[T, C, VC]{
|
||||
dict: &defaults,
|
||||
}
|
||||
}
|
||||
|
||||
// Set parses the value and appends it to the list of values
|
||||
func (i *MapBase[T, C, VC]) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
*i.dict = map[string]T{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.dict)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, item := range flagSplitMultiValues(value) {
|
||||
key, value, ok := strings.Cut(item, defaultMapFlagKeyValueSeparator)
|
||||
if !ok {
|
||||
return fmt.Errorf("item %q is missing separator %q", item, defaultMapFlagKeyValueSeparator)
|
||||
}
|
||||
if err := i.value.Set(value); err != nil {
|
||||
return err
|
||||
}
|
||||
(*i.dict)[key] = i.value.Get().(T)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *MapBase[T, C, VC]) String() string {
|
||||
v := i.Value()
|
||||
var t T
|
||||
if reflect.TypeOf(t).Kind() == reflect.String {
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
return fmt.Sprintf("%T{%s}", v, i.ToString(v))
|
||||
}
|
||||
|
||||
// Serialize allows MapBase to fulfill Serializer
|
||||
func (i *MapBase[T, C, VC]) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.dict)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the mapping of values set by this flag
|
||||
func (i *MapBase[T, C, VC]) Value() map[string]T {
|
||||
if i.dict == nil {
|
||||
return map[string]T{}
|
||||
}
|
||||
return *i.dict
|
||||
}
|
||||
|
||||
// Get returns the mapping of values set by this flag
|
||||
func (i *MapBase[T, C, VC]) Get() interface{} {
|
||||
return *i.dict
|
||||
}
|
||||
|
||||
func (i MapBase[T, C, VC]) ToString(t map[string]T) string {
|
||||
var defaultVals []string
|
||||
var vc VC
|
||||
for _, k := range sortedKeys(t) {
|
||||
defaultVals = append(defaultVals, k+defaultMapFlagKeyValueSeparator+vc.ToString(t[k]))
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
func sortedKeys[T any](dict map[string]T) []string {
|
||||
keys := make([]string, 0, len(dict))
|
||||
for k := range dict {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
54
vendor/github.com/urfave/cli/v3/flag_mutex.go
generated
vendored
Normal file
54
vendor/github.com/urfave/cli/v3/flag_mutex.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package cli
|
||||
|
||||
// MutuallyExclusiveFlags defines a mutually exclusive flag group
|
||||
// Multiple option paths can be provided out of which
|
||||
// only one can be defined on cmdline
|
||||
// So for example
|
||||
// [ --foo | [ --bar something --darth somethingelse ] ]
|
||||
type MutuallyExclusiveFlags struct {
|
||||
// Flag list
|
||||
Flags [][]Flag
|
||||
|
||||
// whether this group is required
|
||||
Required bool
|
||||
|
||||
// Category to apply to all flags within group
|
||||
Category string
|
||||
}
|
||||
|
||||
func (grp MutuallyExclusiveFlags) check(_ *Command) error {
|
||||
oneSet := false
|
||||
e := &mutuallyExclusiveGroup{}
|
||||
|
||||
for _, grpf := range grp.Flags {
|
||||
for _, f := range grpf {
|
||||
if f.IsSet() {
|
||||
if oneSet {
|
||||
e.flag2Name = f.Names()[0]
|
||||
return e
|
||||
}
|
||||
e.flag1Name = f.Names()[0]
|
||||
oneSet = true
|
||||
break
|
||||
}
|
||||
if oneSet {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !oneSet && grp.Required {
|
||||
return &mutuallyExclusiveGroupRequiredFlag{flags: &grp}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (grp MutuallyExclusiveFlags) propagateCategory() {
|
||||
for _, grpf := range grp.Flags {
|
||||
for _, f := range grpf {
|
||||
if cf, ok := f.(CategorizableFlag); ok {
|
||||
cf.SetCategory(grp.Category)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
vendor/github.com/urfave/cli/v3/flag_number_slice.go
generated
vendored
Normal file
15
vendor/github.com/urfave/cli/v3/flag_number_slice.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cli
|
||||
|
||||
type numberType interface {
|
||||
int | int8 | int16 | int32 | int64 | float32 | float64
|
||||
}
|
||||
|
||||
func getNumberSlice[T numberType](cmd *Command, name string) []T {
|
||||
if v, ok := cmd.Value(name).([]T); ok {
|
||||
tracef("%T slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", *new(T), name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("%T slice NOT available for flag name %[1]q (cmd=%[2]q)", *new(T), name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
96
vendor/github.com/urfave/cli/v3/flag_slice_base.go
generated
vendored
Normal file
96
vendor/github.com/urfave/cli/v3/flag_slice_base.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SliceBase wraps []T to satisfy flag.Value
|
||||
type SliceBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
slice *[]T
|
||||
hasBeenSet bool
|
||||
value Value
|
||||
}
|
||||
|
||||
func (i SliceBase[T, C, VC]) Create(val []T, p *[]T, c C) Value {
|
||||
*p = []T{}
|
||||
*p = append(*p, val...)
|
||||
var t T
|
||||
np := new(T)
|
||||
var vc VC
|
||||
return &SliceBase[T, C, VC]{
|
||||
slice: p,
|
||||
value: vc.Create(t, np, c),
|
||||
}
|
||||
}
|
||||
|
||||
// NewSliceBase makes a *SliceBase with default values
|
||||
func NewSliceBase[T any, C any, VC ValueCreator[T, C]](defaults ...T) *SliceBase[T, C, VC] {
|
||||
return &SliceBase[T, C, VC]{
|
||||
slice: &defaults,
|
||||
}
|
||||
}
|
||||
|
||||
// Set parses the value and appends it to the list of values
|
||||
func (i *SliceBase[T, C, VC]) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
*i.slice = []T{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
if err := i.value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return err
|
||||
}
|
||||
*i.slice = append(*i.slice, i.value.Get().(T))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *SliceBase[T, C, VC]) String() string {
|
||||
v := i.Value()
|
||||
var t T
|
||||
if reflect.TypeOf(t).Kind() == reflect.String {
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
return fmt.Sprintf("%T{%s}", v, i.ToString(v))
|
||||
}
|
||||
|
||||
// Serialize allows SliceBase to fulfill Serializer
|
||||
func (i *SliceBase[T, C, VC]) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of values set by this flag
|
||||
func (i *SliceBase[T, C, VC]) Value() []T {
|
||||
if i.slice == nil {
|
||||
return nil
|
||||
}
|
||||
return *i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of values set by this flag
|
||||
func (i *SliceBase[T, C, VC]) Get() interface{} {
|
||||
return *i.slice
|
||||
}
|
||||
|
||||
func (i SliceBase[T, C, VC]) ToString(t []T) string {
|
||||
var defaultVals []string
|
||||
var v VC
|
||||
for _, s := range t {
|
||||
defaultVals = append(defaultVals, v.ToString(s))
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
66
vendor/github.com/urfave/cli/v3/flag_string.go
generated
vendored
Normal file
66
vendor/github.com/urfave/cli/v3/flag_string.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StringFlag = FlagBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringConfig defines the configuration for string flags
|
||||
type StringConfig struct {
|
||||
// Whether to trim whitespace of parsed value
|
||||
TrimSpace bool
|
||||
}
|
||||
|
||||
// -- string Value
|
||||
type stringValue struct {
|
||||
destination *string
|
||||
trimSpace bool
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (s stringValue) Create(val string, p *string, c StringConfig) Value {
|
||||
*p = val
|
||||
return &stringValue{
|
||||
destination: p,
|
||||
trimSpace: c.TrimSpace,
|
||||
}
|
||||
}
|
||||
|
||||
func (s stringValue) ToString(val string) string {
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (s *stringValue) Set(val string) error {
|
||||
if s.trimSpace {
|
||||
val = strings.TrimSpace(val)
|
||||
}
|
||||
*s.destination = val
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringValue) Get() any { return *s.destination }
|
||||
|
||||
func (s *stringValue) String() string {
|
||||
if s.destination != nil {
|
||||
return *s.destination
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (cmd *Command) String(name string) string {
|
||||
if v, ok := cmd.Value(name).(string); ok {
|
||||
tracef("string available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return ""
|
||||
}
|
||||
20
vendor/github.com/urfave/cli/v3/flag_string_map.go
generated
vendored
Normal file
20
vendor/github.com/urfave/cli/v3/flag_string_map.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
StringMap = MapBase[string, StringConfig, stringValue]
|
||||
StringMapFlag = FlagBase[map[string]string, StringConfig, StringMap]
|
||||
)
|
||||
|
||||
var NewStringMap = NewMapBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringMap looks up the value of a local StringMapFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) StringMap(name string) map[string]string {
|
||||
if v, ok := cmd.Value(name).(map[string]string); ok {
|
||||
tracef("string map available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string map NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
20
vendor/github.com/urfave/cli/v3/flag_string_slice.go
generated
vendored
Normal file
20
vendor/github.com/urfave/cli/v3/flag_string_slice.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
StringSlice = SliceBase[string, StringConfig, stringValue]
|
||||
StringSliceFlag = FlagBase[[]string, StringConfig, StringSlice]
|
||||
)
|
||||
|
||||
var NewStringSlice = NewSliceBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) StringSlice(name string) []string {
|
||||
if v, ok := cmd.Value(name).([]string); ok {
|
||||
tracef("string slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
142
vendor/github.com/urfave/cli/v3/flag_timestamp.go
generated
vendored
Normal file
142
vendor/github.com/urfave/cli/v3/flag_timestamp.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TimestampFlag = FlagBase[time.Time, TimestampConfig, timestampValue]
|
||||
|
||||
// TimestampConfig defines the config for timestamp flags
|
||||
type TimestampConfig struct {
|
||||
Timezone *time.Location
|
||||
// Available layouts for flag value.
|
||||
//
|
||||
// Note that value for formats with missing year/date will be interpreted as current year/date respectively.
|
||||
//
|
||||
// Read more about time layouts: https://pkg.go.dev/time#pkg-constants
|
||||
Layouts []string
|
||||
}
|
||||
|
||||
// timestampValue wrap to satisfy golang's flag interface.
|
||||
type timestampValue struct {
|
||||
timestamp *time.Time
|
||||
hasBeenSet bool
|
||||
layouts []string
|
||||
location *time.Location
|
||||
}
|
||||
|
||||
var _ ValueCreator[time.Time, TimestampConfig] = timestampValue{}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (t timestampValue) Create(val time.Time, p *time.Time, c TimestampConfig) Value {
|
||||
*p = val
|
||||
return ×tampValue{
|
||||
timestamp: p,
|
||||
layouts: c.Layouts,
|
||||
location: c.Timezone,
|
||||
}
|
||||
}
|
||||
|
||||
func (t timestampValue) ToString(b time.Time) string {
|
||||
if b.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%v", b)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the Value interface
|
||||
|
||||
// Parses the string value to timestamp
|
||||
func (t *timestampValue) Set(value string) error {
|
||||
var timestamp time.Time
|
||||
var err error
|
||||
|
||||
if t.location == nil {
|
||||
t.location = time.UTC
|
||||
}
|
||||
|
||||
if len(t.layouts) == 0 {
|
||||
return errors.New("got nil/empty layouts slice")
|
||||
}
|
||||
|
||||
for _, layout := range t.layouts {
|
||||
var locErr error
|
||||
|
||||
timestamp, locErr = time.ParseInLocation(layout, value, t.location)
|
||||
if locErr != nil {
|
||||
if err == nil {
|
||||
err = locErr
|
||||
continue
|
||||
}
|
||||
|
||||
err = newMultiError(err, locErr)
|
||||
continue
|
||||
}
|
||||
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaultTS, _ := time.ParseInLocation(time.TimeOnly, time.TimeOnly, timestamp.Location())
|
||||
|
||||
n := time.Now().In(timestamp.Location())
|
||||
|
||||
// If format is missing date (or year only), set it explicitly to current
|
||||
if timestamp.Truncate(time.Hour*24).UnixNano() == defaultTS.Truncate(time.Hour*24).UnixNano() {
|
||||
timestamp = time.Date(
|
||||
n.Year(),
|
||||
n.Month(),
|
||||
n.Day(),
|
||||
timestamp.Hour(),
|
||||
timestamp.Minute(),
|
||||
timestamp.Second(),
|
||||
timestamp.Nanosecond(),
|
||||
timestamp.Location(),
|
||||
)
|
||||
} else if timestamp.Year() == 0 {
|
||||
timestamp = time.Date(
|
||||
n.Year(),
|
||||
timestamp.Month(),
|
||||
timestamp.Day(),
|
||||
timestamp.Hour(),
|
||||
timestamp.Minute(),
|
||||
timestamp.Second(),
|
||||
timestamp.Nanosecond(),
|
||||
timestamp.Location(),
|
||||
)
|
||||
}
|
||||
|
||||
if t.timestamp != nil {
|
||||
*t.timestamp = timestamp
|
||||
}
|
||||
t.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (t *timestampValue) String() string {
|
||||
return fmt.Sprintf("%#v", t.timestamp)
|
||||
}
|
||||
|
||||
// Get returns the flag structure
|
||||
func (t *timestampValue) Get() any {
|
||||
return *t.timestamp
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (cmd *Command) Timestamp(name string) time.Time {
|
||||
if v, ok := cmd.Value(name).(time.Time); ok {
|
||||
tracef("time.Time available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("time.Time NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return time.Time{}
|
||||
}
|
||||
103
vendor/github.com/urfave/cli/v3/flag_uint.go
generated
vendored
Normal file
103
vendor/github.com/urfave/cli/v3/flag_uint.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
UintFlag = FlagBase[uint, IntegerConfig, uintValue[uint]]
|
||||
Uint8Flag = FlagBase[uint8, IntegerConfig, uintValue[uint8]]
|
||||
Uint16Flag = FlagBase[uint16, IntegerConfig, uintValue[uint16]]
|
||||
Uint32Flag = FlagBase[uint32, IntegerConfig, uintValue[uint32]]
|
||||
Uint64Flag = FlagBase[uint64, IntegerConfig, uintValue[uint64]]
|
||||
)
|
||||
|
||||
// -- uint Value
|
||||
type uintValue[T uint | uint8 | uint16 | uint32 | uint64] struct {
|
||||
val *T
|
||||
base int
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (i uintValue[T]) Create(val T, p *T, c IntegerConfig) Value {
|
||||
*p = val
|
||||
|
||||
return &uintValue[T]{
|
||||
val: p,
|
||||
base: c.Base,
|
||||
}
|
||||
}
|
||||
|
||||
func (i uintValue[T]) ToString(b T) string {
|
||||
base := i.base
|
||||
if base == 0 {
|
||||
base = 10
|
||||
}
|
||||
|
||||
return strconv.FormatUint(uint64(b), base)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (i *uintValue[T]) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, i.base, int(unsafe.Sizeof(T(0))*8))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i.val = T(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uintValue[T]) Get() any { return *i.val }
|
||||
|
||||
func (i *uintValue[T]) String() string {
|
||||
base := i.base
|
||||
if base == 0 {
|
||||
base = 10
|
||||
}
|
||||
|
||||
return strconv.FormatUint(uint64(*i.val), base)
|
||||
}
|
||||
|
||||
// Uint looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint(name string) uint {
|
||||
return getUint[uint](cmd, name)
|
||||
}
|
||||
|
||||
// Uint8 looks up the value of a local Uint8Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint8(name string) uint8 {
|
||||
return getUint[uint8](cmd, name)
|
||||
}
|
||||
|
||||
// Uint16 looks up the value of a local Uint16Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint16(name string) uint16 {
|
||||
return getUint[uint16](cmd, name)
|
||||
}
|
||||
|
||||
// Uint32 looks up the value of a local Uint32Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint32(name string) uint32 {
|
||||
return getUint[uint32](cmd, name)
|
||||
}
|
||||
|
||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint64(name string) uint64 {
|
||||
return getUint[uint64](cmd, name)
|
||||
}
|
||||
|
||||
func getUint[T uint | uint8 | uint16 | uint32 | uint64](cmd *Command, name string) T {
|
||||
if v, ok := cmd.Value(name).(T); ok {
|
||||
tracef("uint available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("uint NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
||||
63
vendor/github.com/urfave/cli/v3/flag_uint_slice.go
generated
vendored
Normal file
63
vendor/github.com/urfave/cli/v3/flag_uint_slice.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
UintSlice = SliceBase[uint, IntegerConfig, uintValue[uint]]
|
||||
Uint8Slice = SliceBase[uint8, IntegerConfig, uintValue[uint8]]
|
||||
Uint16Slice = SliceBase[uint16, IntegerConfig, uintValue[uint16]]
|
||||
Uint32Slice = SliceBase[uint32, IntegerConfig, uintValue[uint32]]
|
||||
Uint64Slice = SliceBase[uint64, IntegerConfig, uintValue[uint64]]
|
||||
UintSliceFlag = FlagBase[[]uint, IntegerConfig, UintSlice]
|
||||
Uint8SliceFlag = FlagBase[[]uint8, IntegerConfig, Uint8Slice]
|
||||
Uint16SliceFlag = FlagBase[[]uint16, IntegerConfig, Uint16Slice]
|
||||
Uint32SliceFlag = FlagBase[[]uint32, IntegerConfig, Uint32Slice]
|
||||
Uint64SliceFlag = FlagBase[[]uint64, IntegerConfig, Uint64Slice]
|
||||
)
|
||||
|
||||
var (
|
||||
NewUintSlice = NewSliceBase[uint, IntegerConfig, uintValue[uint]]
|
||||
NewUint8Slice = NewSliceBase[uint8, IntegerConfig, uintValue[uint8]]
|
||||
NewUint16Slice = NewSliceBase[uint16, IntegerConfig, uintValue[uint16]]
|
||||
NewUint32Slice = NewSliceBase[uint32, IntegerConfig, uintValue[uint32]]
|
||||
NewUint64Slice = NewSliceBase[uint64, IntegerConfig, uintValue[uint64]]
|
||||
)
|
||||
|
||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) UintSlice(name string) []uint {
|
||||
return getUintSlice[uint](cmd, name)
|
||||
}
|
||||
|
||||
// Uint8Slice looks up the value of a local Uint8SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Uint8Slice(name string) []uint8 {
|
||||
return getUintSlice[uint8](cmd, name)
|
||||
}
|
||||
|
||||
// Uint16Slice looks up the value of a local Uint16SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Uint16Slice(name string) []uint16 {
|
||||
return getUintSlice[uint16](cmd, name)
|
||||
}
|
||||
|
||||
// Uint32Slice looks up the value of a local Uint32SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Uint32Slice(name string) []uint32 {
|
||||
return getUintSlice[uint32](cmd, name)
|
||||
}
|
||||
|
||||
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) Uint64Slice(name string) []uint64 {
|
||||
return getUintSlice[uint64](cmd, name)
|
||||
}
|
||||
|
||||
func getUintSlice[T uint | uint8 | uint16 | uint32 | uint64](cmd *Command, name string) []T {
|
||||
if v, ok := cmd.Value(name).([]T); ok {
|
||||
tracef("uint slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("uint slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
||||
32
vendor/github.com/urfave/cli/v2/funcs.go → vendor/github.com/urfave/cli/v3/funcs.go
generated
vendored
32
vendor/github.com/urfave/cli/v2/funcs.go → vendor/github.com/urfave/cli/v3/funcs.go
generated
vendored
@@ -1,34 +1,40 @@
|
||||
package cli
|
||||
|
||||
// BashCompleteFunc is an action to execute when the shell completion flag is set
|
||||
type BashCompleteFunc func(*Context)
|
||||
import "context"
|
||||
|
||||
// BeforeFunc is an action to execute before any subcommands are run, but after
|
||||
// the context is ready if a non-nil error is returned, no subcommands are run
|
||||
type BeforeFunc func(*Context) error
|
||||
// ShellCompleteFunc is an action to execute when the shell completion flag is set
|
||||
type ShellCompleteFunc func(context.Context, *Command)
|
||||
|
||||
// AfterFunc is an action to execute after any subcommands are run, but after the
|
||||
// subcommand has finished it is run even if Action() panics
|
||||
type AfterFunc func(*Context) error
|
||||
// BeforeFunc is an action that executes prior to any subcommands being run once
|
||||
// the context is ready. If a non-nil error is returned, no subcommands are
|
||||
// run.
|
||||
type BeforeFunc func(context.Context, *Command) (context.Context, error)
|
||||
|
||||
// AfterFunc is an action that executes after any subcommands are run and have
|
||||
// finished. The AfterFunc is run even if Action() panics.
|
||||
type AfterFunc func(context.Context, *Command) error
|
||||
|
||||
// ActionFunc is the action to execute when no subcommands are specified
|
||||
type ActionFunc func(*Context) error
|
||||
type ActionFunc func(context.Context, *Command) error
|
||||
|
||||
// CommandNotFoundFunc is executed if the proper command cannot be found
|
||||
type CommandNotFoundFunc func(*Context, string)
|
||||
type CommandNotFoundFunc func(context.Context, *Command, string)
|
||||
|
||||
// ConfigureShellCompletionCommand is a function to configure a shell completion command
|
||||
type ConfigureShellCompletionCommand func(*Command)
|
||||
|
||||
// OnUsageErrorFunc is executed if a usage error occurs. This is useful for displaying
|
||||
// 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(cCtx *Context, err error, isSubcommand bool) error
|
||||
type OnUsageErrorFunc func(ctx context.Context, cmd *Command, err error, isSubcommand bool) error
|
||||
|
||||
// InvalidFlagAccessFunc is executed when an invalid flag is accessed from the context.
|
||||
type InvalidFlagAccessFunc func(*Context, string)
|
||||
type InvalidFlagAccessFunc func(context.Context, *Command, string)
|
||||
|
||||
// ExitErrHandlerFunc is executed if provided in order to handle exitError values
|
||||
// returned by Actions and Before/After functions.
|
||||
type ExitErrHandlerFunc func(cCtx *Context, err error)
|
||||
type ExitErrHandlerFunc func(context.Context, *Command, error)
|
||||
|
||||
// FlagStringFunc is used by the help generation to display a flag, which is
|
||||
// expected to be a single line.
|
||||
1443
vendor/github.com/urfave/cli/v3/godoc-current.txt
generated
vendored
Normal file
1443
vendor/github.com/urfave/cli/v3/godoc-current.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
600
vendor/github.com/urfave/cli/v3/help.go
generated
vendored
Normal file
600
vendor/github.com/urfave/cli/v3/help.go
generated
vendored
Normal file
@@ -0,0 +1,600 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
helpName = "help"
|
||||
helpAlias = "h"
|
||||
)
|
||||
|
||||
// Prints help for the App or Command
|
||||
type helpPrinter func(w io.Writer, templ string, data interface{})
|
||||
|
||||
// Prints help for the App or Command with custom template function.
|
||||
type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
|
||||
|
||||
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
||||
// this calls HelpPrinterCustom using only the default template functions.
|
||||
//
|
||||
// If custom logic for printing help is required, this function can be
|
||||
// overridden. If the ExtraInfo field is defined on an App, this function
|
||||
// should not be modified, as HelpPrinterCustom will be used directly in order
|
||||
// to capture the extra information.
|
||||
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
|
||||
var VersionPrinter = printVersion
|
||||
|
||||
func buildHelpCommand(withAction bool) *Command {
|
||||
cmd := &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
HideHelp: true,
|
||||
}
|
||||
|
||||
if withAction {
|
||||
cmd.Action = helpCommandAction
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func helpCommandAction(ctx context.Context, cmd *Command) error {
|
||||
args := cmd.Args()
|
||||
firstArg := args.First()
|
||||
|
||||
tracef("doing help for cmd %[1]q with args %[2]q", cmd, args)
|
||||
|
||||
// This action can be triggered by a "default" action of a command
|
||||
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||
//
|
||||
// 1 $ app
|
||||
// 2 $ app help
|
||||
// 3 $ app foo
|
||||
// 4 $ app help foo
|
||||
// 5 $ app foo help
|
||||
|
||||
// Case 4. when executing a help command set the context to parent
|
||||
// to allow resolution of subsequent args. This will transform
|
||||
// $ app help foo
|
||||
// to
|
||||
// $ app foo
|
||||
// which will then be handled as case 3
|
||||
if cmd.parent != nil && (cmd.HasName(helpName) || cmd.HasName(helpAlias)) {
|
||||
tracef("setting cmd to cmd.parent")
|
||||
cmd = cmd.parent
|
||||
}
|
||||
|
||||
// Case 4. $ app help foo
|
||||
// foo is the command for which help needs to be shown
|
||||
if firstArg != "" {
|
||||
/* if firstArg == "--" {
|
||||
return nil
|
||||
}*/
|
||||
tracef("returning ShowCommandHelp with %[1]q", firstArg)
|
||||
return ShowCommandHelp(ctx, cmd, firstArg)
|
||||
}
|
||||
|
||||
// Case 1 & 2
|
||||
// Special case when running help on main app itself as opposed to individual
|
||||
// commands/subcommands
|
||||
if cmd.parent == nil {
|
||||
tracef("returning ShowAppHelp")
|
||||
_ = ShowAppHelp(cmd)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 3, 5
|
||||
if (len(cmd.Commands) == 1 && !cmd.HideHelp) ||
|
||||
(len(cmd.Commands) == 0 && cmd.HideHelp) {
|
||||
|
||||
tmpl := cmd.CustomHelpTemplate
|
||||
if tmpl == "" {
|
||||
tmpl = CommandHelpTemplate
|
||||
}
|
||||
|
||||
tracef("running HelpPrinter with command %[1]q", cmd.Name)
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, cmd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("running ShowSubcommandHelp")
|
||||
return ShowSubcommandHelp(cmd)
|
||||
}
|
||||
|
||||
// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
|
||||
func ShowAppHelpAndExit(cmd *Command, exitCode int) {
|
||||
_ = ShowAppHelp(cmd)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowAppHelp is an action that displays the help.
|
||||
func ShowAppHelp(cmd *Command) error {
|
||||
tmpl := cmd.CustomRootCommandHelpTemplate
|
||||
if tmpl == "" {
|
||||
tracef("using RootCommandHelpTemplate")
|
||||
tmpl = RootCommandHelpTemplate
|
||||
}
|
||||
|
||||
if cmd.ExtraInfo == nil {
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, cmd.Root())
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("setting ExtraInfo in customAppData")
|
||||
customAppData := func() map[string]any {
|
||||
return map[string]any{
|
||||
"ExtraInfo": cmd.ExtraInfo,
|
||||
}
|
||||
}
|
||||
HelpPrinterCustom(cmd.Root().Writer, tmpl, cmd.Root(), customAppData())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
||||
func DefaultAppComplete(ctx context.Context, cmd *Command) {
|
||||
DefaultCompleteWithFlags(ctx, cmd)
|
||||
}
|
||||
|
||||
func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
|
||||
_, _ = fmt.Fprintf(writer, "%s:%s\n", command.Name, command.Usage)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(writer, "%s\n", command.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cliArgContains(flagName string, args []string) bool {
|
||||
for _, name := range strings.Split(flagName, ",") {
|
||||
name = strings.TrimSpace(name)
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
for _, a := range args {
|
||||
if a == flag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
|
||||
// Trim to handle both "-short" and "--long" flags.
|
||||
cur := strings.TrimLeft(lastArg, "-")
|
||||
for _, flag := range flags {
|
||||
if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
usage := ""
|
||||
if docFlag, ok := flag.(DocGenerationFlag); ok {
|
||||
usage = docFlag.GetUsage()
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(flag.Names()[0])
|
||||
// this will get total count utf8 letters in flag name
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2 // reuse this count to generate single - or -- in flag completion
|
||||
}
|
||||
// if flag name has more than one utf8 letter and last argument in cli has -- prefix then
|
||||
// skip flag completion for short flags example -v or -x
|
||||
if strings.HasPrefix(lastArg, "--") && count == 1 {
|
||||
continue
|
||||
}
|
||||
// match if last argument matches this flag and it is not repeated
|
||||
if strings.HasPrefix(name, cur) && cur != name /* && !cliArgContains(name, os.Args)*/ {
|
||||
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
if usage != "" && strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
|
||||
flagCompletion = fmt.Sprintf("%s:%s", flagCompletion, usage)
|
||||
}
|
||||
fmt.Fprintln(writer, flagCompletion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultCompleteWithFlags(ctx context.Context, cmd *Command) {
|
||||
args := os.Args
|
||||
if cmd != nil && cmd.parent != nil {
|
||||
args = cmd.Args().Slice()
|
||||
tracef("running default complete with flags[%v] on command %[2]q", args, cmd.Name)
|
||||
} else {
|
||||
tracef("running default complete with os.Args flags[%v]", args)
|
||||
}
|
||||
argsLen := len(args)
|
||||
lastArg := ""
|
||||
// parent command will have --generate-shell-completion so we need
|
||||
// to account for that
|
||||
if argsLen > 1 {
|
||||
lastArg = args[argsLen-2]
|
||||
} else if argsLen > 0 {
|
||||
lastArg = args[argsLen-1]
|
||||
}
|
||||
|
||||
if lastArg == "--" {
|
||||
tracef("No completions due to termination")
|
||||
return
|
||||
}
|
||||
|
||||
if lastArg == completionFlag {
|
||||
lastArg = ""
|
||||
}
|
||||
|
||||
if strings.HasPrefix(lastArg, "-") {
|
||||
tracef("printing flag suggestion for flag[%v] on command %[1]q", lastArg, cmd.Name)
|
||||
printFlagSuggestions(lastArg, cmd.Flags, cmd.Root().Writer)
|
||||
return
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
tracef("printing command suggestions on command %[1]q", cmd.Name)
|
||||
printCommandSuggestions(cmd.Commands, cmd.Root().Writer)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandHelpAndExit - exits with code after showing help
|
||||
func ShowCommandHelpAndExit(ctx context.Context, cmd *Command, command string, code int) {
|
||||
_ = ShowCommandHelp(ctx, cmd, command)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ShowCommandHelp prints help for the given command
|
||||
func ShowCommandHelp(ctx context.Context, cmd *Command, commandName string) error {
|
||||
for _, subCmd := range cmd.Commands {
|
||||
if !subCmd.HasName(commandName) {
|
||||
continue
|
||||
}
|
||||
|
||||
tmpl := subCmd.CustomHelpTemplate
|
||||
if tmpl == "" {
|
||||
if len(subCmd.Commands) == 0 {
|
||||
tracef("using CommandHelpTemplate")
|
||||
tmpl = CommandHelpTemplate
|
||||
} else {
|
||||
tracef("using SubcommandHelpTemplate")
|
||||
tmpl = SubcommandHelpTemplate
|
||||
}
|
||||
}
|
||||
|
||||
tracef("running HelpPrinter")
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, subCmd)
|
||||
|
||||
tracef("returning nil after printing help")
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("no matching command found")
|
||||
|
||||
if cmd.CommandNotFound == nil {
|
||||
errMsg := fmt.Sprintf("No help topic for '%v'", commandName)
|
||||
|
||||
if cmd.Suggest {
|
||||
if suggestion := SuggestCommand(cmd.Commands, commandName); suggestion != "" {
|
||||
errMsg += ". " + suggestion
|
||||
}
|
||||
}
|
||||
|
||||
tracef("exiting 3 with errMsg %[1]q", errMsg)
|
||||
return Exit(errMsg, 3)
|
||||
}
|
||||
|
||||
tracef("running CommandNotFound func for %[1]q", commandName)
|
||||
cmd.CommandNotFound(ctx, cmd, commandName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||
func ShowSubcommandHelpAndExit(cmd *Command, exitCode int) {
|
||||
_ = ShowSubcommandHelp(cmd)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowSubcommandHelp prints help for the given subcommand
|
||||
func ShowSubcommandHelp(cmd *Command) error {
|
||||
HelpPrinter(cmd.Root().Writer, SubcommandHelpTemplate, cmd)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowVersion prints the version number of the App
|
||||
func ShowVersion(cmd *Command) {
|
||||
tracef("showing version via VersionPrinter (cmd=%[1]q)", cmd.Name)
|
||||
VersionPrinter(cmd)
|
||||
}
|
||||
|
||||
func printVersion(cmd *Command) {
|
||||
_, _ = fmt.Fprintf(cmd.Root().Writer, "%v version %v\n", cmd.Name, cmd.Version)
|
||||
}
|
||||
|
||||
func handleTemplateError(err error) {
|
||||
if err != nil {
|
||||
tracef("error encountered during template parse: %[1]v", err)
|
||||
// If the writer is closed, t.Execute will fail, and there's nothing
|
||||
// we can do to recover.
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// printHelpCustom is the default implementation of HelpPrinterCustom.
|
||||
//
|
||||
// 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
|
||||
|
||||
tracef("building default funcMap")
|
||||
funcMap := template.FuncMap{
|
||||
"join": strings.Join,
|
||||
"subtract": subtract,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
|
||||
"offset": offset,
|
||||
"offsetCommands": offsetCommands,
|
||||
}
|
||||
|
||||
if wa, ok := customFuncs["wrapAt"]; ok {
|
||||
if wrapAtFunc, ok := wa.(func() int); ok {
|
||||
wrapAt := wrapAtFunc()
|
||||
customFuncs["wrap"] = func(input string, offset int) string {
|
||||
return wrap(input, offset, wrapAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range customFuncs {
|
||||
funcMap[key] = value
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||
|
||||
if _, err := t.New("helpNameTemplate").Parse(helpNameTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("argsTemplate").Parse(argsTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("usageTemplate").Parse(usageTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("descriptionTemplate").Parse(descriptionTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleCommandTemplate").Parse(visibleCommandTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("copyrightTemplate").Parse(copyrightTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("versionTemplate").Parse(versionTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleFlagTemplate").Parse(visibleFlagTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visiblePersistentFlagTemplate").Parse(visiblePersistentFlagTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.ReplaceAll(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS")); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("authorsTemplate").Parse(authorsTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
tracef("executing template")
|
||||
handleTemplateError(t.Execute(w, data))
|
||||
|
||||
_ = w.Flush()
|
||||
}
|
||||
|
||||
func printHelp(out io.Writer, templ string, data interface{}) {
|
||||
HelpPrinterCustom(out, templ, data, nil)
|
||||
}
|
||||
|
||||
func checkVersion(cmd *Command) bool {
|
||||
found := false
|
||||
for _, name := range VersionFlag.Names() {
|
||||
if cmd.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func checkShellCompleteFlag(c *Command, arguments []string) (bool, []string) {
|
||||
if (c.parent == nil && !c.EnableShellCompletion) || (c.parent != nil && !c.Root().shellCompletion) {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
pos := len(arguments) - 1
|
||||
lastArg := arguments[pos]
|
||||
|
||||
if lastArg != completionFlag {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
for _, arg := range arguments {
|
||||
// If arguments include "--", shell completion is disabled
|
||||
// because after "--" only positional arguments are accepted.
|
||||
// https://unix.stackexchange.com/a/11382
|
||||
if arg == "--" {
|
||||
return false, arguments[:pos]
|
||||
}
|
||||
}
|
||||
|
||||
return true, arguments[:pos]
|
||||
}
|
||||
|
||||
func checkCompletions(ctx context.Context, cmd *Command) bool {
|
||||
tracef("checking completions on command %[1]q", cmd.Name)
|
||||
|
||||
if !cmd.Root().shellCompletion {
|
||||
tracef("completion not enabled skipping %[1]q", cmd.Name)
|
||||
return false
|
||||
}
|
||||
|
||||
if argsArguments := cmd.Args(); argsArguments.Present() {
|
||||
name := argsArguments.First()
|
||||
if cmd := cmd.Command(name); cmd != nil {
|
||||
// let the command handle the completion
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
tracef("no subcommand found for completion %[1]q", cmd.Name)
|
||||
|
||||
if cmd.ShellComplete != nil {
|
||||
tracef("running shell completion func for command %[1]q", cmd.Name)
|
||||
cmd.ShellComplete(ctx, cmd)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func indent(spaces int, v string) string {
|
||||
pad := strings.Repeat(" ", spaces)
|
||||
return pad + strings.ReplaceAll(v, "\n", "\n"+pad)
|
||||
}
|
||||
|
||||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func wrap(input string, offset int, wrapAt int) string {
|
||||
var ss []string
|
||||
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
padding := strings.Repeat(" ", offset)
|
||||
|
||||
for i, line := range lines {
|
||||
if line == "" {
|
||||
ss = append(ss, line)
|
||||
} else {
|
||||
wrapped := wrapLine(line, offset, wrapAt, padding)
|
||||
if i == 0 {
|
||||
ss = append(ss, wrapped)
|
||||
} else {
|
||||
ss = append(ss, padding+wrapped)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(ss, "\n")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// this function tries to find the max width of the names column
|
||||
// so say we have the following rows for help
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// We want to offset the 2nd row usage by some amount so that everything
|
||||
// is aligned
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// to find that offset we find the length of all the rows and use the max
|
||||
// to calculate the offset
|
||||
func offsetCommands(cmds []*Command, fixed int) int {
|
||||
max := 0
|
||||
for _, cmd := range cmds {
|
||||
s := strings.Join(cmd.Names(), ", ")
|
||||
if len(s) > max {
|
||||
max = len(s)
|
||||
}
|
||||
}
|
||||
return max + fixed
|
||||
}
|
||||
5
vendor/github.com/urfave/cli/v3/mkdocs-reqs.txt
generated
vendored
Normal file
5
vendor/github.com/urfave/cli/v3/mkdocs-reqs.txt
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
mkdocs-git-revision-date-localized-plugin~=1.2
|
||||
mkdocs-material~=9.5
|
||||
mkdocs~=1.6
|
||||
mkdocs-redirects~=1.2
|
||||
pygments~=2.18
|
||||
36
vendor/github.com/urfave/cli/v2/mkdocs.yml → vendor/github.com/urfave/cli/v3/mkdocs.yml
generated
vendored
36
vendor/github.com/urfave/cli/v2/mkdocs.yml → vendor/github.com/urfave/cli/v3/mkdocs.yml
generated
vendored
@@ -15,9 +15,36 @@ nav:
|
||||
- Code of Conduct: CODE_OF_CONDUCT.md
|
||||
- Releasing: RELEASING.md
|
||||
- Security: SECURITY.md
|
||||
- Migrate v2 to v3: migrate-v2-to-v3.md
|
||||
- Migrate v1 to v2: migrate-v1-to-v2.md
|
||||
- v3 Manual:
|
||||
- Getting Started: v3/getting-started.md
|
||||
- Migrating From Older Releases: v3/migrating-from-older-releases.md
|
||||
- Examples:
|
||||
- Greet: v3/examples/greet.md
|
||||
- Flags:
|
||||
- Basics: v3/examples/flags/basics.md
|
||||
- Value Sources: v3/examples/flags/value-sources.md
|
||||
- Short Options: v3/examples/flags/short-options.md
|
||||
- Advanced: v3/examples/flags/advanced.md
|
||||
- Arguments:
|
||||
- Basics: v3/examples/arguments/basics.md
|
||||
- Advanced: v3/examples/arguments/advanced.md
|
||||
- Subcommands:
|
||||
- Basics: v3/examples/subcommands/basics.md
|
||||
- Categories: v3/examples/subcommands/categories.md
|
||||
- Completions:
|
||||
- Shell Completions: v3/examples/completions/shell-completions.md
|
||||
- Customizations: v3/examples/completions/customizations.md
|
||||
- Help Text:
|
||||
- Generated Help Text: v3/examples/help/generated-help-text.md
|
||||
- Suggestions: v3/examples/help/suggestions.md
|
||||
- Error Handling:
|
||||
- Exit Codes: v3/examples/exit-codes.md
|
||||
- Full API Example: v3/examples/full-api-example.md
|
||||
- v2 Manual:
|
||||
- Getting Started: v2/getting-started.md
|
||||
- Migrating to v3: v2/migrating-to-v3.md
|
||||
- Migrating From Older Releases: v2/migrating-from-older-releases.md
|
||||
- Examples:
|
||||
- Greet: v2/examples/greet.md
|
||||
@@ -69,10 +96,15 @@ theme:
|
||||
- navigation.sections
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
|
||||
plugins:
|
||||
- git-revision-date-localized
|
||||
- search
|
||||
- redirects:
|
||||
redirect_maps:
|
||||
'v3/examples/bash-completions.md': 'v3/examples/completions/shell-completions.md'
|
||||
- tags
|
||||
|
||||
# NOTE: this is the recommended configuration from
|
||||
# https://squidfunk.github.io/mkdocs-material/setup/extensions/#recommended-configuration
|
||||
markdown_extensions:
|
||||
@@ -92,8 +124,8 @@ markdown_extensions:
|
||||
- pymdownx.caret
|
||||
- pymdownx.details
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||
- pymdownx.highlight
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.keys
|
||||
0
vendor/github.com/urfave/cli/v2/sort.go → vendor/github.com/urfave/cli/v3/sort.go
generated
vendored
0
vendor/github.com/urfave/cli/v2/sort.go → vendor/github.com/urfave/cli/v3/sort.go
generated
vendored
1
vendor/github.com/urfave/cli/v3/staticcheck.conf
generated
vendored
Normal file
1
vendor/github.com/urfave/cli/v3/staticcheck.conf
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
checks=["all"]
|
||||
147
vendor/github.com/urfave/cli/v3/suggestions.go
generated
vendored
Normal file
147
vendor/github.com/urfave/cli/v3/suggestions.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
const suggestDidYouMeanTemplate = "Did you mean %q?"
|
||||
|
||||
var (
|
||||
SuggestFlag SuggestFlagFunc = suggestFlag
|
||||
SuggestCommand SuggestCommandFunc = suggestCommand
|
||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||
)
|
||||
|
||||
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
|
||||
|
||||
type SuggestCommandFunc func(commands []*Command, provided string) string
|
||||
|
||||
// jaroDistance is the measure of similarity between two strings. It returns a
|
||||
// value between 0 and 1, where 1 indicates identical strings and 0 indicates
|
||||
// completely different strings.
|
||||
//
|
||||
// Adapted from https://github.com/xrash/smetrics/blob/5f08fbb34913bc8ab95bb4f2a89a0637ca922666/jaro.go.
|
||||
func jaroDistance(a, b string) float64 {
|
||||
if len(a) == 0 && len(b) == 0 {
|
||||
return 1
|
||||
}
|
||||
if len(a) == 0 || len(b) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
lenA := float64(len(a))
|
||||
lenB := float64(len(b))
|
||||
hashA := make([]bool, len(a))
|
||||
hashB := make([]bool, len(b))
|
||||
maxDistance := int(math.Max(0, math.Floor(math.Max(lenA, lenB)/2.0)-1))
|
||||
|
||||
var matches float64
|
||||
for i := 0; i < len(a); i++ {
|
||||
start := int(math.Max(0, float64(i-maxDistance)))
|
||||
end := int(math.Min(lenB-1, float64(i+maxDistance)))
|
||||
|
||||
for j := start; j <= end; j++ {
|
||||
if hashB[j] {
|
||||
continue
|
||||
}
|
||||
if a[i] == b[j] {
|
||||
hashA[i] = true
|
||||
hashB[j] = true
|
||||
matches++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if matches == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var transpositions float64
|
||||
var j int
|
||||
for i := 0; i < len(a); i++ {
|
||||
if !hashA[i] {
|
||||
continue
|
||||
}
|
||||
for !hashB[j] {
|
||||
j++
|
||||
}
|
||||
if a[i] != b[j] {
|
||||
transpositions++
|
||||
}
|
||||
j++
|
||||
}
|
||||
|
||||
transpositions /= 2
|
||||
return ((matches / lenA) + (matches / lenB) + ((matches - transpositions) / matches)) / 3.0
|
||||
}
|
||||
|
||||
// jaroWinkler is more accurate when strings have a common prefix up to a
|
||||
// defined maximum length.
|
||||
//
|
||||
// Adapted from https://github.com/xrash/smetrics/blob/5f08fbb34913bc8ab95bb4f2a89a0637ca922666/jaro-winkler.go.
|
||||
func jaroWinkler(a, b string) float64 {
|
||||
const (
|
||||
boostThreshold = 0.7
|
||||
prefixSize = 4
|
||||
)
|
||||
jaroDist := jaroDistance(a, b)
|
||||
if jaroDist <= boostThreshold {
|
||||
return jaroDist
|
||||
}
|
||||
|
||||
prefix := int(math.Min(float64(len(a)), math.Min(float64(prefixSize), float64(len(b)))))
|
||||
|
||||
var prefixMatch float64
|
||||
for i := 0; i < prefix; i++ {
|
||||
if a[i] == b[i] {
|
||||
prefixMatch++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return jaroDist + 0.1*prefixMatch*(1.0-jaroDist)
|
||||
}
|
||||
|
||||
func suggestFlag(flags []Flag, provided string, hideHelp bool) string {
|
||||
distance := 0.0
|
||||
suggestion := ""
|
||||
|
||||
for _, flag := range flags {
|
||||
flagNames := flag.Names()
|
||||
if !hideHelp && HelpFlag != nil {
|
||||
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 suggestion
|
||||
}
|
||||
@@ -1,16 +1,23 @@
|
||||
package cli
|
||||
|
||||
var helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}`
|
||||
var usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}}{{if .ArgsUsage}} {{.ArgsUsage}}{{else}}{{if .Args}} [arguments...]{{end}}{{end}}{{end}}`
|
||||
var descriptionTemplate = `{{wrap .Description 3}}`
|
||||
var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
var (
|
||||
helpNameTemplate = `{{$v := offset .FullName 6}}{{wrap .FullName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}`
|
||||
argsTemplate = `{{if .Arguments}}{{range .Arguments}}{{.Usage}}{{end}}{{end}}`
|
||||
usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}}{{if .VisibleFlags}} [options]{{end}}{{if .VisibleCommands}} [command [command options]]{{end}}{{if .ArgsUsage}} {{.ArgsUsage}}{{else}}{{if .Arguments}} {{template "argsTemplate" .}}{{end}}{{end}}{{end}}`
|
||||
descriptionTemplate = `{{wrap .Description 3}}`
|
||||
authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}`
|
||||
)
|
||||
|
||||
var visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}`
|
||||
|
||||
var visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}}
|
||||
|
||||
{{.Name}}:{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}`
|
||||
|
||||
var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}}
|
||||
{{if .Name}}{{.Name}}
|
||||
|
||||
@@ -21,6 +28,9 @@ var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}}
|
||||
var visibleFlagTemplate = `{{range $i, $e := .VisibleFlags}}
|
||||
{{wrap $e.String 6}}{{end}}`
|
||||
|
||||
var visiblePersistentFlagTemplate = `{{range $i, $e := .VisiblePersistentFlags}}
|
||||
{{wrap $e.String 6}}{{end}}`
|
||||
|
||||
var versionTemplate = `{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
@@ -28,14 +38,14 @@ VERSION:
|
||||
|
||||
var copyrightTemplate = `{{wrap .Copyright 3}}`
|
||||
|
||||
// AppHelpTemplate is the text template for the Default help topic.
|
||||
// RootCommandHelpTemplate is the text template for the Default help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var AppHelpTemplate = `NAME:
|
||||
var RootCommandHelpTemplate = `NAME:
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}}{{if .ArgsUsage}} {{.ArgsUsage}}{{else}}{{if .Args}} [arguments...]{{end}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}} {{if .VisibleFlags}}[global options]{{end}}{{if .VisibleCommands}} [command [command options]]{{end}}{{if .ArgsUsage}} {{.ArgsUsage}}{{else}}{{if .Arguments}} [arguments...]{{end}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
@@ -73,7 +83,9 @@ DESCRIPTION:
|
||||
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .VisiblePersistentFlags}}
|
||||
|
||||
GLOBAL OPTIONS:{{template "visiblePersistentFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||
@@ -83,7 +95,7 @@ var SubcommandHelpTemplate = `NAME:
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{template "usageTemplate" .}}{{if .Category}}
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}}{{if .VisibleCommands}} [command [command options]]{{end}}{{if .ArgsUsage}} {{.ArgsUsage}}{{else}}{{if .Arguments}} [arguments...]{{end}}{{end}}{{end}}{{if .Category}}
|
||||
|
||||
CATEGORY:
|
||||
{{.Category}}{{end}}{{if .Description}}
|
||||
@@ -91,49 +103,16 @@ CATEGORY:
|
||||
DESCRIPTION:
|
||||
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
||||
var FishCompletionTemplate = `# {{ .Command.Name }} fish shell completion
|
||||
|
||||
{{end}}# NAME
|
||||
|
||||
{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }}
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
{{ .App.Name }}
|
||||
{{ if .SynopsisArgs }}
|
||||
` + "```" + `
|
||||
{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + `
|
||||
{{ end }}{{ if .App.Description }}
|
||||
# DESCRIPTION
|
||||
|
||||
{{ .App.Description }}
|
||||
{{ end }}
|
||||
**Usage**:
|
||||
|
||||
` + "```" + `{{ if .App.UsageText }}
|
||||
{{ .App.UsageText }}
|
||||
{{ else }}
|
||||
{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
{{ end }}` + "```" + `
|
||||
{{ if .GlobalArgs }}
|
||||
# GLOBAL OPTIONS
|
||||
{{ range $v := .GlobalArgs }}
|
||||
{{ $v }}{{ end }}
|
||||
{{ end }}{{ if .Commands }}
|
||||
# COMMANDS
|
||||
{{ range $v := .Commands }}
|
||||
{{ $v }}{{ end }}{{ end }}`
|
||||
|
||||
var FishCompletionTemplate = `# {{ .App.Name }} fish shell completion
|
||||
|
||||
function __fish_{{ .App.Name }}_no_subcommand --description 'Test if there has been any subcommand yet'
|
||||
function __fish_{{ .Command.Name }}_no_subcommand --description 'Test if there has been any subcommand yet'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i{{ range $v := .AllCommands }} {{ $v }}{{ end }}
|
||||
return 1
|
||||
257
vendor/github.com/urfave/cli/v3/value_source.go
generated
vendored
Normal file
257
vendor/github.com/urfave/cli/v3/value_source.go
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ValueSource is a source which can be used to look up a value,
|
||||
// typically for use with a cli.Flag
|
||||
type ValueSource interface {
|
||||
fmt.Stringer
|
||||
fmt.GoStringer
|
||||
|
||||
// Lookup returns the value from the source and if it was found
|
||||
// or returns an empty string and false
|
||||
Lookup() (string, bool)
|
||||
}
|
||||
|
||||
// EnvValueSource is to specifically detect env sources when
|
||||
// printing help text
|
||||
type EnvValueSource interface {
|
||||
IsFromEnv() bool
|
||||
Key() string
|
||||
}
|
||||
|
||||
// MapSource is a source which can be used to look up a value
|
||||
// based on a key
|
||||
// typically for use with a cli.Flag
|
||||
type MapSource interface {
|
||||
fmt.Stringer
|
||||
fmt.GoStringer
|
||||
|
||||
// Lookup returns the value from the source based on key
|
||||
// and if it was found
|
||||
// or returns an empty string and false
|
||||
Lookup(string) (any, bool)
|
||||
}
|
||||
|
||||
// ValueSourceChain contains an ordered series of ValueSource that
|
||||
// allows for lookup where the first ValueSource to resolve is
|
||||
// returned
|
||||
type ValueSourceChain struct {
|
||||
Chain []ValueSource
|
||||
}
|
||||
|
||||
func NewValueSourceChain(src ...ValueSource) ValueSourceChain {
|
||||
return ValueSourceChain{
|
||||
Chain: src,
|
||||
}
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) Append(other ValueSourceChain) {
|
||||
vsc.Chain = append(vsc.Chain, other.Chain...)
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) EnvKeys() []string {
|
||||
vals := []string{}
|
||||
|
||||
for _, src := range vsc.Chain {
|
||||
if v, ok := src.(EnvValueSource); ok && v.IsFromEnv() {
|
||||
vals = append(vals, v.Key())
|
||||
}
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) String() string {
|
||||
s := []string{}
|
||||
|
||||
for _, vs := range vsc.Chain {
|
||||
s = append(s, vs.String())
|
||||
}
|
||||
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) GoString() string {
|
||||
s := []string{}
|
||||
|
||||
for _, vs := range vsc.Chain {
|
||||
s = append(s, vs.GoString())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("&ValueSourceChain{Chain:{%[1]s}}", strings.Join(s, ","))
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) Lookup() (string, bool) {
|
||||
s, _, ok := vsc.LookupWithSource()
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) LookupWithSource() (string, ValueSource, bool) {
|
||||
for _, src := range vsc.Chain {
|
||||
if value, found := src.Lookup(); found {
|
||||
return value, src, true
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil, false
|
||||
}
|
||||
|
||||
// envVarValueSource encapsulates a ValueSource from an environment variable
|
||||
type envVarValueSource struct {
|
||||
key string
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) Lookup() (string, bool) {
|
||||
return os.LookupEnv(strings.TrimSpace(string(e.key)))
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) IsFromEnv() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) Key() string {
|
||||
return e.key
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) String() string { return fmt.Sprintf("environment variable %[1]q", e.key) }
|
||||
func (e *envVarValueSource) GoString() string {
|
||||
return fmt.Sprintf("&envVarValueSource{Key:%[1]q}", e.key)
|
||||
}
|
||||
|
||||
func EnvVar(key string) ValueSource {
|
||||
return &envVarValueSource{
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
// EnvVars is a helper function to encapsulate a number of
|
||||
// envVarValueSource together as a ValueSourceChain
|
||||
func EnvVars(keys ...string) ValueSourceChain {
|
||||
vsc := ValueSourceChain{Chain: []ValueSource{}}
|
||||
|
||||
for _, key := range keys {
|
||||
vsc.Chain = append(vsc.Chain, EnvVar(key))
|
||||
}
|
||||
|
||||
return vsc
|
||||
}
|
||||
|
||||
// fileValueSource encapsulates a ValueSource from a file
|
||||
type fileValueSource struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (f *fileValueSource) Lookup() (string, bool) {
|
||||
data, err := os.ReadFile(f.Path)
|
||||
return string(data), err == nil
|
||||
}
|
||||
|
||||
func (f *fileValueSource) String() string { return fmt.Sprintf("file %[1]q", f.Path) }
|
||||
func (f *fileValueSource) GoString() string {
|
||||
return fmt.Sprintf("&fileValueSource{Path:%[1]q}", f.Path)
|
||||
}
|
||||
|
||||
func File(path string) ValueSource {
|
||||
return &fileValueSource{Path: path}
|
||||
}
|
||||
|
||||
// Files is a helper function to encapsulate a number of
|
||||
// fileValueSource together as a ValueSourceChain
|
||||
func Files(paths ...string) ValueSourceChain {
|
||||
vsc := ValueSourceChain{Chain: []ValueSource{}}
|
||||
|
||||
for _, path := range paths {
|
||||
vsc.Chain = append(vsc.Chain, File(path))
|
||||
}
|
||||
|
||||
return vsc
|
||||
}
|
||||
|
||||
type mapSource struct {
|
||||
name string
|
||||
m map[any]any
|
||||
}
|
||||
|
||||
func NewMapSource(name string, m map[any]any) MapSource {
|
||||
return &mapSource{
|
||||
name: name,
|
||||
m: m,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *mapSource) String() string { return fmt.Sprintf("map source %[1]q", ms.name) }
|
||||
func (ms *mapSource) GoString() string {
|
||||
return fmt.Sprintf("&mapSource{name:%[1]q}", ms.name)
|
||||
}
|
||||
|
||||
// Lookup returns a value from the map source. The lookup name may be a dot-separated path into the map.
|
||||
// If that is the case, it will recursively traverse the map based on the '.' delimited sections to find
|
||||
// a nested value for the key.
|
||||
func (ms *mapSource) Lookup(name string) (any, bool) {
|
||||
sections := strings.Split(name, ".")
|
||||
if name == "" || len(sections) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
node := ms.m
|
||||
|
||||
// traverse into the map based on the dot-separated sections
|
||||
if len(sections) >= 2 { // the last section is the value we want, we will return it directly at the end
|
||||
for _, section := range sections[:len(sections)-1] {
|
||||
child, ok := node[section]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
switch child := child.(type) {
|
||||
case map[string]any:
|
||||
node = make(map[any]any, len(child))
|
||||
for k, v := range child {
|
||||
node[k] = v
|
||||
}
|
||||
case map[any]any:
|
||||
node = child
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := node[sections[len(sections)-1]]; ok {
|
||||
return val, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
type mapValueSource struct {
|
||||
key string
|
||||
ms MapSource
|
||||
}
|
||||
|
||||
func NewMapValueSource(key string, ms MapSource) ValueSource {
|
||||
return &mapValueSource{
|
||||
key: key,
|
||||
ms: ms,
|
||||
}
|
||||
}
|
||||
|
||||
func (mvs *mapValueSource) String() string {
|
||||
return fmt.Sprintf("key %[1]q from %[2]s", mvs.key, mvs.ms.String())
|
||||
}
|
||||
|
||||
func (mvs *mapValueSource) GoString() string {
|
||||
return fmt.Sprintf("&mapValueSource{key:%[1]q, src:%[2]s}", mvs.key, mvs.ms.GoString())
|
||||
}
|
||||
|
||||
func (mvs *mapValueSource) Lookup() (string, bool) {
|
||||
if v, ok := mvs.ms.Lookup(mvs.key); !ok {
|
||||
return "", false
|
||||
} else {
|
||||
return fmt.Sprintf("%+v", v), true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user