update vendored

This commit is contained in:
Louis Abel 2022-11-14 18:57:22 -07:00
parent 08b382b51f
commit 174f0860a7
Signed by: label
GPG Key ID: 6735C0E1BD65D048
25 changed files with 532 additions and 402 deletions

2
go.mod
View File

@ -2,7 +2,7 @@ module github.com/rocky-linux/rpaste
go 1.18
require github.com/urfave/cli/v2 v2.19.2
require github.com/urfave/cli/v2 v2.23.5
require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect

4
go.sum
View File

@ -2,7 +2,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/urfave/cli/v2 v2.19.2 h1:eXu5089gqqiDQKSnFW+H/FhjrxRGztwSxlTsVK7IuqQ=
github.com/urfave/cli/v2 v2.19.2/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw=
github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=

View File

@ -7,8 +7,8 @@ import (
"io"
"os"
"path/filepath"
"reflect"
"sort"
"strings"
"time"
)
@ -21,6 +21,7 @@ var (
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 = suggestFlag
SuggestCommand SuggestCommandFunc = suggestCommand
@ -104,14 +105,23 @@ type App struct {
// 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
// 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
rootCommand *Command
}
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
@ -194,12 +204,24 @@ func (a *App) Setup() {
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})
}
})
}
var newCommands []*Command
for _, c := range a.Commands {
if c.HelpName == "" {
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
cname := c.Name
if c.HelpName != "" {
cname = c.HelpName
}
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname)
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
newCommands = append(newCommands, c)
@ -238,6 +260,36 @@ func (a *App) Setup() {
if a.Metadata == nil {
a.Metadata = make(map[string]interface{})
}
if len(a.SliceFlagSeparator) != 0 {
defaultSliceFlagSeparator = a.SliceFlagSeparator
}
}
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,
}
}
func (a *App) newFlagSet() (*flag.FlagSet, error) {
@ -268,136 +320,20 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
// always appends the completion flag at the end of the command
shellComplete, arguments := checkShellCompleteFlag(a, arguments)
set, err := a.newFlagSet()
if err != nil {
return err
}
err = parseIter(set, a, arguments[1:], shellComplete)
nerr := normalizeFlags(a.Flags, set)
cCtx := NewContext(a, set, &Context{Context: ctx})
if nerr != nil {
_, _ = fmt.Fprintln(a.Writer, nerr)
if !a.HideHelp {
_ = ShowAppHelp(cCtx)
}
return nerr
}
cCtx := NewContext(a, nil, &Context{Context: ctx})
cCtx.shellComplete = shellComplete
if checkCompletions(cCtx) {
return nil
}
a.rootCommand = a.newRootCommand()
cCtx.Command = a.rootCommand
if err != nil {
if a.OnUsageError != nil {
err := a.OnUsageError(cCtx, err, false)
a.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
if a.Suggest {
if suggestion, err := a.suggestFlagFromError(err, ""); err == nil {
fmt.Fprintf(a.Writer, suggestion)
}
}
if !a.HideHelp {
_ = ShowAppHelp(cCtx)
}
return err
}
return a.rootCommand.Run(cCtx, arguments...)
}
if a.After != nil && !cCtx.shellComplete {
defer func() {
if afterErr := a.After(cCtx); afterErr != nil {
if err != nil {
err = newMultiError(err, afterErr)
} else {
err = afterErr
}
}
}()
}
if !a.HideHelp && checkHelp(cCtx) {
_ = ShowAppHelp(cCtx)
return nil
}
if !a.HideVersion && checkVersion(cCtx) {
ShowVersion(cCtx)
return nil
}
cerr := cCtx.checkRequiredFlags(a.Flags)
if cerr != nil {
_ = ShowAppHelp(cCtx)
return cerr
}
if a.Before != nil && !cCtx.shellComplete {
beforeErr := a.Before(cCtx)
if beforeErr != nil {
a.handleExitCoder(cCtx, beforeErr)
err = beforeErr
return err
}
}
if err = runFlagActions(cCtx, a.Flags); err != nil {
return err
}
var c *Command
args := cCtx.Args()
if args.Present() {
name := args.First()
if a.validCommandName(name) {
c = a.Command(name)
} else {
hasDefault := a.DefaultCommand != ""
isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames())
var (
isDefaultSubcommand = false
defaultHasSubcommands = false
)
if hasDefault {
dc := a.Command(a.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 := a.argsWithDefaultCommand(args)
if !reflect.DeepEqual(args, argsWithDefault) {
c = a.Command(argsWithDefault.First())
}
}
}
} else if a.DefaultCommand != "" {
c = a.Command(a.DefaultCommand)
}
if c != nil {
return c.Run(cCtx)
}
if a.Action == nil {
a.Action = helpCommand.Action
}
// Run default Action
err = a.Action(cCtx)
a.handleExitCoder(cCtx, err)
return err
// This is a stub function to keep public API unchanged from old code
//
// Deprecated: use App.Run or App.RunContext
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
return a.RunContext(ctx.Context, ctx.Args().Slice())
}
func (a *App) suggestFlagFromError(err error, command string) (string, error) {
@ -407,15 +343,17 @@ func (a *App) suggestFlagFromError(err error, command string) (string, error) {
}
flags := a.Flags
hideHelp := a.HideHelp
if command != "" {
cmd := a.Command(command)
if cmd == nil {
return "", err
}
flags = cmd.Flags
hideHelp = hideHelp || cmd.HideHelp
}
suggestion := SuggestFlag(flags, flag, a.HideHelp)
suggestion := SuggestFlag(flags, flag, hideHelp)
if len(suggestion) == 0 {
return "", err
}
@ -435,120 +373,6 @@ func (a *App) RunAndExitOnError() {
}
}
// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to
// generate command-specific flags
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
// Setup also handles HideHelp and HideHelpCommand
a.Setup()
var newCmds []*Command
for _, c := range a.Commands {
if c.HelpName == "" {
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
}
newCmds = append(newCmds, c)
}
a.Commands = newCmds
set, err := a.newFlagSet()
if err != nil {
return err
}
err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete)
nerr := normalizeFlags(a.Flags, set)
cCtx := NewContext(a, set, ctx)
if nerr != nil {
_, _ = fmt.Fprintln(a.Writer, nerr)
_, _ = fmt.Fprintln(a.Writer)
if len(a.Commands) > 0 {
_ = ShowSubcommandHelp(cCtx)
} else {
_ = ShowCommandHelp(ctx, cCtx.Args().First())
}
return nerr
}
if checkCompletions(cCtx) {
return nil
}
if err != nil {
if a.OnUsageError != nil {
err = a.OnUsageError(cCtx, err, true)
a.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
if a.Suggest {
if suggestion, err := a.suggestFlagFromError(err, cCtx.Command.Name); err == nil {
fmt.Fprintf(a.Writer, suggestion)
}
}
_ = ShowSubcommandHelp(cCtx)
return err
}
if len(a.Commands) > 0 {
if checkSubcommandHelp(cCtx) {
return nil
}
} else {
if checkCommandHelp(ctx, cCtx.Args().First()) {
return nil
}
}
cerr := cCtx.checkRequiredFlags(a.Flags)
if cerr != nil {
_ = ShowSubcommandHelp(cCtx)
return cerr
}
if a.After != nil && !cCtx.shellComplete {
defer func() {
afterErr := a.After(cCtx)
if afterErr != nil {
a.handleExitCoder(cCtx, err)
if err != nil {
err = newMultiError(err, afterErr)
} else {
err = afterErr
}
}
}()
}
if a.Before != nil && !cCtx.shellComplete {
beforeErr := a.Before(cCtx)
if beforeErr != nil {
a.handleExitCoder(cCtx, beforeErr)
err = beforeErr
return err
}
}
if err = runFlagActions(cCtx, a.Flags); err != nil {
return err
}
args := cCtx.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(cCtx)
}
}
// Run default Action
err = a.Action(cCtx)
a.handleExitCoder(cCtx, err)
return err
}
// 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 {

View File

@ -22,4 +22,4 @@
// }
package cli
//go:generate go run cmd/urfave-cli-genflags/main.go
//go:generate make -C cmd/urfave-cli-genflags run

View File

@ -3,6 +3,7 @@ package cli
import (
"flag"
"fmt"
"reflect"
"sort"
"strings"
)
@ -62,6 +63,12 @@ type Command struct {
// 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
}
type Commands []*Command
@ -89,10 +96,21 @@ func (c *Command) FullName() string {
return strings.Join(c.commandNamePath, " ")
}
// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags
func (c *Command) Run(ctx *Context) (err error) {
if len(c.Subcommands) > 0 {
return c.startApp(ctx)
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 {
@ -104,46 +122,72 @@ func (c *Command) Run(ctx *Context) (err error) {
c.UseShortOptionHandling = true
}
set, err := c.parseFlags(ctx.Args(), ctx.shellComplete)
c.categories = newCommandCategories()
for _, command := range c.Subcommands {
c.categories.AddCommand(command.Category, command)
}
sort.Sort(c.categories.(*commandCategories))
cCtx := NewContext(ctx.App, set, ctx)
cCtx.Command = c
if checkCommandCompletions(cCtx, c.Name) {
var newCmds []*Command
for _, scmd := range c.Subcommands {
if scmd.HelpName == "" {
scmd.HelpName = fmt.Sprintf("%s %s", c.HelpName, scmd.Name)
}
newCmds = append(newCmds, scmd)
}
c.Subcommands = newCmds
}
func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
if !c.isRoot {
c.setup(cCtx)
}
a := args(arguments)
set, err := c.parseFlags(&a, cCtx.shellComplete)
cCtx.flagSet = set
if c.isRoot {
if checkCompletions(cCtx) {
return nil
}
} else if checkCommandCompletions(cCtx, c.Name) {
return nil
}
if err != nil {
if c.OnUsageError != nil {
err = c.OnUsageError(cCtx, err, false)
err = c.OnUsageError(cCtx, err, !c.isRoot)
cCtx.App.handleExitCoder(cCtx, err)
return err
}
_, _ = fmt.Fprintln(cCtx.App.Writer, "Incorrect Usage:", err.Error())
_, _ = fmt.Fprintln(cCtx.App.Writer)
if ctx.App.Suggest {
if suggestion, err := ctx.App.suggestFlagFromError(err, c.Name); err == nil {
fmt.Fprintf(cCtx.App.Writer, suggestion)
_, _ = 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 {
_ = ShowCommandHelp(cCtx, c.Name)
if c.isRoot {
_ = ShowAppHelp(cCtx)
} else {
_ = ShowCommandHelp(cCtx.parentContext, c.Name)
}
}
return err
}
if checkCommandHelp(cCtx, c.Name) {
if checkHelp(cCtx) {
return helpCommand.Action(cCtx)
}
if c.isRoot && !cCtx.App.HideVersion && checkVersion(cCtx) {
ShowVersion(cCtx)
return nil
}
cerr := cCtx.checkRequiredFlags(c.Flags)
if cerr != nil {
if !c.HideHelp {
_ = ShowCommandHelp(cCtx, c.Name)
}
return cerr
}
if c.After != nil {
if c.After != nil && !cCtx.shellComplete {
defer func() {
afterErr := c.After(cCtx)
if afterErr != nil {
@ -157,10 +201,17 @@ func (c *Command) Run(ctx *Context) (err error) {
}()
}
if c.Before != nil {
err = c.Before(cCtx)
if err != nil {
cCtx.App.handleExitCoder(cCtx, err)
cerr := cCtx.checkRequiredFlags(c.Flags)
if cerr != nil {
_ = ShowSubcommandHelp(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
}
}
@ -169,16 +220,57 @@ func (c *Command) Run(ctx *Context) (err error) {
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
}
cCtx.Command = c
err = c.Action(cCtx)
if err != nil {
cCtx.App.handleExitCoder(cCtx, err)
}
cCtx.App.handleExitCoder(cCtx, err)
return err
}
@ -190,6 +282,31 @@ 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 {
@ -228,71 +345,21 @@ func (c *Command) HasName(name string) bool {
return false
}
func (c *Command) startApp(ctx *Context) error {
app := &App{
Metadata: ctx.App.Metadata,
Name: fmt.Sprintf("%s %s", ctx.App.Name, c.Name),
// 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)
}
}
if c.HelpName == "" {
app.HelpName = c.HelpName
} else {
app.HelpName = app.Name
}
app.Usage = c.Usage
app.UsageText = c.UsageText
app.Description = c.Description
app.ArgsUsage = c.ArgsUsage
// set CommandNotFound
app.CommandNotFound = ctx.App.CommandNotFound
app.CustomAppHelpTemplate = c.CustomHelpTemplate
// set the flags and commands
app.Commands = c.Subcommands
app.Flags = c.Flags
app.HideHelp = c.HideHelp
app.HideHelpCommand = c.HideHelpCommand
app.Version = ctx.App.Version
app.HideVersion = true
app.Compiled = ctx.App.Compiled
app.Reader = ctx.App.Reader
app.Writer = ctx.App.Writer
app.ErrWriter = ctx.App.ErrWriter
app.ExitErrHandler = ctx.App.ExitErrHandler
app.UseShortOptionHandling = ctx.App.UseShortOptionHandling
app.Suggest = ctx.App.Suggest
app.categories = newCommandCategories()
for _, command := range c.Subcommands {
app.categories.AddCommand(command.Category, command)
}
sort.Sort(app.categories.(*commandCategories))
// bash completion
app.EnableBashCompletion = ctx.App.EnableBashCompletion
if c.BashComplete != nil {
app.BashComplete = c.BashComplete
}
// set the actions
app.Before = c.Before
app.After = c.After
if c.Action != nil {
app.Action = c.Action
} else {
app.Action = helpCommand.Action
}
app.OnUsageError = c.OnUsageError
for index, cc := range app.Commands {
app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
}
return app.RunAsSubcommand(ctx)
return ret
}
// VisibleCommands returns a slice of the Commands with Hidden=false

View File

@ -82,7 +82,27 @@ func (cCtx *Context) IsSet(name string) bool {
func (cCtx *Context) LocalFlagNames() []string {
var names []string
cCtx.flagSet.Visit(makeFlagNameVisitor(&names))
return 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
@ -90,7 +110,7 @@ func (cCtx *Context) LocalFlagNames() []string {
func (cCtx *Context) FlagNames() []string {
var names []string
for _, pCtx := range cCtx.Lineage() {
pCtx.flagSet.Visit(makeFlagNameVisitor(&names))
names = append(names, pCtx.LocalFlagNames()...)
}
return names
}

View File

@ -83,7 +83,7 @@ type ExitCoder interface {
type exitError struct {
exitCode int
message interface{}
err error
}
// NewExitError calls Exit to create a new ExitCoder.
@ -98,23 +98,38 @@ func NewExitError(message interface{}, exitCode int) ExitCoder {
//
// This is the simplest way to trigger a non-zero exit code for an App without
// having to call os.Exit manually. During testing, this behavior can be avoided
// by overiding the ExitErrHandler function on an App or the package-global
// by overriding the ExitErrHandler function on an App or the package-global
// OsExiter function.
func Exit(message interface{}, exitCode int) ExitCoder {
var err error
switch e := message.(type) {
case ErrorFormatter:
err = fmt.Errorf("%+v", message)
case error:
err = e
default:
err = fmt.Errorf("%+v", message)
}
return &exitError{
message: message,
err: err,
exitCode: exitCode,
}
}
func (ee *exitError) Error() string {
return fmt.Sprintf("%v", ee.message)
return ee.err.Error()
}
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.
//

View File

@ -98,7 +98,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr
a.prepareFishFlags(command.VisibleFlags(), command.Names())...,
)
// recursevly iterate subcommands
// recursively iterate subcommands
if len(command.Subcommands) > 0 {
completions = append(
completions,

View File

@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"io/ioutil"
"os"
"regexp"
"runtime"
"strings"
@ -14,6 +15,8 @@ import (
const defaultPlaceholder = "value"
var defaultSliceFlagSeparator = ","
var (
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
@ -268,19 +271,23 @@ func prefixedNames(names []string, placeholder string) string {
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 len(envVars) > 0 {
prefix := "$"
suffix := ""
sep := ", $"
if runtime.GOOS == "windows" {
prefix = "%"
suffix = "%"
sep = "%, %"
}
envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix)
if runtime.GOOS != "windows" || os.Getenv("PSHOME") != "" {
envText = defaultEnvFormat(envVars)
} else {
envText = envFormat(envVars, "%", "%, %", "%")
}
return str + envText
}
@ -373,5 +380,5 @@ func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhe
}
func flagSplitMultiValues(val string) []string {
return strings.Split(val, ",")
return strings.Split(val, defaultSliceFlagSeparator)
}

View File

@ -84,7 +84,7 @@ func (f *BoolFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return fmt.Sprintf("%v", f.Value)
return fmt.Sprintf("%v", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag
@ -103,6 +103,9 @@ func (f *BoolFlag) RunAction(c *Context) error {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valBool, err := strconv.ParseBool(val)

View File

@ -32,7 +32,7 @@ func (f *DurationFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return f.defaultValue.String()
}
// GetEnvVars returns the env vars for this flag
@ -42,6 +42,9 @@ func (f *DurationFlag) GetEnvVars() []string {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valDuration, err := time.ParseDuration(val)

48
vendor/github.com/urfave/cli/v2/flag_ext.go generated vendored Normal file
View File

@ -0,0 +1,48 @@
package cli
import "flag"
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)
return nil
}
func (e *extFlag) Names() []string {
return []string{e.f.Name}
}
func (e *extFlag) IsSet() bool {
return false
}
func (e *extFlag) String() string {
return FlagStringer(e)
}
func (e *extFlag) IsVisible() bool {
return true
}
func (e *extFlag) TakesValue() bool {
return false
}
func (e *extFlag) GetUsage() string {
return e.f.Usage
}
func (e *extFlag) GetValue() string {
return e.f.Value.String()
}
func (e *extFlag) GetDefaultText() string {
return e.f.DefValue
}
func (e *extFlag) GetEnvVars() []string {
return nil
}

View File

@ -11,6 +11,19 @@ type Generic interface {
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
@ -40,7 +53,10 @@ func (f *GenericFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
if f.defaultValue != nil {
return f.defaultValue.String()
}
return ""
}
// GetEnvVars returns the env vars for this flag
@ -51,6 +67,11 @@ func (f *GenericFlag) GetEnvVars() []string {
// 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()}
}
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
if err := f.Value.Set(val); err != nil {

View File

@ -32,7 +32,7 @@ func (f *IntFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return fmt.Sprintf("%d", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag
@ -42,6 +42,9 @@ func (f *IntFlag) GetEnvVars() []string {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseInt(val, f.Base, 64)

View File

@ -32,7 +32,7 @@ func (f *Int64Flag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return fmt.Sprintf("%d", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag
@ -42,6 +42,9 @@ func (f *Int64Flag) GetEnvVars() []string {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseInt(val, f.Base, 64)

View File

@ -33,10 +33,10 @@ func (f *PathFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
if f.Value == "" {
return f.Value
if f.defaultValue == "" {
return f.defaultValue
}
return fmt.Sprintf("%q", f.Value)
return fmt.Sprintf("%q", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag
@ -46,6 +46,9 @@ func (f *PathFlag) GetEnvVars() []string {
// 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
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val
f.HasBeenSet = true

View File

@ -31,10 +31,10 @@ func (f *StringFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
if f.Value == "" {
return f.Value
if f.defaultValue == "" {
return f.defaultValue
}
return fmt.Sprintf("%q", f.Value)
return fmt.Sprintf("%q", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag
@ -44,6 +44,9 @@ func (f *StringFlag) GetEnvVars() []string {
// 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
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val
f.HasBeenSet = true

View File

@ -72,6 +72,25 @@ 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
@ -101,7 +120,11 @@ func (f *TimestampFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
if f.defaultValue != nil && f.defaultValue.timestamp != nil {
return f.defaultValue.timestamp.String()
}
return ""
}
// GetEnvVars returns the env vars for this flag
@ -120,6 +143,8 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
f.Value.SetLayout(f.Layout)
f.Value.SetLocation(f.Timezone)
f.defaultValue = f.Value.clone()
if f.Destination != nil {
f.Destination.SetLayout(f.Layout)
f.Destination.SetLocation(f.Timezone)

View File

@ -23,6 +23,9 @@ func (f *UintFlag) GetCategory() string {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseUint(val, f.Base, 64)
@ -66,7 +69,7 @@ func (f *UintFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return fmt.Sprintf("%d", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag

View File

@ -23,6 +23,9 @@ func (f *Uint64Flag) GetCategory() string {
// 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
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" {
valInt, err := strconv.ParseUint(val, f.Base, 64)
@ -66,7 +69,7 @@ func (f *Uint64Flag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
return fmt.Sprintf("%d", f.defaultValue)
}
// GetEnvVars returns the env vars for this flag

View File

@ -136,7 +136,7 @@ var SubcommandHelpTemplate = `NAME:
{{template "helpNameTemplate" .}}
USAGE:
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
DESCRIPTION:
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
@ -316,12 +316,19 @@ type App struct {
// 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
// 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
// Has unexported fields.
}
@ -348,8 +355,9 @@ func (a *App) RunAndExitOnError()
code in the cli.ExitCoder
func (a *App) RunAsSubcommand(ctx *Context) (err error)
RunAsSubcommand invokes the subcommand given the context, parses ctx.Args()
to generate command-specific flags
This is a stub function to keep public API unchanged from old code
Deprecated: use App.Run or App.RunContext
func (a *App) RunContext(ctx context.Context, arguments []string) (err error)
RunContext is like Run except it takes a Context that will be passed to
@ -446,6 +454,7 @@ type BoolFlag struct {
Count *int
Action func(*Context, bool) error
// Has unexported fields.
}
BoolFlag is a flag with type bool
@ -553,10 +562,13 @@ type Command struct {
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
CustomHelpTemplate string
// Has unexported fields.
}
Command is a subcommand for a cli.App.
func (cmd *Command) Command(name string) *Command
func (c *Command) FullName() string
FullName returns the full name of the command. For subcommands this ensures
that parent commands are part of the command path