From c20d7d45aacd213b384d06f0e29997fce542be18 Mon Sep 17 00:00:00 2001 From: appleboy Date: Sat, 4 Jan 2020 17:44:25 +0000 Subject: [PATCH] chore(cli): upgrade urfave/cli to v2 version (#85) chore(cli): upgrade urfave/cli to v2 version Co-authored-by: Bo-Yi Wu Reviewed-by: Lunny Xiao Reviewed-by: Andrew Thornton --- cmd/flags.go | 16 +- cmd/issues.go | 12 +- cmd/labels.go | 30 +- cmd/login.go | 32 +- cmd/logout.go | 4 +- cmd/pulls.go | 2 +- cmd/releases.go | 20 +- cmd/repos.go | 12 +- go.mod | 2 +- go.sum | 4 +- main.go | 18 +- vendor/github.com/urfave/cli/.travis.yml | 35 -- vendor/github.com/urfave/cli/category.go | 44 --- vendor/github.com/urfave/cli/context.go | 339 ------------------ vendor/github.com/urfave/cli/flag_bool_t.go | 110 ------ .../github.com/urfave/cli/flag_int64_slice.go | 141 -------- .../github.com/urfave/cli/flag_int_slice.go | 142 -------- .../urfave/cli/flag_string_slice.go | 138 ------- vendor/github.com/urfave/cli/{ => v2}/.flake8 | 0 .../github.com/urfave/cli/{ => v2}/.gitignore | 4 +- .../urfave/cli/{ => v2}/CODE_OF_CONDUCT.md | 0 vendor/github.com/urfave/cli/{ => v2}/LICENSE | 0 .../github.com/urfave/cli/{ => v2}/README.md | 72 ++-- vendor/github.com/urfave/cli/{ => v2}/app.go | 154 ++++---- .../urfave/cli/{ => v2}/appveyor.yml | 2 +- vendor/github.com/urfave/cli/v2/args.go | 54 +++ vendor/github.com/urfave/cli/v2/category.go | 79 ++++ vendor/github.com/urfave/cli/{ => v2}/cli.go | 17 +- .../github.com/urfave/cli/{ => v2}/command.go | 196 +++------- vendor/github.com/urfave/cli/v2/context.go | 274 ++++++++++++++ vendor/github.com/urfave/cli/{ => v2}/docs.go | 14 +- .../github.com/urfave/cli/{ => v2}/errors.go | 62 ++-- vendor/github.com/urfave/cli/{ => v2}/fish.go | 14 +- vendor/github.com/urfave/cli/{ => v2}/flag.go | 236 +++++++----- .../urfave/cli/{ => v2}/flag_bool.go | 93 +++-- .../urfave/cli/{ => v2}/flag_duration.go | 87 +++-- .../urfave/cli/{ => v2}/flag_float64.go | 88 ++--- .../urfave/cli/v2/flag_float64_slice.go | 165 +++++++++ .../urfave/cli/{ => v2}/flag_generic.go | 70 ++-- .../urfave/cli/{ => v2}/flag_int.go | 61 ++-- .../urfave/cli/{ => v2}/flag_int64.go | 63 ++-- .../urfave/cli/v2/flag_int64_slice.go | 161 +++++++++ .../urfave/cli/v2/flag_int_slice.go | 175 +++++++++ vendor/github.com/urfave/cli/v2/flag_path.go | 95 +++++ .../urfave/cli/{ => v2}/flag_string.go | 53 ++- .../urfave/cli/v2/flag_string_slice.go | 159 ++++++++ .../urfave/cli/v2/flag_timestamp.go | 152 ++++++++ .../urfave/cli/{ => v2}/flag_uint.go | 61 ++-- .../urfave/cli/{ => v2}/flag_uint64.go | 87 +++-- .../github.com/urfave/cli/{ => v2}/funcs.go | 8 +- vendor/github.com/urfave/cli/{ => v2}/go.mod | 2 +- vendor/github.com/urfave/cli/{ => v2}/go.sum | 0 vendor/github.com/urfave/cli/{ => v2}/help.go | 47 +-- .../github.com/urfave/cli/{ => v2}/parse.go | 9 +- vendor/github.com/urfave/cli/{ => v2}/sort.go | 0 .../urfave/cli/{ => v2}/template.go | 8 +- vendor/modules.txt | 4 +- 57 files changed, 2151 insertions(+), 1776 deletions(-) delete mode 100644 vendor/github.com/urfave/cli/.travis.yml delete mode 100644 vendor/github.com/urfave/cli/category.go delete mode 100644 vendor/github.com/urfave/cli/context.go delete mode 100644 vendor/github.com/urfave/cli/flag_bool_t.go delete mode 100644 vendor/github.com/urfave/cli/flag_int64_slice.go delete mode 100644 vendor/github.com/urfave/cli/flag_int_slice.go delete mode 100644 vendor/github.com/urfave/cli/flag_string_slice.go rename vendor/github.com/urfave/cli/{ => v2}/.flake8 (100%) rename vendor/github.com/urfave/cli/{ => v2}/.gitignore (59%) rename vendor/github.com/urfave/cli/{ => v2}/CODE_OF_CONDUCT.md (100%) rename vendor/github.com/urfave/cli/{ => v2}/LICENSE (100%) rename vendor/github.com/urfave/cli/{ => v2}/README.md (58%) rename vendor/github.com/urfave/cli/{ => v2}/app.go (81%) rename vendor/github.com/urfave/cli/{ => v2}/appveyor.yml (96%) create mode 100644 vendor/github.com/urfave/cli/v2/args.go create mode 100644 vendor/github.com/urfave/cli/v2/category.go rename vendor/github.com/urfave/cli/{ => v2}/cli.go (67%) rename vendor/github.com/urfave/cli/{ => v2}/command.go (57%) create mode 100644 vendor/github.com/urfave/cli/v2/context.go rename vendor/github.com/urfave/cli/{ => v2}/docs.go (91%) rename vendor/github.com/urfave/cli/{ => v2}/errors.go (62%) rename vendor/github.com/urfave/cli/{ => v2}/fish.go (93%) rename vendor/github.com/urfave/cli/{ => v2}/flag.go (55%) rename vendor/github.com/urfave/cli/{ => v2}/flag_bool.go (51%) rename vendor/github.com/urfave/cli/{ => v2}/flag_duration.go (56%) rename vendor/github.com/urfave/cli/{ => v2}/flag_float64.go (56%) create mode 100644 vendor/github.com/urfave/cli/v2/flag_float64_slice.go rename vendor/github.com/urfave/cli/{ => v2}/flag_generic.go (52%) rename vendor/github.com/urfave/cli/{ => v2}/flag_int.go (56%) rename vendor/github.com/urfave/cli/{ => v2}/flag_int64.go (56%) create mode 100644 vendor/github.com/urfave/cli/v2/flag_int64_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_int_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_path.go rename vendor/github.com/urfave/cli/{ => v2}/flag_string.go (59%) create mode 100644 vendor/github.com/urfave/cli/v2/flag_string_slice.go create mode 100644 vendor/github.com/urfave/cli/v2/flag_timestamp.go rename vendor/github.com/urfave/cli/{ => v2}/flag_uint.go (56%) rename vendor/github.com/urfave/cli/{ => v2}/flag_uint64.go (56%) rename vendor/github.com/urfave/cli/{ => v2}/funcs.go (88%) rename vendor/github.com/urfave/cli/{ => v2}/go.mod (82%) rename vendor/github.com/urfave/cli/{ => v2}/go.sum (100%) rename vendor/github.com/urfave/cli/{ => v2}/help.go (91%) rename vendor/github.com/urfave/cli/{ => v2}/parse.go (88%) rename vendor/github.com/urfave/cli/{ => v2}/sort.go (100%) rename vendor/github.com/urfave/cli/{ => v2}/template.go (95%) diff --git a/cmd/flags.go b/cmd/flags.go index 0341745..21a684c 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -7,7 +7,7 @@ package cmd import ( "log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // create global variables for global Flags to simplify @@ -52,8 +52,8 @@ var OutputFlag = cli.StringFlag{ // subcommand to work around issue and provide --login and --output: // https://github.com/urfave/cli/issues/585 var LoginOutputFlags = []cli.Flag{ - LoginFlag, - OutputFlag, + &LoginFlag, + &OutputFlag, } // LoginRepoFlags defines login and repo flags that should @@ -61,9 +61,9 @@ var LoginOutputFlags = []cli.Flag{ // the subcommand to work around issue and provide --login and --repo: // https://github.com/urfave/cli/issues/585 var LoginRepoFlags = []cli.Flag{ - LoginFlag, - RepoFlag, - RemoteFlag, + &LoginFlag, + &RepoFlag, + &RemoteFlag, } // AllDefaultFlags defines flags that should be available @@ -71,8 +71,8 @@ var LoginRepoFlags = []cli.Flag{ // to work around issue and provide --login, --repo and --output: // https://github.com/urfave/cli/issues/585 var AllDefaultFlags = append([]cli.Flag{ - RepoFlag, - RemoteFlag, + &RepoFlag, + &RemoteFlag, }, LoginOutputFlags...) // initCommand returns repository and *Login based on flags diff --git a/cmd/issues.go b/cmd/issues.go index c70527a..a3ccecf 100644 --- a/cmd/issues.go +++ b/cmd/issues.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdIssues represents to login a gitea server. @@ -22,9 +22,9 @@ var CmdIssues = cli.Command{ Usage: "List and create issues", Description: `List and create issues`, Action: runIssues, - Subcommands: []cli.Command{ - CmdIssuesList, - CmdIssuesCreate, + Subcommands: []*cli.Command{ + &CmdIssuesList, + &CmdIssuesCreate, }, Flags: AllDefaultFlags, } @@ -124,11 +124,11 @@ var CmdIssuesCreate = cli.Command{ Description: `Create an issue on repository`, Action: runIssuesCreate, Flags: append([]cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "title, t", Usage: "issue title to create", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "body, b", Usage: "issue body to create", }, diff --git a/cmd/labels.go b/cmd/labels.go index d9afbfc..2419a93 100644 --- a/cmd/labels.go +++ b/cmd/labels.go @@ -14,7 +14,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdLabels represents to operate repositories' labels. @@ -23,13 +23,13 @@ var CmdLabels = cli.Command{ Usage: "Manage issue labels", Description: `Manage issue labels`, Action: runLabels, - Subcommands: []cli.Command{ - CmdLabelCreate, - CmdLabelUpdate, - CmdLabelDelete, + Subcommands: []*cli.Command{ + &CmdLabelCreate, + &CmdLabelUpdate, + &CmdLabelDelete, }, Flags: append([]cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "save, s", Usage: "Save all the labels as a file", }, @@ -94,19 +94,19 @@ var CmdLabelCreate = cli.Command{ Description: `Create a label`, Action: runLabelCreate, Flags: []cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "name", Usage: "label name", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "color", Usage: "label color value", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "description", Usage: "label description", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "file", Usage: "indicate a label file", }, @@ -186,19 +186,19 @@ var CmdLabelUpdate = cli.Command{ Description: `Update a label`, Action: runLabelUpdate, Flags: []cli.Flag{ - cli.IntFlag{ + &cli.IntFlag{ Name: "id", Usage: "label id", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "name", Usage: "label name", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "color", Usage: "label color value", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "description", Usage: "label description", }, @@ -246,7 +246,7 @@ var CmdLabelDelete = cli.Command{ Description: `Delete a label`, Action: runLabelCreate, Flags: []cli.Flag{ - cli.IntFlag{ + &cli.IntFlag{ Name: "id", Usage: "label id", }, diff --git a/cmd/login.go b/cmd/login.go index 803a2aa..771490e 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdLogin represents to login a gitea server. @@ -21,9 +21,9 @@ var CmdLogin = cli.Command{ Name: "login", Usage: "Log in to a Gitea server", Description: `Log in to a Gitea server`, - Subcommands: []cli.Command{ - cmdLoginList, - cmdLoginAdd, + Subcommands: []*cli.Command{ + &cmdLoginList, + &cmdLoginAdd, }, } @@ -33,23 +33,23 @@ var cmdLoginAdd = cli.Command{ Usage: "Add a Gitea login", Description: `Add a Gitea login`, Flags: []cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "name, n", Usage: "Login name", }, - cli.StringFlag{ - Name: "url, u", - Value: "https://try.gitea.io", - EnvVar: "GITEA_SERVER_URL", - Usage: "Server URL", + &cli.StringFlag{ + Name: "url, u", + Value: "https://try.gitea.io", + EnvVars: []string{"GITEA_SERVER_URL"}, + Usage: "Server URL", }, - cli.StringFlag{ - Name: "token, t", - Value: "", - EnvVar: "GITEA_SERVER_TOKEN", - Usage: "Access token. Can be obtained from Settings > Applications", + &cli.StringFlag{ + Name: "token, t", + Value: "", + EnvVars: []string{"GITEA_SERVER_TOKEN"}, + Usage: "Access token. Can be obtained from Settings > Applications", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "insecure, i", Usage: "Disable TLS verification", }, diff --git a/cmd/logout.go b/cmd/logout.go index e7eb3f7..0335bed 100644 --- a/cmd/logout.go +++ b/cmd/logout.go @@ -9,7 +9,7 @@ import ( "log" "os" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdLogout represents to logout a gitea server. @@ -19,7 +19,7 @@ var CmdLogout = cli.Command{ Description: `Log out from a Gitea server`, Action: runLogout, Flags: []cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "name, n", Usage: "Login name to remove", }, diff --git a/cmd/pulls.go b/cmd/pulls.go index 24e43de..50ffbe0 100644 --- a/cmd/pulls.go +++ b/cmd/pulls.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdPulls represents to login a gitea server. diff --git a/cmd/releases.go b/cmd/releases.go index c327d01..09b874f 100644 --- a/cmd/releases.go +++ b/cmd/releases.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdReleases represents to login a gitea server. @@ -20,8 +20,8 @@ var CmdReleases = cli.Command{ Usage: "Create releases", Description: `Create releases`, Action: runReleases, - Subcommands: []cli.Command{ - CmdReleaseCreate, + Subcommands: []*cli.Command{ + &CmdReleaseCreate, }, Flags: AllDefaultFlags, } @@ -71,31 +71,31 @@ var CmdReleaseCreate = cli.Command{ Description: `Create a release`, Action: runReleaseCreate, Flags: append([]cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "tag", Usage: "Tag name", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "target", Usage: "Target refs, branch name or commit id", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "title, t", Usage: "Release title", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "note, n", Usage: "Release notes", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "draft, d", Usage: "Is a draft", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "prerelease, p", Usage: "Is a pre-release", }, - cli.StringSliceFlag{ + &cli.StringSliceFlag{ Name: "asset, a", Usage: "List of files to attach", }, diff --git a/cmd/repos.go b/cmd/repos.go index 2ef04cb..8bfd364 100644 --- a/cmd/repos.go +++ b/cmd/repos.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/sdk/gitea" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // CmdRepos represents to login a gitea server. @@ -18,8 +18,8 @@ var CmdRepos = cli.Command{ Usage: "Operate with repositories", Description: `Operate with repositories`, Action: runReposList, - Subcommands: []cli.Command{ - CmdReposList, + Subcommands: []*cli.Command{ + &CmdReposList, }, Flags: LoginOutputFlags, } @@ -31,15 +31,15 @@ var CmdReposList = cli.Command{ Description: `List available repositories`, Action: runReposList, Flags: append([]cli.Flag{ - cli.StringFlag{ + &cli.StringFlag{ Name: "mode", Usage: "Filter listed repositories based on mode, optional - fork, mirror, source", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "org", Usage: "Filter listed repositories based on organization, optional", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "user", Usage: "Filter listed repositories absed on user, optional", }, diff --git a/go.mod b/go.mod index eed03a4..e9509b9 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/olekukonko/tablewriter v0.0.1 github.com/stretchr/testify v1.4.0 - github.com/urfave/cli v1.22.2 + github.com/urfave/cli/v2 v2.1.1 gopkg.in/src-d/go-git.v4 v4.13.1 gopkg.in/yaml.v2 v2.2.7 // indirect ) diff --git a/go.sum b/go.sum index 1287c95..7e99204 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= +github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/main.go b/main.go index 05c506f..1b22a43 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/tea/cmd" "code.gitea.io/tea/modules/setting" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) // Version holds the current Gitea version @@ -33,14 +33,14 @@ func main() { app.Usage = "Command line tool to interact with Gitea" app.Description = `` app.Version = Version + formatBuiltWith(Tags) - app.Commands = []cli.Command{ - cmd.CmdLogin, - cmd.CmdLogout, - cmd.CmdIssues, - cmd.CmdPulls, - cmd.CmdReleases, - cmd.CmdRepos, - cmd.CmdLabels, + app.Commands = []*cli.Command{ + &cmd.CmdLogin, + &cmd.CmdLogout, + &cmd.CmdIssues, + &cmd.CmdPulls, + &cmd.CmdReleases, + &cmd.CmdRepos, + &cmd.CmdLabels, } app.EnableBashCompletion = true err := app.Run(os.Args) diff --git a/vendor/github.com/urfave/cli/.travis.yml b/vendor/github.com/urfave/cli/.travis.yml deleted file mode 100644 index d36c224..0000000 --- a/vendor/github.com/urfave/cli/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: go -sudo: false -dist: bionic -osx_image: xcode10 -go: - - 1.11.x - - 1.12.x - - 1.13.x - -os: - - linux - - osx - -env: - GO111MODULE=on - GOPROXY=https://proxy.golang.org - -cache: - directories: - - node_modules - -before_script: - - go get github.com/urfave/gfmrun/cmd/gfmrun - - go get golang.org/x/tools/cmd/goimports - - npm install markdown-toc - - go mod tidy - -script: - - go run build.go vet - - go run build.go test - - go run build.go gfmrun docs/v1/manual.md - - go run build.go toc docs/v1/manual.md - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/urfave/cli/category.go b/vendor/github.com/urfave/cli/category.go deleted file mode 100644 index bf3c73c..0000000 --- a/vendor/github.com/urfave/cli/category.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -// CommandCategories is a slice of *CommandCategory. -type CommandCategories []*CommandCategory - -// CommandCategory is a category containing commands. -type CommandCategory struct { - Name string - Commands Commands -} - -func (c CommandCategories) Less(i, j int) bool { - return lexicographicLess(c[i].Name, c[j].Name) -} - -func (c CommandCategories) Len() int { - return len(c) -} - -func (c CommandCategories) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -// AddCommand adds a command to a category. -func (c CommandCategories) AddCommand(category string, command Command) CommandCategories { - for _, commandCategory := range c { - if commandCategory.Name == category { - commandCategory.Commands = append(commandCategory.Commands, command) - return c - } - } - return append(c, &CommandCategory{Name: category, Commands: []Command{command}}) -} - -// VisibleCommands returns a slice of the Commands with Hidden=false -func (c *CommandCategory) VisibleCommands() []Command { - ret := []Command{} - for _, command := range c.Commands { - if !command.Hidden { - ret = append(ret, command) - } - } - return ret -} diff --git a/vendor/github.com/urfave/cli/context.go b/vendor/github.com/urfave/cli/context.go deleted file mode 100644 index ecfc032..0000000 --- a/vendor/github.com/urfave/cli/context.go +++ /dev/null @@ -1,339 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "fmt" - "os" - "reflect" - "strings" - "syscall" -) - -// 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 { - App *App - Command Command - shellComplete bool - flagSet *flag.FlagSet - setFlags map[string]bool - 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.shellComplete = parentCtx.shellComplete - } - - return c -} - -// NumFlags returns the number of flags set -func (c *Context) NumFlags() int { - return c.flagSet.NFlag() -} - -// Set sets a context flag to a value. -func (c *Context) Set(name, value string) error { - c.setFlags = nil - return c.flagSet.Set(name, value) -} - -// GlobalSet sets a context flag to a value on the global flagset -func (c *Context) GlobalSet(name, value string) error { - globalContext(c).setFlags = nil - return globalContext(c).flagSet.Set(name, value) -} - -// IsSet determines if the flag was actually set -func (c *Context) IsSet(name string) bool { - if c.setFlags == nil { - c.setFlags = make(map[string]bool) - - c.flagSet.Visit(func(f *flag.Flag) { - c.setFlags[f.Name] = true - }) - - c.flagSet.VisitAll(func(f *flag.Flag) { - if _, ok := c.setFlags[f.Name]; ok { - return - } - c.setFlags[f.Name] = false - }) - - // XXX hack to support IsSet for flags with EnvVar - // - // There isn't an easy way to do this with the current implementation since - // whether a flag was set via an environment variable is very difficult to - // determine here. Instead, we intend to introduce a backwards incompatible - // change in version 2 to add `IsSet` to the Flag interface to push the - // responsibility closer to where the information required to determine - // whether a flag is set by non-standard means such as environment - // variables is available. - // - // See https://github.com/urfave/cli/issues/294 for additional discussion - flags := c.Command.Flags - if c.Command.Name == "" { // cannot == Command{} since it contains slice types - if c.App != nil { - flags = c.App.Flags - } - } - for _, f := range flags { - eachName(f.GetName(), func(name string) { - if isSet, ok := c.setFlags[name]; isSet || !ok { - return - } - - val := reflect.ValueOf(f) - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - - filePathValue := val.FieldByName("FilePath") - if filePathValue.IsValid() { - eachName(filePathValue.String(), func(filePath string) { - if _, err := os.Stat(filePath); err == nil { - c.setFlags[name] = true - return - } - }) - } - - envVarValue := val.FieldByName("EnvVar") - if envVarValue.IsValid() { - eachName(envVarValue.String(), func(envVar string) { - envVar = strings.TrimSpace(envVar) - if _, ok := syscall.Getenv(envVar); ok { - c.setFlags[name] = true - return - } - }) - } - }) - } - } - - return c.setFlags[name] -} - -// GlobalIsSet determines if the global flag was actually set -func (c *Context) GlobalIsSet(name string) bool { - ctx := c - if ctx.parentContext != nil { - ctx = ctx.parentContext - } - - for ; ctx != nil; ctx = ctx.parentContext { - if ctx.IsSet(name) { - return true - } - } - return false -} - -// FlagNames returns a slice of flag names used in this context. -func (c *Context) FlagNames() (names []string) { - for _, f := range c.Command.Flags { - name := strings.Split(f.GetName(), ",")[0] - if name == "help" { - continue - } - names = append(names, name) - } - return -} - -// GlobalFlagNames returns a slice of global flag names used by the app. -func (c *Context) GlobalFlagNames() (names []string) { - for _, f := range c.App.Flags { - name := strings.Split(f.GetName(), ",")[0] - if name == "help" || name == "version" { - continue - } - names = append(names, name) - } - return -} - -// Parent returns the parent context, if any -func (c *Context) Parent() *Context { - return c.parentContext -} - -// value returns the value of the flag coressponding to `name` -func (c *Context) value(name string) interface{} { - return c.flagSet.Lookup(name).Value.(flag.Getter).Get() -} - -// Args contains apps console arguments -type Args []string - -// Args returns the command line arguments associated with the context. -func (c *Context) Args() Args { - args := Args(c.flagSet.Args()) - return args -} - -// NArg returns the number of the command line arguments. -func (c *Context) NArg() int { - return len(c.Args()) -} - -// Get returns the nth argument, or else a blank string -func (a Args) Get(n int) string { - if len(a) > n { - return a[n] - } - return "" -} - -// First returns the first argument, or else a blank string -func (a Args) First() string { - return a.Get(0) -} - -// Tail returns the rest of the arguments (not the first one) -// or else an empty string slice -func (a Args) Tail() []string { - if len(a) >= 2 { - return []string(a)[1:] - } - return []string{} -} - -// Present checks if there are any arguments present -func (a Args) Present() bool { - return len(a) != 0 -} - -// Swap swaps arguments at the given indexes -func (a Args) Swap(from, to int) error { - if from >= len(a) || to >= len(a) { - return errors.New("index out of range") - } - a[from], a[to] = a[to], a[from] - return nil -} - -func globalContext(ctx *Context) *Context { - if ctx == nil { - return nil - } - - for { - if ctx.parentContext == nil { - return ctx - } - ctx = ctx.parentContext - } -} - -func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { - if ctx.parentContext != nil { - ctx = ctx.parentContext - } - for ; ctx != nil; ctx = ctx.parentContext { - if f := ctx.flagSet.Lookup(name); f != nil { - return ctx.flagSet - } - } - return nil -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - switch ff.Value.(type) { - case *StringSlice: - 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 := strings.Split(f.GetName(), ",") - 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 -} - -type requiredFlagsErr interface { - error - getMissingFlags() []string -} - -type errRequiredFlags struct { - missingFlags []string -} - -func (e *errRequiredFlags) Error() string { - numberOfMissingFlags := len(e.missingFlags) - if numberOfMissingFlags == 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 -} - -func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr { - var missingFlags []string - for _, f := range flags { - if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() { - var flagPresent bool - var flagName string - for _, key := range strings.Split(f.GetName(), ",") { - if len(key) > 1 { - flagName = key - } - - if context.IsSet(strings.TrimSpace(key)) { - flagPresent = true - } - } - - if !flagPresent && flagName != "" { - missingFlags = append(missingFlags, flagName) - } - } - } - - if len(missingFlags) != 0 { - return &errRequiredFlags{missingFlags: missingFlags} - } - - return nil -} diff --git a/vendor/github.com/urfave/cli/flag_bool_t.go b/vendor/github.com/urfave/cli/flag_bool_t.go deleted file mode 100644 index cd0888f..0000000 --- a/vendor/github.com/urfave/cli/flag_bool_t.go +++ /dev/null @@ -1,110 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "strconv" -) - -// BoolTFlag is a flag with type bool that is true by default -type BoolTFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Destination *bool -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f BoolTFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f BoolTFlag) GetName() string { - return f.Name -} - -// IsRequired returns whether or not the flag is required -func (f BoolTFlag) IsRequired() bool { - return f.Required -} - -// TakesValue returns true of the flag takes a value, otherwise false -func (f BoolTFlag) TakesValue() bool { - return false -} - -// GetUsage returns the usage string for the flag -func (f BoolTFlag) GetUsage() string { - return f.Usage -} - -// GetValue returns the flags value as string representation and an empty -// string if the flag takes no value at all. -func (f BoolTFlag) GetValue() string { - return "" -} - -// BoolT looks up the value of a local BoolTFlag, returns -// false if not found -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// GlobalBoolT looks up the value of a global BoolTFlag, returns -// false if not found -func (c *Context) GlobalBoolT(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupBoolT(name, fs) - } - return false -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolTFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { - val := true - - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - if envVal == "" { - val = false - } else { - envValBool, err := strconv.ParseBool(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) - } - val = envValBool - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.BoolVar(f.Destination, name, val, f.Usage) - return - } - set.Bool(name, val, f.Usage) - }) - - return nil -} - -func lookupBoolT(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 -} diff --git a/vendor/github.com/urfave/cli/flag_int64_slice.go b/vendor/github.com/urfave/cli/flag_int64_slice.go deleted file mode 100644 index ed2e983..0000000 --- a/vendor/github.com/urfave/cli/flag_int64_slice.go +++ /dev/null @@ -1,141 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "strconv" - "strings" -) - -// Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter -type Int64Slice []int64 - -// Set parses the value into an integer and appends it to the list of values -func (f *Int64Slice) Set(value string) error { - tmp, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return err - } - *f = append(*f, tmp) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *Int64Slice) String() string { - return fmt.Sprintf("%#v", *f) -} - -// Value returns the slice of ints set by this flag -func (f *Int64Slice) Value() []int64 { - return *f -} - -// Get returns the slice of ints set by this flag -func (f *Int64Slice) Get() interface{} { - return *f -} - -// Int64SliceFlag is a flag with type *Int64Slice -type Int64SliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value *Int64Slice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f Int64SliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f Int64SliceFlag) GetName() string { - return f.Name -} - -// IsRequired returns whether or not the flag is required -func (f Int64SliceFlag) IsRequired() bool { - return f.Required -} - -// 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 -} - -// 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 { - if f.Value != nil { - return f.Value.String() - } - return "" -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64SliceFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - newVal := &Int64Slice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err) - } - } - if f.Value == nil { - f.Value = newVal - } else { - *f.Value = *newVal - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &Int64Slice{} - } - set.Var(f.Value, name, f.Usage) - }) - return nil -} - -// Int64Slice looks up the value of a local Int64SliceFlag, returns -// nil if not found -func (c *Context) Int64Slice(name string) []int64 { - return lookupInt64Slice(name, c.flagSet) -} - -// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns -// nil if not found -func (c *Context) GlobalInt64Slice(name string) []int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt64Slice(name, fs) - } - return nil -} - -func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} diff --git a/vendor/github.com/urfave/cli/flag_int_slice.go b/vendor/github.com/urfave/cli/flag_int_slice.go deleted file mode 100644 index c38d010..0000000 --- a/vendor/github.com/urfave/cli/flag_int_slice.go +++ /dev/null @@ -1,142 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "strconv" - "strings" -) - -// IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter -type IntSlice []int - -// Set parses the value into an integer and appends it to the list of values -func (f *IntSlice) Set(value string) error { - tmp, err := strconv.Atoi(value) - if err != nil { - return err - } - *f = append(*f, tmp) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *IntSlice) String() string { - return fmt.Sprintf("%#v", *f) -} - -// Value returns the slice of ints set by this flag -func (f *IntSlice) Value() []int { - return *f -} - -// Get returns the slice of ints set by this flag -func (f *IntSlice) Get() interface{} { - return *f -} - -// IntSliceFlag is a flag with type *IntSlice -type IntSliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value *IntSlice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f IntSliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f IntSliceFlag) GetName() string { - return f.Name -} - -// IsRequired returns whether or not the flag is required -func (f IntSliceFlag) IsRequired() bool { - return f.Required -} - -// 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 -} - -// 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 { - if f.Value != nil { - return f.Value.String() - } - return "" -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - newVal := &IntSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err) - } - } - if f.Value == nil { - f.Value = newVal - } else { - *f.Value = *newVal - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &IntSlice{} - } - set.Var(f.Value, name, f.Usage) - }) - - return nil -} - -// IntSlice looks up the value of a local IntSliceFlag, returns -// nil if not found -func (c *Context) IntSlice(name string) []int { - return lookupIntSlice(name, c.flagSet) -} - -// GlobalIntSlice looks up the value of a global IntSliceFlag, returns -// nil if not found -func (c *Context) GlobalIntSlice(name string) []int { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupIntSlice(name, fs) - } - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} diff --git a/vendor/github.com/urfave/cli/flag_string_slice.go b/vendor/github.com/urfave/cli/flag_string_slice.go deleted file mode 100644 index e865b2f..0000000 --- a/vendor/github.com/urfave/cli/flag_string_slice.go +++ /dev/null @@ -1,138 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "strings" -) - -// StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter -type StringSlice []string - -// Set appends the string value to the list of values -func (f *StringSlice) Set(value string) error { - *f = append(*f, value) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *StringSlice) String() string { - return fmt.Sprintf("%s", *f) -} - -// Value returns the slice of strings set by this flag -func (f *StringSlice) Value() []string { - return *f -} - -// Get returns the slice of strings set by this flag -func (f *StringSlice) Get() interface{} { - return *f -} - -// StringSliceFlag is a flag with type *StringSlice -type StringSliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - TakesFile bool - Value *StringSlice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f StringSliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f StringSliceFlag) GetName() string { - return f.Name -} - -// IsRequired returns whether or not the flag is required -func (f StringSliceFlag) IsRequired() bool { - return f.Required -} - -// 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 -} - -// 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 { - if f.Value != nil { - return f.Value.String() - } - return "" -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - newVal := &StringSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err) - } - } - if f.Value == nil { - f.Value = newVal - } else { - *f.Value = *newVal - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &StringSlice{} - } - set.Var(f.Value, name, f.Usage) - }) - - return nil -} - -// StringSlice looks up the value of a local StringSliceFlag, returns -// nil if not found -func (c *Context) StringSlice(name string) []string { - return lookupStringSlice(name, c.flagSet) -} - -// GlobalStringSlice looks up the value of a global StringSliceFlag, returns -// nil if not found -func (c *Context) GlobalStringSlice(name string) []string { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupStringSlice(name, fs) - } - return nil -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} diff --git a/vendor/github.com/urfave/cli/.flake8 b/vendor/github.com/urfave/cli/v2/.flake8 similarity index 100% rename from vendor/github.com/urfave/cli/.flake8 rename to vendor/github.com/urfave/cli/v2/.flake8 diff --git a/vendor/github.com/urfave/cli/.gitignore b/vendor/github.com/urfave/cli/v2/.gitignore similarity index 59% rename from vendor/github.com/urfave/cli/.gitignore rename to vendor/github.com/urfave/cli/v2/.gitignore index 7a7e2d9..b013e4a 100644 --- a/vendor/github.com/urfave/cli/.gitignore +++ b/vendor/github.com/urfave/cli/v2/.gitignore @@ -1,3 +1,5 @@ *.coverprofile +*.orig node_modules/ -vendor \ No newline at end of file +vendor +.idea diff --git a/vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md b/vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md similarity index 100% rename from vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md rename to vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md diff --git a/vendor/github.com/urfave/cli/LICENSE b/vendor/github.com/urfave/cli/v2/LICENSE similarity index 100% rename from vendor/github.com/urfave/cli/LICENSE rename to vendor/github.com/urfave/cli/v2/LICENSE diff --git a/vendor/github.com/urfave/cli/README.md b/vendor/github.com/urfave/cli/v2/README.md similarity index 58% rename from vendor/github.com/urfave/cli/README.md rename to vendor/github.com/urfave/cli/v2/README.md index b2abbcf..e7fb3d7 100644 --- a/vendor/github.com/urfave/cli/README.md +++ b/vendor/github.com/urfave/cli/v2/README.md @@ -1,7 +1,6 @@ cli === -[![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) [![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) @@ -15,15 +14,44 @@ applications in an expressive way. ## Usage Documentation -Usage documentation exists for each major version +Usage documentation exists for each major version. Don't know what version you're on? You're probably using the version from the `master` branch, which is currently `v2`. +- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md) - `v1` - [./docs/v1/manual.md](./docs/v1/manual.md) -- `v2` - 🚧 documentation for `v2` is WIP 🚧 ## Installation -Make sure you have a working Go environment. Go version 1.10+ is supported. [See -the install instructions for Go](http://golang.org/doc/install.html). +Make sure you have a working Go environment. Go version 1.11+ is supported. [See the install instructions for Go](http://golang.org/doc/install.html). + +Go Modules are strongly recommended when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules). + +### Using `v2` releases + +``` +$ GO111MODULE=on go get github.com/urfave/cli/v2 +``` + +```go +... +import ( + "github.com/urfave/cli/v2" // imports as package "cli" +) +... +``` + +### Using `v1` releases + +``` +$ GO111MODULE=on go get github.com/urfave/cli +``` + +```go +... +import ( + "github.com/urfave/cli" +) +... +``` ### GOPATH @@ -36,35 +64,5 @@ export PATH=$PATH:$GOPATH/bin ### Supported platforms cli is tested against multiple versions of Go on Linux, and against the latest -released version of Go on OS X and Windows. For full details, see -[`./.travis.yml`](./.travis.yml) and [`./appveyor.yml`](./appveyor.yml). - -### Using `v1` releases - -``` -$ go get github.com/urfave/cli -``` - -```go -... -import ( - "github.com/urfave/cli" -) -... -``` - -### Using `v2` releases - -**Warning**: `v2` is in a pre-release state. - -``` -$ go get github.com/urfave/cli.v2 -``` - -```go -... -import ( - "github.com/urfave/cli.v2" // imports as package "cli" -) -... -``` +released version of Go on OS X and Windows. This project uses Github Actions for +builds. For more build info, please look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml). diff --git a/vendor/github.com/urfave/cli/app.go b/vendor/github.com/urfave/cli/v2/app.go similarity index 81% rename from vendor/github.com/urfave/cli/app.go rename to vendor/github.com/urfave/cli/v2/app.go index 95d2038..c04e9af 100644 --- a/vendor/github.com/urfave/cli/app.go +++ b/vendor/github.com/urfave/cli/v2/app.go @@ -1,24 +1,22 @@ package cli import ( + "context" "flag" "fmt" "io" "os" "path/filepath" + "reflect" "sort" "time" ) var ( - changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md" + changeLogURL = "https://github.com/urfave/cli/blob/master/docs/CHANGELOG.md" appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) - // unused variable. commented for now. will remove in future if agreed upon by everyone - //runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) - - contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you." - - errInvalidActionType = NewExitError("ERROR invalid Action type. "+ + 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) ) @@ -41,7 +39,7 @@ type App struct { // Description of the program Description string // List of commands to execute - Commands []Command + Commands []*Command // List of flags to parse Flags []Flag // Boolean to enable bash completion commands @@ -50,9 +48,9 @@ type App struct { HideHelp bool // Boolean to hide built-in version flag and the VERSION section of help HideVersion bool - // Populate on app startup, only gettable through method Categories() + // categories contains the categorized commands and is populated on app startup categories CommandCategories - // An action to execute when the bash-completion flag is set + // 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 @@ -60,12 +58,8 @@ type App struct { // 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 - // Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}` - // *Note*: support for the deprecated `Action` signature will be removed in a future version - Action interface{} - + Action ActionFunc // Execute this function if the proper command cannot be found CommandNotFound CommandNotFoundFunc // Execute this function if an usage error occurs @@ -73,13 +67,9 @@ type App struct { // Compilation date Compiled time.Time // List of all authors who contributed - Authors []Author + Authors []*Author // Copyright of the binary if any Copyright string - // Name of Author (Note: Use App.Authors, this is deprecated) - Author string - // Email of Author (Note: Use App.Authors, this is deprecated) - Email string // Writer writer to write output to Writer io.Writer // ErrWriter writes error output @@ -96,7 +86,7 @@ type App struct { // render custom help text by setting this variable. CustomAppHelpTemplate string // Boolean to enable short-option handling so user can combine several - // single-character bool arguements into one + // single-character bool arguments into one // i.e. foobar -o -v -> foobar -ov UseShortOptionHandling bool @@ -121,7 +111,6 @@ func NewApp() *App { HelpName: filepath.Base(os.Args[0]), Usage: "A new cli application", UsageText: "", - Version: "0.0.0", BashComplete: DefaultAppComplete, Action: helpCommand.Action, Compiled: compileTime(), @@ -139,22 +128,52 @@ func (a *App) Setup() { a.didSetup = true - if a.Author != "" || a.Email != "" { - a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) + if a.Name == "" { + a.Name = filepath.Base(os.Args[0]) } - var newCmds []Command + if a.HelpName == "" { + a.HelpName = filepath.Base(os.Args[0]) + } + + 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.Writer == nil { + a.Writer = os.Stdout + } + + var newCommands []*Command + for _, c := range a.Commands { if c.HelpName == "" { c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) } - newCmds = append(newCmds, c) + newCommands = append(newCommands, c) } - a.Commands = newCmds + a.Commands = newCommands if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { + a.appendCommand(helpCommand) + + if HelpFlag != nil { a.appendFlag(HelpFlag) } } @@ -163,11 +182,11 @@ func (a *App) Setup() { a.appendFlag(VersionFlag) } - a.categories = CommandCategories{} + a.categories = newCommandCategories() for _, command := range a.Commands { - a.categories = a.categories.AddCommand(command.Category, command) + a.categories.AddCommand(command.Category, command) } - sort.Sort(a.categories) + sort.Sort(a.categories.(*commandCategories)) if a.Metadata == nil { a.Metadata = make(map[string]interface{}) @@ -189,6 +208,13 @@ func (a *App) useShortOptionHandling() bool { // 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 @@ -204,9 +230,9 @@ func (a *App) Run(arguments []string) (err error) { return err } - err = parseIter(set, a, arguments[1:]) + err = parseIter(set, a, arguments[1:], shellComplete) nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, nil) + context := NewContext(a, set, &Context{Context: ctx}) if nerr != nil { _, _ = fmt.Fprintln(a.Writer, nerr) _ = ShowAppHelp(context) @@ -249,7 +275,7 @@ func (a *App) Run(arguments []string) (err error) { defer func() { if afterErr := a.After(context); afterErr != nil { if err != nil { - err = NewMultiError(err, afterErr) + err = newMultiError(err, afterErr) } else { err = afterErr } @@ -282,7 +308,7 @@ func (a *App) Run(arguments []string) (err error) { } // Run default Action - err = HandleAction(a.Action, context) + err = a.Action(context) a.handleExitCoder(context, err) return err @@ -303,17 +329,20 @@ 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) { + a.Setup() + // append help to commands if len(a.Commands) > 0 { if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { + a.appendCommand(helpCommand) + + if HelpFlag != nil { a.appendFlag(HelpFlag) } } } - newCmds := []Command{} + var newCmds []*Command for _, c := range a.Commands { if c.HelpName == "" { c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) @@ -327,7 +356,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { return err } - err = parseIter(set, a, ctx.Args().Tail()) + err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete) nerr := normalizeFlags(a.Flags, set) context := NewContext(a, set, ctx) @@ -379,7 +408,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { if afterErr != nil { a.handleExitCoder(context, err) if err != nil { - err = NewMultiError(err, afterErr) + err = newMultiError(err, afterErr) } else { err = afterErr } @@ -406,7 +435,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { } // Run default Action - err = HandleAction(a.Action, context) + err = a.Action(context) a.handleExitCoder(context, err) return err @@ -416,28 +445,21 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { func (a *App) Command(name string) *Command { for _, c := range a.Commands { if c.HasName(name) { - return &c + return c } } return nil } -// Categories returns a slice containing all the categories with the commands they contain -func (a *App) Categories() CommandCategories { - return a.categories -} - // VisibleCategories returns a slice of categories and commands that are // Hidden=false -func (a *App) VisibleCategories() []*CommandCategory { - ret := []*CommandCategory{} - for _, category := range a.categories { - if visible := func() *CommandCategory { - for _, command := range category.Commands { - if !command.Hidden { - return category - } +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 { @@ -448,8 +470,8 @@ func (a *App) VisibleCategories() []*CommandCategory { } // VisibleCommands returns a slice of the Commands with Hidden=false -func (a *App) VisibleCommands() []Command { - var ret []Command +func (a *App) VisibleCommands() []*Command { + var ret []*Command for _, command := range a.Commands { if !command.Hidden { ret = append(ret, command) @@ -465,7 +487,7 @@ func (a *App) VisibleFlags() []Flag { func (a *App) hasFlag(flag Flag) bool { for _, f := range a.Flags { - if flag == f { + if reflect.DeepEqual(flag, f) { return true } } @@ -482,9 +504,15 @@ func (a *App) errWriter() io.Writer { return a.ErrWriter } -func (a *App) appendFlag(flag Flag) { - if !a.hasFlag(flag) { - a.Flags = append(a.Flags, flag) +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) } } @@ -503,7 +531,7 @@ type Author struct { } // String makes Author comply to the Stringer interface, to allow an easy print in the templating process -func (a Author) String() string { +func (a *Author) String() string { e := "" if a.Email != "" { e = " <" + a.Email + ">" diff --git a/vendor/github.com/urfave/cli/appveyor.yml b/vendor/github.com/urfave/cli/v2/appveyor.yml similarity index 96% rename from vendor/github.com/urfave/cli/appveyor.yml rename to vendor/github.com/urfave/cli/v2/appveyor.yml index 8ef2fea..f1cae90 100644 --- a/vendor/github.com/urfave/cli/appveyor.yml +++ b/vendor/github.com/urfave/cli/v2/appveyor.yml @@ -20,7 +20,7 @@ install: - go version - go env - go get github.com/urfave/gfmrun/cmd/gfmrun - - go mod vendor + - go mod tidy build_script: - go run build.go vet diff --git a/vendor/github.com/urfave/cli/v2/args.go b/vendor/github.com/urfave/cli/v2/args.go new file mode 100644 index 0000000..bd65c17 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/args.go @@ -0,0 +1,54 @@ +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 +} diff --git a/vendor/github.com/urfave/cli/v2/category.go b/vendor/github.com/urfave/cli/v2/category.go new file mode 100644 index 0000000..867e390 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/category.go @@ -0,0 +1,79 @@ +package cli + +// CommandCategories interface allows for category manipulation +type CommandCategories interface { + // AddCommand adds a command to a category, creating a new category if necessary. + AddCommand(category string, command *Command) + // categories returns a copy of the category slice + Categories() []CommandCategory +} + +type commandCategories []*commandCategory + +func newCommandCategories() CommandCategories { + ret := commandCategories([]*commandCategory{}) + return &ret +} + +func (c *commandCategories) Less(i, j int) bool { + return lexicographicLess((*c)[i].Name(), (*c)[j].Name()) +} + +func (c *commandCategories) Len() int { + return len(*c) +} + +func (c *commandCategories) Swap(i, j int) { + (*c)[i], (*c)[j] = (*c)[j], (*c)[i] +} + +func (c *commandCategories) AddCommand(category string, command *Command) { + for _, commandCategory := range []*commandCategory(*c) { + if commandCategory.name == category { + commandCategory.commands = append(commandCategory.commands, command) + return + } + } + newVal := append(*c, + &commandCategory{name: category, commands: []*Command{command}}) + *c = newVal +} + +func (c *commandCategories) Categories() []CommandCategory { + ret := make([]CommandCategory, len(*c)) + for i, cat := range *c { + ret[i] = cat + } + return ret +} + +// CommandCategory is a category containing commands. +type CommandCategory interface { + // Name returns the category name string + Name() string + // VisibleCommands returns a slice of the Commands with Hidden=false + VisibleCommands() []*Command +} + +type commandCategory struct { + name string + commands []*Command +} + +func (c *commandCategory) Name() string { + return c.name +} + +func (c *commandCategory) VisibleCommands() []*Command { + if c.commands == nil { + c.commands = []*Command{} + } + + var ret []*Command + for _, command := range c.commands { + if !command.Hidden { + ret = append(ret, command) + } + } + return ret +} diff --git a/vendor/github.com/urfave/cli/cli.go b/vendor/github.com/urfave/cli/v2/cli.go similarity index 67% rename from vendor/github.com/urfave/cli/cli.go rename to vendor/github.com/urfave/cli/v2/cli.go index 4bd2508..62a5bc2 100644 --- a/vendor/github.com/urfave/cli/cli.go +++ b/vendor/github.com/urfave/cli/v2/cli.go @@ -2,18 +2,19 @@ // 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.NewApp().Run(os.Args) +// (&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.NewApp() -// app.Name = "greet" -// app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) error { -// println("Greetings") -// return nil -// } +// app := &cli.App{ +// Name: "greet", +// Usage: "say a greeting", +// Action: func(c *cli.Context) error { +// fmt.Println("Greetings") +// return nil +// }, +// } // // app.Run(os.Args) // } diff --git a/vendor/github.com/urfave/cli/command.go b/vendor/github.com/urfave/cli/v2/command.go similarity index 57% rename from vendor/github.com/urfave/cli/command.go rename to vendor/github.com/urfave/cli/v2/command.go index e7cb97a..db6c802 100644 --- a/vendor/github.com/urfave/cli/command.go +++ b/vendor/github.com/urfave/cli/v2/command.go @@ -11,8 +11,6 @@ import ( type Command struct { // The name of the command Name string - // short name of the command. Typically one character (deprecated, use `Aliases`) - ShortName string // A list of aliases for the command Aliases []string // A short description of the usage of this command @@ -34,23 +32,15 @@ type Command struct { // It is run even if Action() panics After AfterFunc // The function to call when this command is invoked - Action interface{} - // TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind - // of deprecation period has passed, maybe? - + Action ActionFunc // Execute this function if a usage error occurs. OnUsageError OnUsageErrorFunc // List of child commands - Subcommands Commands + Subcommands []*Command // List of flags to parse Flags []Flag // Treat all flags as normal arguments if true SkipFlagParsing bool - // Skip argument reordering which attempts to move flags before arguments, - // but only works if all flags appear after all arguments. This behavior was - // removed n version 2 since it only works under specific conditions so we - // backport here by exposing it as an option for compatibility. - SkipArgReorder bool // Boolean to hide built-in help command HideHelp bool // Boolean to hide this command from help or completion @@ -70,7 +60,9 @@ type Command struct { CustomHelpTemplate string } -type CommandsByName []Command +type Commands []*Command + +type CommandsByName []*Command func (c CommandsByName) Len() int { return len(c) @@ -86,35 +78,29 @@ func (c CommandsByName) Swap(i, j int) { // 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 { +func (c *Command) FullName() string { if c.commandNamePath == nil { return c.Name } return strings.Join(c.commandNamePath, " ") } -// Commands is a slice of Command -type Commands []Command - // Run invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c Command) Run(ctx *Context) (err error) { +func (c *Command) Run(ctx *Context) (err error) { if len(c.Subcommands) > 0 { return c.startApp(ctx) } - if !c.HideHelp && (HelpFlag != BoolFlag{}) { + if !c.HideHelp && HelpFlag != nil { // append help to flags - c.Flags = append( - c.Flags, - HelpFlag, - ) + c.appendFlag(HelpFlag) } if ctx.App.UseShortOptionHandling { c.UseShortOptionHandling = true } - set, err := c.parseFlags(ctx.Args().Tail()) + set, err := c.parseFlags(ctx.Args(), ctx.shellComplete) context := NewContext(ctx.App, set, ctx) context.Command = c @@ -124,7 +110,7 @@ func (c Command) Run(ctx *Context) (err error) { if err != nil { if c.OnUsageError != nil { - err := c.OnUsageError(context, err, false) + err = c.OnUsageError(context, err, false) context.App.handleExitCoder(context, err) return err } @@ -150,7 +136,7 @@ func (c Command) Run(ctx *Context) (err error) { if afterErr != nil { context.App.handleExitCoder(context, err) if err != nil { - err = NewMultiError(err, afterErr) + err = newMultiError(err, afterErr) } else { err = afterErr } @@ -171,7 +157,8 @@ func (c Command) Run(ctx *Context) (err error) { c.Action = helpSubcommand.Action } - err = HandleAction(c.Action, context) + context.Command = c + err = c.Action(context) if err != nil { context.App.handleExitCoder(context, err) @@ -179,26 +166,25 @@ func (c Command) Run(ctx *Context) (err error) { return err } -func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) { - if c.SkipFlagParsing { - set, err := c.newFlagSet() - if err != nil { - return nil, err - } +func (c *Command) newFlagSet() (*flag.FlagSet, error) { + return flagSet(c.Name, c.Flags) +} - return set, set.Parse(append([]string{"--"}, args...)) - } - - if !c.SkipArgReorder { - args = reorderArgs(c.Flags, args) - } +func (c *Command) useShortOptionHandling() bool { + return c.UseShortOptionHandling +} +func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) { set, err := c.newFlagSet() if err != nil { return nil, err } - err = parseIter(set, c, args) + if c.SkipFlagParsing { + return set, set.Parse(append([]string{"--"}, args.Tail()...)) + } + + err = parseIter(set, c, args.Tail(), shellComplete) if err != nil { return nil, err } @@ -211,96 +197,13 @@ func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) { return set, nil } -func (c *Command) newFlagSet() (*flag.FlagSet, error) { - return flagSet(c.Name, c.Flags) -} - -func (c *Command) useShortOptionHandling() bool { - return c.UseShortOptionHandling -} - -// reorderArgs moves all flags (via reorderedArgs) before the rest of -// the arguments (remainingArgs) as this is what flag expects. -func reorderArgs(commandFlags []Flag, args []string) []string { - var remainingArgs, reorderedArgs []string - - nextIndexMayContainValue := false - for i, arg := range args { - - // dont reorder any args after a -- - // read about -- here: - // https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash - if arg == "--" { - remainingArgs = append(remainingArgs, args[i:]...) - break - - // checks if this arg is a value that should be re-ordered next to its associated flag - } else if nextIndexMayContainValue && !strings.HasPrefix(arg, "-") { - nextIndexMayContainValue = false - reorderedArgs = append(reorderedArgs, arg) - - // checks if this is an arg that should be re-ordered - } else if argIsFlag(commandFlags, arg) { - // we have determined that this is a flag that we should re-order - reorderedArgs = append(reorderedArgs, arg) - // if this arg does not contain a "=", then the next index may contain the value for this flag - nextIndexMayContainValue = !strings.Contains(arg, "=") - - // simply append any remaining args - } else { - remainingArgs = append(remainingArgs, arg) - } - } - - return append(reorderedArgs, remainingArgs...) -} - -// argIsFlag checks if an arg is one of our command flags -func argIsFlag(commandFlags []Flag, arg string) bool { - // checks if this is just a `-`, and so definitely not a flag - if arg == "-" { - return false - } - // flags always start with a - - if !strings.HasPrefix(arg, "-") { - return false - } - // this line turns `--flag` into `flag` - if strings.HasPrefix(arg, "--") { - arg = strings.Replace(arg, "-", "", 2) - } - // this line turns `-flag` into `flag` - if strings.HasPrefix(arg, "-") { - arg = strings.Replace(arg, "-", "", 1) - } - // this line turns `flag=value` into `flag` - arg = strings.Split(arg, "=")[0] - // look through all the flags, to see if the `arg` is one of our flags - for _, flag := range commandFlags { - for _, key := range strings.Split(flag.GetName(), ",") { - key := strings.TrimSpace(key) - if key == arg { - return true - } - } - } - // return false if this arg was not one of our flags - return false -} - // Names returns the names including short names and aliases. -func (c Command) Names() []string { - names := []string{c.Name} - - if c.ShortName != "" { - names = append(names, c.ShortName) - } - - return append(names, c.Aliases...) +func (c *Command) Names() []string { + return append([]string{c.Name}, c.Aliases...) } -// HasName returns true if Command.Name or Command.ShortName matches given name -func (c Command) HasName(name string) bool { +// 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 @@ -309,12 +212,12 @@ func (c Command) HasName(name string) bool { return false } -func (c Command) startApp(ctx *Context) error { - app := NewApp() - app.Metadata = ctx.App.Metadata - app.ExitErrHandler = ctx.App.ExitErrHandler - // set the name and usage - app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) +func (c *Command) startApp(ctx *Context) error { + app := &App{ + Metadata: ctx.App.Metadata, + Name: fmt.Sprintf("%s %s", ctx.App.Name, c.Name), + } + if c.HelpName == "" { app.HelpName = c.HelpName } else { @@ -337,18 +240,17 @@ func (c Command) startApp(ctx *Context) error { app.Version = ctx.App.Version app.HideVersion = ctx.App.HideVersion app.Compiled = ctx.App.Compiled - app.Author = ctx.App.Author - app.Email = ctx.App.Email app.Writer = ctx.App.Writer app.ErrWriter = ctx.App.ErrWriter + app.ExitErrHandler = ctx.App.ExitErrHandler app.UseShortOptionHandling = ctx.App.UseShortOptionHandling - app.categories = CommandCategories{} + app.categories = newCommandCategories() for _, command := range c.Subcommands { - app.categories = app.categories.AddCommand(command.Category, command) + app.categories.AddCommand(command.Category, command) } - sort.Sort(app.categories) + sort.Sort(app.categories.(*commandCategories)) // bash completion app.EnableBashCompletion = ctx.App.EnableBashCompletion @@ -374,6 +276,22 @@ func (c Command) startApp(ctx *Context) error { } // VisibleFlags returns a slice of the Flags with Hidden=false -func (c Command) VisibleFlags() []Flag { +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 +} diff --git a/vendor/github.com/urfave/cli/v2/context.go b/vendor/github.com/urfave/cli/v2/context.go new file mode 100644 index 0000000..c0c526f --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/context.go @@ -0,0 +1,274 @@ +package cli + +import ( + "context" + "errors" + "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 + setFlags map[string]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 (c *Context) NumFlags() int { + return c.flagSet.NFlag() +} + +// Set sets a context flag to a value. +func (c *Context) Set(name, value string) error { + return c.flagSet.Set(name, value) +} + +// IsSet determines if the flag was actually set +func (c *Context) IsSet(name string) bool { + if fs := lookupFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { + isSet := false + fs.Visit(func(f *flag.Flag) { + if f.Name == name { + isSet = true + } + }) + if isSet { + return true + } + } + + f := lookupFlag(name, c) + if f == nil { + return false + } + + return f.IsSet() + } + + return false +} + +// LocalFlagNames returns a slice of flag names used in this context. +func (c *Context) LocalFlagNames() []string { + var names []string + c.flagSet.Visit(makeFlagNameVisitor(&names)) + return names +} + +// FlagNames returns a slice of flag names used by the this context and all of +// its parent contexts. +func (c *Context) FlagNames() []string { + var names []string + for _, ctx := range c.Lineage() { + ctx.flagSet.Visit(makeFlagNameVisitor(&names)) + } + return names +} + +// Lineage returns *this* context and all of its ancestor contexts in order from +// child to parent +func (c *Context) Lineage() []*Context { + var lineage []*Context + + for cur := c; cur != nil; cur = cur.parentContext { + lineage = append(lineage, cur) + } + + return lineage +} + +// Value returns the value of the flag corresponding to `name` +func (c *Context) Value(name string) interface{} { + return c.flagSet.Lookup(name).Value.(flag.Getter).Get() +} + +// Args returns the command line arguments associated with the context. +func (c *Context) Args() Args { + ret := args(c.flagSet.Args()) + return &ret +} + +// NArg returns the number of the command line arguments. +func (c *Context) NArg() int { + return c.Args().Len() +} + +func lookupFlag(name string, ctx *Context) Flag { + for _, c := range ctx.Lineage() { + if c.Command == nil { + continue + } + + for _, f := range c.Command.Flags { + for _, n := range f.Names() { + if n == name { + return f + } + } + } + } + + if ctx.App != nil { + for _, f := range ctx.App.Flags { + for _, n := range f.Names() { + if n == name { + return f + } + } + } + } + + return nil +} + +func lookupFlagSet(name string, ctx *Context) *flag.FlagSet { + for _, c := range ctx.Lineage() { + if f := c.flagSet.Lookup(name); f != nil { + return c.flagSet + } + } + + return 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 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) + } + } +} + +type requiredFlagsErr interface { + error + getMissingFlags() []string +} + +type errRequiredFlags struct { + missingFlags []string +} + +func (e *errRequiredFlags) Error() string { + numberOfMissingFlags := len(e.missingFlags) + if numberOfMissingFlags == 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 +} + +func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr { + var missingFlags []string + for _, f := range flags { + if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() { + var flagPresent bool + var flagName string + + for _, key := range f.Names() { + if len(key) > 1 { + flagName = key + } + + if context.IsSet(strings.TrimSpace(key)) { + flagPresent = true + } + } + + if !flagPresent && flagName != "" { + missingFlags = append(missingFlags, flagName) + } + } + } + + if len(missingFlags) != 0 { + return &errRequiredFlags{missingFlags: missingFlags} + } + + return nil +} diff --git a/vendor/github.com/urfave/cli/docs.go b/vendor/github.com/urfave/cli/v2/docs.go similarity index 91% rename from vendor/github.com/urfave/cli/docs.go rename to vendor/github.com/urfave/cli/v2/docs.go index 5b94566..dc16fc8 100644 --- a/vendor/github.com/urfave/cli/docs.go +++ b/vendor/github.com/urfave/cli/v2/docs.go @@ -48,15 +48,14 @@ func (a *App) writeDocTemplate(w io.Writer) error { return t.ExecuteTemplate(w, name, &cliTemplate{ App: a, Commands: prepareCommands(a.Commands, 0), - GlobalArgs: prepareArgsWithValues(a.Flags), - SynopsisArgs: prepareArgsSynopsis(a.Flags), + GlobalArgs: prepareArgsWithValues(a.VisibleFlags()), + SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()), }) } -func prepareCommands(commands []Command, level int) []string { - coms := []string{} - for i := range commands { - command := &commands[i] +func prepareCommands(commands []*Command, level int) []string { + var coms []string + for _, command := range commands { if command.Hidden { continue } @@ -110,7 +109,8 @@ func prepareFlags( continue } modifiedArg := opener - for _, s := range strings.Split(flag.GetName(), ",") { + + for _, s := range flag.Names() { trimmed := strings.TrimSpace(s) if len(modifiedArg) > len(opener) { modifiedArg += sep diff --git a/vendor/github.com/urfave/cli/errors.go b/vendor/github.com/urfave/cli/v2/errors.go similarity index 62% rename from vendor/github.com/urfave/cli/errors.go rename to vendor/github.com/urfave/cli/v2/errors.go index 562b295..344b436 100644 --- a/vendor/github.com/urfave/cli/errors.go +++ b/vendor/github.com/urfave/cli/v2/errors.go @@ -15,25 +15,40 @@ var OsExiter = os.Exit var ErrWriter io.Writer = os.Stderr // MultiError is an error that wraps multiple errors. -type MultiError struct { - Errors []error +type MultiError interface { + error + // Errors returns a copy of the errors slice + Errors() []error } // NewMultiError creates a new MultiError. Pass in one or more errors. -func NewMultiError(err ...error) MultiError { - return MultiError{Errors: err} +func newMultiError(err ...error) MultiError { + ret := multiError(err) + return &ret } +type multiError []error + // Error implements the error interface. -func (m MultiError) Error() string { - errs := make([]string, len(m.Errors)) - for i, err := range m.Errors { +func (m *multiError) Error() string { + errs := make([]string, len(*m)) + for i, err := range *m { errs[i] = err.Error() } return strings.Join(errs, "\n") } +// 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) + } + return errs +} + +// ErrorFormatter is the interface that will suitably format the error output type ErrorFormatter interface { Format(s fmt.State, verb rune) } @@ -45,29 +60,30 @@ type ExitCoder interface { ExitCode() int } -// ExitError fulfills both the builtin `error` interface and `ExitCoder` -type ExitError struct { +type exitError struct { exitCode int message interface{} } -// NewExitError makes a new *ExitError -func NewExitError(message interface{}, exitCode int) *ExitError { - return &ExitError{ - exitCode: exitCode, +// NewExitError makes a new *exitError +func NewExitError(message interface{}, exitCode int) ExitCoder { + return Exit(message, exitCode) +} + +// Exit wraps a message and exit code into an ExitCoder suitable for handling by +// HandleExitCoder +func Exit(message interface{}, exitCode int) ExitCoder { + return &exitError{ message: message, + exitCode: exitCode, } } -// Error returns the string message, fulfilling the interface required by -// `error` -func (ee *ExitError) Error() string { +func (ee *exitError) Error() string { return fmt.Sprintf("%v", ee.message) } -// ExitCode returns the exit code, fulfilling the interface required by -// `ExitCoder` -func (ee *ExitError) ExitCode() int { +func (ee *exitError) ExitCode() int { return ee.exitCode } @@ -83,9 +99,9 @@ func HandleExitCoder(err error) { if exitErr, ok := err.(ExitCoder); ok { if err.Error() != "" { if _, ok := exitErr.(ErrorFormatter); ok { - fmt.Fprintf(ErrWriter, "%+v\n", err) + _, _ = fmt.Fprintf(ErrWriter, "%+v\n", err) } else { - fmt.Fprintln(ErrWriter, err) + _, _ = fmt.Fprintln(ErrWriter, err) } } OsExiter(exitErr.ExitCode()) @@ -101,10 +117,10 @@ func HandleExitCoder(err error) { func handleMultiError(multiErr MultiError) int { code := 1 - for _, merr := range multiErr.Errors { + for _, merr := range multiErr.Errors() { if multiErr2, ok := merr.(MultiError); ok { code = handleMultiError(multiErr2) - } else { + } else if merr != nil { fmt.Fprintln(ErrWriter, merr) if exitErr, ok := merr.(ExitCoder); ok { code = exitErr.ExitCode() diff --git a/vendor/github.com/urfave/cli/fish.go b/vendor/github.com/urfave/cli/v2/fish.go similarity index 93% rename from vendor/github.com/urfave/cli/fish.go rename to vendor/github.com/urfave/cli/v2/fish.go index cf183af..67122c9 100644 --- a/vendor/github.com/urfave/cli/fish.go +++ b/vendor/github.com/urfave/cli/v2/fish.go @@ -64,11 +64,9 @@ func (a *App) writeFishCompletionTemplate(w io.Writer) error { }) } -func (a *App) prepareFishCommands(commands []Command, allCommands *[]string, previousCommands []string) []string { +func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, previousCommands []string) []string { completions := []string{} - for i := range commands { - command := &commands[i] - + for _, command := range commands { if command.Hidden { continue } @@ -131,7 +129,7 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string fishAddFileFlag(f, completion) - for idx, opt := range strings.Split(flag.GetName(), ",") { + for idx, opt := range flag.Names() { if idx == 0 { completion.WriteString(fmt.Sprintf( " -l %s", strings.TrimSpace(opt), @@ -161,15 +159,15 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string func fishAddFileFlag(flag Flag, completion *strings.Builder) { switch f := flag.(type) { - case GenericFlag: + case *GenericFlag: if f.TakesFile { return } - case StringFlag: + case *StringFlag: if f.TakesFile { return } - case StringSliceFlag: + case *StringSliceFlag: if f.TakesFile { return } diff --git a/vendor/github.com/urfave/cli/flag.go b/vendor/github.com/urfave/cli/v2/flag.go similarity index 55% rename from vendor/github.com/urfave/cli/flag.go rename to vendor/github.com/urfave/cli/v2/flag.go index 1cfa1cd..ec128fd 100644 --- a/vendor/github.com/urfave/cli/flag.go +++ b/vendor/github.com/urfave/cli/v2/flag.go @@ -5,38 +5,53 @@ import ( "fmt" "io/ioutil" "reflect" + "regexp" "runtime" "strconv" "strings" "syscall" + "time" ) const defaultPlaceholder = "value" +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{ +var BashCompletionFlag Flag = &BoolFlag{ Name: "generate-bash-completion", Hidden: true, } // VersionFlag prints the version for the application -var VersionFlag Flag = BoolFlag{ - Name: "version, v", - Usage: "print the version", +var VersionFlag Flag = &BoolFlag{ + Name: "version", + Aliases: []string{"v"}, + Usage: "print the version", } -// HelpFlag prints the help for all commands and subcommands -// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand -// unless HideHelp is set to true) -var HelpFlag Flag = BoolFlag{ - Name: "help, h", - Usage: "show help", +// HelpFlag prints the help for all commands and subcommands. +// Set to nil to disable the flag. The subcommand +// will still be added unless HideHelp is set to true. +var HelpFlag Flag = &BoolFlag{ + Name: "help", + Aliases: []string{"h"}, + Usage: "show help", } // 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 @@ -57,7 +72,12 @@ func (f FlagsByName) Len() int { } func (f FlagsByName) Less(i, j int) bool { - return lexicographicLess(f[i].GetName(), f[j].GetName()) + 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) { @@ -70,8 +90,9 @@ func (f FlagsByName) Swap(i, j int) { type Flag interface { fmt.Stringer // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) - GetName() string + Apply(*flag.FlagSet) error + Names() []string + IsSet() bool } // RequiredFlag is an interface that allows us to mark flags as required @@ -97,40 +118,18 @@ type DocGenerationFlag interface { GetValue() string } -// errorableFlag is an interface that allows us to return errors during apply -// it allows flags defined in this library to return errors in a fashion backwards compatible -// TODO remove in v2 and modify the existing Flag interface to return errors -type errorableFlag interface { - Flag - - ApplyWithError(*flag.FlagSet) error -} - func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { set := flag.NewFlagSet(name, flag.ContinueOnError) for _, f := range flags { - //TODO remove in v2 when errorableFlag is removed - if ef, ok := f.(errorableFlag); ok { - if err := ef.ApplyWithError(set); err != nil { - return nil, err - } - } else { - f.Apply(set) + if err := f.Apply(set); err != nil { + return nil, err } } set.SetOutput(ioutil.Discard) return set, nil } -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - func visibleFlags(fl []Flag) []Flag { var visible []Flag for _, f := range fl { @@ -169,25 +168,27 @@ func unquoteUsage(usage string) (string, string) { return "", usage } -func prefixedNames(fullName, placeholder string) string { +func prefixedNames(names []string, placeholder string) string { var prefixed string - parts := strings.Split(fullName, ",") - for i, name := range parts { - name = strings.Trim(name, " ") + for i, name := range names { + if name == "" { + continue + } + prefixed += prefixFor(name) + name if placeholder != "" { prefixed += " " + placeholder } - if i < len(parts)-1 { + if i < len(names)-1 { prefixed += ", " } } return prefixed } -func withEnvHint(envVar, str string) string { +func withEnvHint(envVars []string, str string) string { envText := "" - if envVar != "" { + if envVars != nil && len(envVars) > 0 { prefix := "$" suffix := "" sep := ", $" @@ -196,11 +197,51 @@ func withEnvHint(envVar, str string) string { suffix = "%" sep = "%, %" } - envText = " [" + prefix + strings.Join(strings.Split(envVar, ","), sep) + suffix + "]" + + envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix) } return str + envText } +func flagNames(f Flag) []string { + var ret []string + + name := flagStringField(f, "Name") + aliases := flagStringSliceField(f, "Aliases") + + 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 flagStringSliceField(f Flag, name string) []string { + fv := flagValue(f) + field := fv.FieldByName(name) + + if field.IsValid() { + return field.Interface().([]string) + } + + return []string{} +} + +func flagStringField(f Flag, name string) string { + fv := flagValue(f) + field := fv.FieldByName(name) + + if field.IsValid() { + return field.String() + } + + return "" +} + func withFileHint(filePath, str string) string { fileText := "" if filePath != "" { @@ -221,39 +262,27 @@ func stringifyFlag(f Flag) string { fv := flagValue(f) switch f.(type) { - case IntSliceFlag: - return FlagFileHinter( - fv.FieldByName("FilePath").String(), - FlagEnvHinter( - fv.FieldByName("EnvVar").String(), - stringifyIntSliceFlag(f.(IntSliceFlag)), - ), - ) - case Int64SliceFlag: - return FlagFileHinter( - fv.FieldByName("FilePath").String(), - FlagEnvHinter( - fv.FieldByName("EnvVar").String(), - stringifyInt64SliceFlag(f.(Int64SliceFlag)), - ), - ) - case StringSliceFlag: - return FlagFileHinter( - fv.FieldByName("FilePath").String(), - FlagEnvHinter( - fv.FieldByName("EnvVar").String(), - stringifyStringSliceFlag(f.(StringSliceFlag)), - ), - ) + case *IntSliceFlag: + return withEnvHint(flagStringSliceField(f, "EnvVars"), + stringifyIntSliceFlag(f.(*IntSliceFlag))) + case *Int64SliceFlag: + return withEnvHint(flagStringSliceField(f, "EnvVars"), + stringifyInt64SliceFlag(f.(*Int64SliceFlag))) + case *Float64SliceFlag: + return withEnvHint(flagStringSliceField(f, "EnvVars"), + stringifyFloat64SliceFlag(f.(*Float64SliceFlag))) + case *StringSliceFlag: + return withEnvHint(flagStringSliceField(f, "EnvVars"), + stringifyStringSliceFlag(f.(*StringSliceFlag))) } placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) needsPlaceholder := false defaultValueString := "" - - if val := fv.FieldByName("Value"); val.IsValid() { - needsPlaceholder = true + val := fv.FieldByName("Value") + if val.IsValid() { + needsPlaceholder = val.Kind() != reflect.Bool defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface()) if val.Kind() == reflect.String && val.String() != "" { @@ -261,6 +290,12 @@ func stringifyFlag(f Flag) string { } } + helpText := fv.FieldByName("DefaultText") + if helpText.IsValid() && helpText.String() != "" { + needsPlaceholder = val.Kind() != reflect.Bool + defaultValueString = fmt.Sprintf(" (default: %s)", helpText.String()) + } + if defaultValueString == " (default: )" { defaultValueString = "" } @@ -271,16 +306,11 @@ func stringifyFlag(f Flag) string { usageWithDefault := strings.TrimSpace(usage + defaultValueString) - return FlagFileHinter( - fv.FieldByName("FilePath").String(), - FlagEnvHinter( - fv.FieldByName("EnvVar").String(), - FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder)+"\t"+usageWithDefault, - ), - ) + return withEnvHint(flagStringSliceField(f, "EnvVars"), + fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault)) } -func stringifyIntSliceFlag(f IntSliceFlag) string { +func stringifyIntSliceFlag(f *IntSliceFlag) string { var defaultVals []string if f.Value != nil && len(f.Value.Value()) > 0 { for _, i := range f.Value.Value() { @@ -288,10 +318,10 @@ func stringifyIntSliceFlag(f IntSliceFlag) string { } } - return stringifySliceFlag(f.Usage, f.Name, defaultVals) + return stringifySliceFlag(f.Usage, f.Names(), defaultVals) } -func stringifyInt64SliceFlag(f Int64SliceFlag) string { +func stringifyInt64SliceFlag(f *Int64SliceFlag) string { var defaultVals []string if f.Value != nil && len(f.Value.Value()) > 0 { for _, i := range f.Value.Value() { @@ -299,10 +329,22 @@ func stringifyInt64SliceFlag(f Int64SliceFlag) string { } } - return stringifySliceFlag(f.Usage, f.Name, defaultVals) + return stringifySliceFlag(f.Usage, f.Names(), defaultVals) } -func stringifyStringSliceFlag(f StringSliceFlag) string { +func stringifyFloat64SliceFlag(f *Float64SliceFlag) 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 stringifySliceFlag(f.Usage, f.Names(), defaultVals) +} + +func stringifyStringSliceFlag(f *StringSliceFlag) string { var defaultVals []string if f.Value != nil && len(f.Value.Value()) > 0 { for _, s := range f.Value.Value() { @@ -312,10 +354,10 @@ func stringifyStringSliceFlag(f StringSliceFlag) string { } } - return stringifySliceFlag(f.Usage, f.Name, defaultVals) + return stringifySliceFlag(f.Usage, f.Names(), defaultVals) } -func stringifySliceFlag(usage, name string, defaultVals []string) string { +func stringifySliceFlag(usage string, names, defaultVals []string) string { placeholder, usage := unquoteUsage(usage) if placeholder == "" { placeholder = defaultPlaceholder @@ -326,15 +368,25 @@ func stringifySliceFlag(usage, name string, defaultVals []string) string { defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", ")) } - usageWithDefault := strings.TrimSpace(usage + defaultVal) - return FlagNamePrefixer(name, placeholder) + "\t" + usageWithDefault + usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal)) + return fmt.Sprintf("%s\t%s", prefixedNames(names, placeholder), usageWithDefault) } -func flagFromFileEnv(filePath, envName string) (val string, ok bool) { - for _, envVar := range strings.Split(envName, ",") { +func hasFlag(flags []Flag, fl Flag) bool { + for _, existing := range flags { + if fl == existing { + return true + } + } + + return false +} + +func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool) { + for _, envVar := range envVars { envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - return envVal, true + if val, ok := syscall.Getenv(envVar); ok { + return val, true } } for _, fileVar := range strings.Split(filePath, ",") { diff --git a/vendor/github.com/urfave/cli/flag_bool.go b/vendor/github.com/urfave/cli/v2/flag_bool.go similarity index 51% rename from vendor/github.com/urfave/cli/flag_bool.go rename to vendor/github.com/urfave/cli/v2/flag_bool.go index 2499b0b..6a1da61 100644 --- a/vendor/github.com/urfave/cli/flag_bool.go +++ b/vendor/github.com/urfave/cli/v2/flag_bool.go @@ -9,93 +9,90 @@ import ( // BoolFlag is a flag with type bool type BoolFlag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool + Value bool + DefaultText string Destination *bool + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *BoolFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f BoolFlag) String() string { +func (f *BoolFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f BoolFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *BoolFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f BoolFlag) IsRequired() bool { +func (f *BoolFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f BoolFlag) TakesValue() bool { +func (f *BoolFlag) TakesValue() bool { return false } // GetUsage returns the usage string for the flag -func (f BoolFlag) GetUsage() string { +func (f *BoolFlag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f BoolFlag) GetValue() string { +func (f *BoolFlag) GetValue() string { return "" } +// Apply populates the flag given the flag set and environment +func (f *BoolFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valBool, err := strconv.ParseBool(val) + + if err != nil { + return fmt.Errorf("could not parse %q as bool value for flag %s: %s", val, f.Name, err) + } + + f.Value = valBool + f.HasBeenSet = true + } + } + + for _, name := range f.Names() { + if f.Destination != nil { + set.BoolVar(f.Destination, name, f.Value, f.Usage) + continue + } + set.Bool(name, f.Value, f.Usage) + } + + return nil +} + // Bool looks up the value of a local BoolFlag, returns // false if not found func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// GlobalBool looks up the value of a global BoolFlag, returns -// false if not found -func (c *Context) GlobalBool(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupBool(name, fs) } return false } -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { - val := false - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - if envVal == "" { - val = false - } else { - envValBool, err := strconv.ParseBool(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) - } - val = envValBool - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.BoolVar(f.Destination, name, val, f.Usage) - return - } - set.Bool(name, val, f.Usage) - }) - - return nil -} - func lookupBool(name string, set *flag.FlagSet) bool { f := set.Lookup(name) if f != nil { diff --git a/vendor/github.com/urfave/cli/flag_duration.go b/vendor/github.com/urfave/cli/v2/flag_duration.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_duration.go rename to vendor/github.com/urfave/cli/v2/flag_duration.go index df4ade5..2c34944 100644 --- a/vendor/github.com/urfave/cli/flag_duration.go +++ b/vendor/github.com/urfave/cli/v2/flag_duration.go @@ -9,90 +9,89 @@ import ( // DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) type DurationFlag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value time.Duration + DefaultText string Destination *time.Duration + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *DurationFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f DurationFlag) String() string { +func (f *DurationFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f DurationFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *DurationFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f DurationFlag) IsRequired() bool { +func (f *DurationFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f DurationFlag) TakesValue() bool { +func (f *DurationFlag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f DurationFlag) GetUsage() string { +func (f *DurationFlag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f DurationFlag) GetValue() string { +func (f *DurationFlag) GetValue() string { return f.Value.String() } +// Apply populates the flag given the flag set and environment +func (f *DurationFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valDuration, err := time.ParseDuration(val) + + if err != nil { + return fmt.Errorf("could not parse %q as duration value for flag %s: %s", val, f.Name, err) + } + + f.Value = valDuration + f.HasBeenSet = true + } + } + + 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 +} + // Duration looks up the value of a local DurationFlag, returns // 0 if not found func (c *Context) Duration(name string) time.Duration { - return lookupDuration(name, c.flagSet) -} - -// GlobalDuration looks up the value of a global DurationFlag, returns -// 0 if not found -func (c *Context) GlobalDuration(name string) time.Duration { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupDuration(name, fs) } return 0 } -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f DurationFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValDuration, err := time.ParseDuration(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err) - } - - f.Value = envValDuration - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.DurationVar(f.Destination, name, f.Value, f.Usage) - return - } - set.Duration(name, f.Value, f.Usage) - }) - - return nil -} - func lookupDuration(name string, set *flag.FlagSet) time.Duration { f := set.Lookup(name) if f != nil { diff --git a/vendor/github.com/urfave/cli/flag_float64.go b/vendor/github.com/urfave/cli/v2/flag_float64.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_float64.go rename to vendor/github.com/urfave/cli/v2/flag_float64.go index 65398d3..31f06f3 100644 --- a/vendor/github.com/urfave/cli/flag_float64.go +++ b/vendor/github.com/urfave/cli/v2/flag_float64.go @@ -9,90 +9,90 @@ import ( // Float64Flag is a flag with type float64 type Float64Flag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value float64 + DefaultText string Destination *float64 + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *Float64Flag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f Float64Flag) String() string { +func (f *Float64Flag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f Float64Flag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *Float64Flag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f Float64Flag) IsRequired() bool { +func (f *Float64Flag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f Float64Flag) TakesValue() bool { +func (f *Float64Flag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f Float64Flag) GetUsage() string { +func (f *Float64Flag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f Float64Flag) GetValue() string { +func (f *Float64Flag) GetValue() string { return fmt.Sprintf("%f", f.Value) } +// Apply populates the flag given the flag set and environment +func (f *Float64Flag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valFloat, err := strconv.ParseFloat(val, 10) + + if err != nil { + return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", val, f.Name, err) + } + + f.Value = valFloat + f.HasBeenSet = true + } + } + + 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 +} + // Float64 looks up the value of a local Float64Flag, returns // 0 if not found func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// GlobalFloat64 looks up the value of a global Float64Flag, returns -// 0 if not found -func (c *Context) GlobalFloat64(name string) float64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupFloat64(name, fs) } return 0 } -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Float64Flag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValFloat, err := strconv.ParseFloat(envVal, 10) - if err != nil { - return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = envValFloat - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.Float64Var(f.Destination, name, f.Value, f.Usage) - return - } - set.Float64(name, f.Value, f.Usage) - }) - - return nil -} - func lookupFloat64(name string, set *flag.FlagSet) float64 { f := set.Lookup(name) if f != nil { diff --git a/vendor/github.com/urfave/cli/v2/flag_float64_slice.go b/vendor/github.com/urfave/cli/v2/flag_float64_slice.go new file mode 100644 index 0000000..91d2e9d --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_float64_slice.go @@ -0,0 +1,165 @@ +package cli + +import ( + "encoding/json" + "flag" + "fmt" + "strconv" + "strings" +) + +// Float64Slice wraps []float64 to satisfy flag.Value +type Float64Slice struct { + slice []float64 + hasBeenSet bool +} + +// NewFloat64Slice makes a *Float64Slice with default values +func NewFloat64Slice(defaults ...float64) *Float64Slice { + return &Float64Slice{slice: append([]float64{}, defaults...)} +} + +// 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 + } + + tmp, err := strconv.ParseFloat(value, 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 { + return fmt.Sprintf("%#v", f.slice) +} + +// 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 +} + +// Float64SliceFlag is a flag with type *Float64Slice +type Float64SliceFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + Value *Float64Slice + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *Float64SliceFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *Float64SliceFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *Float64SliceFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *Float64SliceFlag) IsRequired() bool { + return f.Required +} + +// 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 +} + +// 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 { + if f.Value != nil { + return f.Value.String() + } + return "" +} + +// Apply populates the flag given the flag set and environment +func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + f.Value = &Float64Slice{} + + for _, s := range strings.Split(val, ",") { + if err := f.Value.Set(strings.TrimSpace(s)); err != nil { + return fmt.Errorf("could not parse %q as float64 slice value for flag %s: %s", f.Value, f.Name, err) + } + } + + f.HasBeenSet = true + } + } + + for _, name := range f.Names() { + if f.Value == nil { + f.Value = &Float64Slice{} + } + set.Var(f.Value, name, f.Usage) + } + + return nil +} + +// Float64Slice looks up the value of a local Float64SliceFlag, returns +// nil if not found +func (c *Context) Float64Slice(name string) []float64 { + if fs := lookupFlagSet(name, c); fs != nil { + return lookupFloat64Slice(name, fs) + } + return nil +} + +func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*Float64Slice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} diff --git a/vendor/github.com/urfave/cli/flag_generic.go b/vendor/github.com/urfave/cli/v2/flag_generic.go similarity index 52% rename from vendor/github.com/urfave/cli/flag_generic.go rename to vendor/github.com/urfave/cli/v2/flag_generic.go index c43dae7..2d9baa7 100644 --- a/vendor/github.com/urfave/cli/flag_generic.go +++ b/vendor/github.com/urfave/cli/v2/flag_generic.go @@ -13,45 +13,53 @@ type Generic interface { // GenericFlag is a flag with type Generic type GenericFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - TakesFile bool - Value Generic + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + TakesFile bool + Value Generic + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *GenericFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f GenericFlag) String() string { +func (f *GenericFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f GenericFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *GenericFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f GenericFlag) IsRequired() bool { +func (f *GenericFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f GenericFlag) TakesValue() bool { +func (f *GenericFlag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f GenericFlag) GetUsage() string { +func (f *GenericFlag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f GenericFlag) GetValue() string { +func (f *GenericFlag) GetValue() string { if f.Value != nil { return f.Value.String() } @@ -60,24 +68,20 @@ func (f GenericFlag) GetValue() string { // Apply takes the flagset and calls Set on the generic flag with the value // provided by the user for parsing by the flag -// Ignores parsing errors -func (f GenericFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} +func (f GenericFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + if err := f.Value.Set(val); err != nil { + return fmt.Errorf("could not parse %q as value for flag %s: %s", val, f.Name, err) + } -// ApplyWithError 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) ApplyWithError(set *flag.FlagSet) error { - val := f.Value - if fileEnvVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - if err := val.Set(fileEnvVal); err != nil { - return fmt.Errorf("could not parse %s as value for flag %s: %s", fileEnvVal, f.Name, err) + f.HasBeenSet = true } } - eachName(f.Name, func(name string) { + for _, name := range f.Names() { set.Var(f.Value, name, f.Usage) - }) + } return nil } @@ -85,13 +89,7 @@ func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error { // Generic looks up the value of a local GenericFlag, returns // nil if not found func (c *Context) Generic(name string) interface{} { - return lookupGeneric(name, c.flagSet) -} - -// GlobalGeneric looks up the value of a global GenericFlag, returns -// nil if not found -func (c *Context) GlobalGeneric(name string) interface{} { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupGeneric(name, fs) } return nil diff --git a/vendor/github.com/urfave/cli/flag_int.go b/vendor/github.com/urfave/cli/v2/flag_int.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_int.go rename to vendor/github.com/urfave/cli/v2/flag_int.go index bae32e2..be961bf 100644 --- a/vendor/github.com/urfave/cli/flag_int.go +++ b/vendor/github.com/urfave/cli/v2/flag_int.go @@ -9,70 +9,77 @@ import ( // IntFlag is a flag with type int type IntFlag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value int + DefaultText string Destination *int + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *IntFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f IntFlag) String() string { +func (f *IntFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f IntFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *IntFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f IntFlag) IsRequired() bool { +func (f *IntFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f IntFlag) TakesValue() bool { +func (f *IntFlag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f IntFlag) GetUsage() string { +func (f *IntFlag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f IntFlag) GetValue() string { +func (f *IntFlag) GetValue() string { return fmt.Sprintf("%d", f.Value) } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} +func (f *IntFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valInt, err := strconv.ParseInt(val, 0, 64) -// ApplyWithError populates the flag given the flag set and environment -func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValInt, err := strconv.ParseInt(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) + if err != nil { + return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err) + } + + f.Value = int(valInt) + f.HasBeenSet = true } - f.Value = int(envValInt) } - eachName(f.Name, func(name string) { + for _, name := range f.Names() { if f.Destination != nil { set.IntVar(f.Destination, name, f.Value, f.Usage) - return + continue } set.Int(name, f.Value, f.Usage) - }) + } return nil } @@ -80,13 +87,7 @@ func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { // Int looks up the value of a local IntFlag, returns // 0 if not found func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// GlobalInt looks up the value of a global IntFlag, returns -// 0 if not found -func (c *Context) GlobalInt(name string) int { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupInt(name, fs) } return 0 diff --git a/vendor/github.com/urfave/cli/flag_int64.go b/vendor/github.com/urfave/cli/v2/flag_int64.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_int64.go rename to vendor/github.com/urfave/cli/v2/flag_int64.go index aaafbe9..c979119 100644 --- a/vendor/github.com/urfave/cli/flag_int64.go +++ b/vendor/github.com/urfave/cli/v2/flag_int64.go @@ -9,85 +9,84 @@ import ( // Int64Flag is a flag with type int64 type Int64Flag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value int64 + DefaultText string Destination *int64 + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *Int64Flag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f Int64Flag) String() string { +func (f *Int64Flag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f Int64Flag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *Int64Flag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f Int64Flag) IsRequired() bool { +func (f *Int64Flag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f Int64Flag) TakesValue() bool { +func (f *Int64Flag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f Int64Flag) GetUsage() string { +func (f *Int64Flag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f Int64Flag) GetValue() string { +func (f *Int64Flag) GetValue() string { return fmt.Sprintf("%d", f.Value) } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64Flag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} +func (f *Int64Flag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valInt, err := strconv.ParseInt(val, 0, 64) -// ApplyWithError populates the flag given the flag set and environment -func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValInt, err := strconv.ParseInt(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) + if err != nil { + return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err) + } + + f.Value = valInt + f.HasBeenSet = true } - - f.Value = envValInt } - eachName(f.Name, func(name string) { + for _, name := range f.Names() { if f.Destination != nil { set.Int64Var(f.Destination, name, f.Value, f.Usage) - return + continue } set.Int64(name, f.Value, f.Usage) - }) - + } return nil } // Int64 looks up the value of a local Int64Flag, returns // 0 if not found func (c *Context) Int64(name string) int64 { - return lookupInt64(name, c.flagSet) -} - -// GlobalInt64 looks up the value of a global Int64Flag, returns -// 0 if not found -func (c *Context) GlobalInt64(name string) int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupInt64(name, fs) } return 0 diff --git a/vendor/github.com/urfave/cli/v2/flag_int64_slice.go b/vendor/github.com/urfave/cli/v2/flag_int64_slice.go new file mode 100644 index 0000000..41aa066 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_int64_slice.go @@ -0,0 +1,161 @@ +package cli + +import ( + "encoding/json" + "flag" + "fmt" + "strconv" + "strings" +) + +// Int64Slice wraps []int64 to satisfy flag.Value +type Int64Slice struct { + slice []int64 + hasBeenSet bool +} + +// NewInt64Slice makes an *Int64Slice with default values +func NewInt64Slice(defaults ...int64) *Int64Slice { + return &Int64Slice{slice: append([]int64{}, defaults...)} +} + +// 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 + } + + tmp, err := strconv.ParseInt(value, 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 { + return fmt.Sprintf("%#v", i.slice) +} + +// 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 +} + +// Int64SliceFlag is a flag with type *Int64Slice +type Int64SliceFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + Value *Int64Slice + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *Int64SliceFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *Int64SliceFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *Int64SliceFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *Int64SliceFlag) IsRequired() bool { + return f.Required +} + +// 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 +} + +// 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 { + if f.Value != nil { + return f.Value.String() + } + return "" +} + +// Apply populates the flag given the flag set and environment +func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + f.Value = &Int64Slice{} + + for _, s := range strings.Split(val, ",") { + if err := f.Value.Set(strings.TrimSpace(s)); err != nil { + return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", val, f.Name, err) + } + } + + f.HasBeenSet = true + } + + for _, name := range f.Names() { + if f.Value == nil { + f.Value = &Int64Slice{} + } + set.Var(f.Value, name, f.Usage) + } + + return nil +} + +// Int64Slice looks up the value of a local Int64SliceFlag, returns +// nil if not found +func (c *Context) Int64Slice(name string) []int64 { + return lookupInt64Slice(name, c.flagSet) +} + +func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} diff --git a/vendor/github.com/urfave/cli/v2/flag_int_slice.go b/vendor/github.com/urfave/cli/v2/flag_int_slice.go new file mode 100644 index 0000000..9388978 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_int_slice.go @@ -0,0 +1,175 @@ +package cli + +import ( + "encoding/json" + "flag" + "fmt" + "strconv" + "strings" +) + +// IntSlice wraps []int to satisfy flag.Value +type IntSlice struct { + slice []int + hasBeenSet bool +} + +// NewIntSlice makes an *IntSlice with default values +func NewIntSlice(defaults ...int) *IntSlice { + return &IntSlice{slice: append([]int{}, defaults...)} +} + +// 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) +} + +// 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 + } + + tmp, err := strconv.ParseInt(value, 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 { + return fmt.Sprintf("%#v", i.slice) +} + +// 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 +} + +// IntSliceFlag is a flag with type *IntSlice +type IntSliceFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + Value *IntSlice + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *IntSliceFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *IntSliceFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *IntSliceFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *IntSliceFlag) IsRequired() bool { + return f.Required +} + +// 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 +} + +// 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 { + if f.Value != nil { + return f.Value.String() + } + return "" +} + +// Apply populates the flag given the flag set and environment +func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + f.Value = &IntSlice{} + + for _, s := range strings.Split(val, ",") { + if err := f.Value.Set(strings.TrimSpace(s)); err != nil { + return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", val, f.Name, err) + } + } + + f.HasBeenSet = true + } + + for _, name := range f.Names() { + if f.Value == nil { + f.Value = &IntSlice{} + } + set.Var(f.Value, name, f.Usage) + } + + return nil +} + +// IntSlice looks up the value of a local IntSliceFlag, returns +// nil if not found +func (c *Context) IntSlice(name string) []int { + if fs := lookupFlagSet(name, c); fs != nil { + return lookupIntSlice(name, c.flagSet) + } + return nil +} + +func lookupIntSlice(name string, set *flag.FlagSet) []int { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} diff --git a/vendor/github.com/urfave/cli/v2/flag_path.go b/vendor/github.com/urfave/cli/v2/flag_path.go new file mode 100644 index 0000000..a322857 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_path.go @@ -0,0 +1,95 @@ +package cli + +import "flag" + +type PathFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + TakesFile bool + Value string + DefaultText string + Destination *string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *PathFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *PathFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *PathFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *PathFlag) IsRequired() bool { + return f.Required +} + +// 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 +} + +// 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 +} + +// Apply populates the flag given the flag set and environment +func (f *PathFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + 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 +} + +// Path looks up the value of a local PathFlag, returns +// "" if not found +func (c *Context) Path(name string) string { + if fs := lookupFlagSet(name, c); fs != nil { + return lookupPath(name, fs) + } + + return "" +} + +func lookupPath(name string, set *flag.FlagSet) string { + f := set.Lookup(name) + if f != nil { + parsed, err := f.Value.String(), error(nil) + if err != nil { + return "" + } + return parsed + } + return "" +} diff --git a/vendor/github.com/urfave/cli/flag_string.go b/vendor/github.com/urfave/cli/v2/flag_string.go similarity index 59% rename from vendor/github.com/urfave/cli/flag_string.go rename to vendor/github.com/urfave/cli/v2/flag_string.go index 9f29da4..bcd8253 100644 --- a/vendor/github.com/urfave/cli/flag_string.go +++ b/vendor/github.com/urfave/cli/v2/flag_string.go @@ -5,67 +5,70 @@ import "flag" // StringFlag is a flag with type string type StringFlag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool TakesFile bool Value string + DefaultText string Destination *string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *StringFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f StringFlag) String() string { +func (f *StringFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f StringFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *StringFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f StringFlag) IsRequired() bool { +func (f *StringFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f StringFlag) TakesValue() bool { +func (f *StringFlag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f StringFlag) GetUsage() string { +func (f *StringFlag) GetUsage() string { return f.Usage } // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. -func (f StringFlag) GetValue() string { +func (f *StringFlag) GetValue() string { return f.Value } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - f.Value = envVal +func (f *StringFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + f.Value = val + f.HasBeenSet = true } - eachName(f.Name, func(name string) { + for _, name := range f.Names() { if f.Destination != nil { set.StringVar(f.Destination, name, f.Value, f.Usage) - return + continue } set.String(name, f.Value, f.Usage) - }) + } return nil } @@ -73,13 +76,7 @@ func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { // String looks up the value of a local StringFlag, returns // "" if not found func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// GlobalString looks up the value of a global StringFlag, returns -// "" if not found -func (c *Context) GlobalString(name string) string { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupString(name, fs) } return "" diff --git a/vendor/github.com/urfave/cli/v2/flag_string_slice.go b/vendor/github.com/urfave/cli/v2/flag_string_slice.go new file mode 100644 index 0000000..a114a49 --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_string_slice.go @@ -0,0 +1,159 @@ +package cli + +import ( + "encoding/json" + "flag" + "fmt" + "strings" +) + +// StringSlice wraps a []string to satisfy flag.Value +type StringSlice struct { + slice []string + hasBeenSet bool +} + +// NewStringSlice creates a *StringSlice with default values +func NewStringSlice(defaults ...string) *StringSlice { + return &StringSlice{slice: append([]string{}, defaults...)} +} + +// 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 + } + + s.slice = append(s.slice, value) + + return nil +} + +// 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 +} + +// StringSliceFlag is a flag with type *StringSlice +type StringSliceFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + TakesFile bool + Value *StringSlice + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *StringSliceFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *StringSliceFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *StringSliceFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *StringSliceFlag) IsRequired() bool { + return f.Required +} + +// 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 +} + +// 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 { + if f.Value != nil { + return f.Value.String() + } + return "" +} + +// Apply populates the flag given the flag set and environment +func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + f.Value = &StringSlice{} + + for _, s := range strings.Split(val, ",") { + if err := f.Value.Set(strings.TrimSpace(s)); err != nil { + return fmt.Errorf("could not parse %q as string value for flag %s: %s", val, f.Name, err) + } + } + + f.HasBeenSet = true + } + + for _, name := range f.Names() { + if f.Value == nil { + f.Value = &StringSlice{} + } + set.Var(f.Value, name, f.Usage) + } + + return nil +} + +// StringSlice looks up the value of a local StringSliceFlag, returns +// nil if not found +func (c *Context) StringSlice(name string) []string { + if fs := lookupFlagSet(name, c); fs != nil { + return lookupStringSlice(name, fs) + } + return nil +} + +func lookupStringSlice(name string, set *flag.FlagSet) []string { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} diff --git a/vendor/github.com/urfave/cli/v2/flag_timestamp.go b/vendor/github.com/urfave/cli/v2/flag_timestamp.go new file mode 100644 index 0000000..d24edcd --- /dev/null +++ b/vendor/github.com/urfave/cli/v2/flag_timestamp.go @@ -0,0 +1,152 @@ +package cli + +import ( + "flag" + "fmt" + "time" +) + +// Timestamp wrap to satisfy golang's flag interface. +type Timestamp struct { + timestamp *time.Time + hasBeenSet bool + layout string +} + +// 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 +} + +// Parses the string value to timestamp +func (t *Timestamp) Set(value string) error { + 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 +} + +// TimestampFlag is a flag with type time +type TimestampFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + Layout string + Value *Timestamp + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *TimestampFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *TimestampFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *TimestampFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *TimestampFlag) IsRequired() bool { + return f.Required +} + +// TakesValue returns true of the flag takes a value, otherwise false +func (f *TimestampFlag) TakesValue() bool { + return true +} + +// GetUsage returns the usage string for the flag +func (f *TimestampFlag) GetUsage() string { + return f.Usage +} + +// GetValue returns the flags value as string representation and an empty +// string if the flag takes no value at all. +func (f *TimestampFlag) GetValue() string { + if f.Value != nil { + return f.Value.timestamp.String() + } + return "" +} + +// 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") + } + f.Value = &Timestamp{} + f.Value.SetLayout(f.Layout) + + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if err := f.Value.Set(val); err != nil { + return fmt.Errorf("could not parse %q as timestamp value for flag %s: %s", val, f.Name, err) + } + f.HasBeenSet = true + } + + for _, name := range f.Names() { + set.Var(f.Value, name, f.Usage) + } + return nil +} + +// Timestamp gets the timestamp from a flag name +func (c *Context) Timestamp(name string) *time.Time { + if fs := lookupFlagSet(name, c); 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 +} diff --git a/vendor/github.com/urfave/cli/flag_uint.go b/vendor/github.com/urfave/cli/v2/flag_uint.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_uint.go rename to vendor/github.com/urfave/cli/v2/flag_uint.go index d6a04f4..9f59238 100644 --- a/vendor/github.com/urfave/cli/flag_uint.go +++ b/vendor/github.com/urfave/cli/v2/flag_uint.go @@ -9,85 +9,84 @@ import ( // UintFlag is a flag with type uint type UintFlag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value uint + DefaultText string Destination *uint + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *UintFlag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f UintFlag) String() string { +func (f *UintFlag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f UintFlag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *UintFlag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f UintFlag) IsRequired() bool { +func (f *UintFlag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f UintFlag) TakesValue() bool { +func (f *UintFlag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f UintFlag) GetUsage() string { +func (f *UintFlag) GetUsage() string { return f.Usage } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f UintFlag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} +func (f *UintFlag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valInt, err := strconv.ParseUint(val, 0, 64) + if err != nil { + return fmt.Errorf("could not parse %q as uint value for flag %s: %s", val, f.Name, err) + } -// ApplyWithError populates the flag given the flag set and environment -func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValInt, err := strconv.ParseUint(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err) + f.Value = uint(valInt) + f.HasBeenSet = true } - - f.Value = uint(envValInt) } - eachName(f.Name, func(name string) { + for _, name := range f.Names() { if f.Destination != nil { set.UintVar(f.Destination, name, f.Value, f.Usage) - return + continue } set.Uint(name, f.Value, f.Usage) - }) + } 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 { +func (f *UintFlag) GetValue() string { return fmt.Sprintf("%d", f.Value) } // Uint looks up the value of a local UintFlag, returns // 0 if not found func (c *Context) Uint(name string) uint { - return lookupUint(name, c.flagSet) -} - -// GlobalUint looks up the value of a global UintFlag, returns -// 0 if not found -func (c *Context) GlobalUint(name string) uint { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupUint(name, fs) } return 0 diff --git a/vendor/github.com/urfave/cli/flag_uint64.go b/vendor/github.com/urfave/cli/v2/flag_uint64.go similarity index 56% rename from vendor/github.com/urfave/cli/flag_uint64.go rename to vendor/github.com/urfave/cli/v2/flag_uint64.go index ea6493a..5bbd1fa 100644 --- a/vendor/github.com/urfave/cli/flag_uint64.go +++ b/vendor/github.com/urfave/cli/v2/flag_uint64.go @@ -9,85 +9,84 @@ import ( // Uint64Flag is a flag with type uint64 type Uint64Flag struct { Name string + Aliases []string Usage string - EnvVar string + EnvVars []string FilePath string Required bool Hidden bool Value uint64 + DefaultText string Destination *uint64 + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *Uint64Flag) IsSet() bool { + return f.HasBeenSet } // String returns a readable representation of this value // (for usage defaults) -func (f Uint64Flag) String() string { +func (f *Uint64Flag) String() string { return FlagStringer(f) } -// GetName returns the name of the flag -func (f Uint64Flag) GetName() string { - return f.Name +// Names returns the names of the flag +func (f *Uint64Flag) Names() []string { + return flagNames(f) } // IsRequired returns whether or not the flag is required -func (f Uint64Flag) IsRequired() bool { +func (f *Uint64Flag) IsRequired() bool { return f.Required } // TakesValue returns true of the flag takes a value, otherwise false -func (f Uint64Flag) TakesValue() bool { +func (f *Uint64Flag) TakesValue() bool { return true } // GetUsage returns the usage string for the flag -func (f Uint64Flag) GetUsage() string { +func (f *Uint64Flag) GetUsage() string { return f.Usage } +// Apply populates the flag given the flag set and environment +func (f *Uint64Flag) Apply(set *flag.FlagSet) error { + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if val != "" { + valInt, err := strconv.ParseUint(val, 0, 64) + if err != nil { + return fmt.Errorf("could not parse %q as uint64 value for flag %s: %s", val, f.Name, err) + } + + 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 +} + // 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 { +func (f *Uint64Flag) GetValue() string { return fmt.Sprintf("%d", f.Value) } -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Uint64Flag) Apply(set *flag.FlagSet) { - _ = f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { - if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { - envValInt, err := strconv.ParseUint(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = envValInt - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.Uint64Var(f.Destination, name, f.Value, f.Usage) - return - } - set.Uint64(name, f.Value, f.Usage) - }) - - return nil -} - // Uint64 looks up the value of a local Uint64Flag, returns // 0 if not found func (c *Context) Uint64(name string) uint64 { - return lookupUint64(name, c.flagSet) -} - -// GlobalUint64 looks up the value of a global Uint64Flag, returns -// 0 if not found -func (c *Context) GlobalUint64(name string) uint64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { + if fs := lookupFlagSet(name, c); fs != nil { return lookupUint64(name, fs) } return 0 diff --git a/vendor/github.com/urfave/cli/funcs.go b/vendor/github.com/urfave/cli/v2/funcs.go similarity index 88% rename from vendor/github.com/urfave/cli/funcs.go rename to vendor/github.com/urfave/cli/v2/funcs.go index 0036b11..474c48f 100644 --- a/vendor/github.com/urfave/cli/funcs.go +++ b/vendor/github.com/urfave/cli/v2/funcs.go @@ -1,6 +1,6 @@ package cli -// BashCompleteFunc is an action to execute when the bash-completion flag is set +// BashCompleteFunc is an action to execute when the shell completion flag is set type BashCompleteFunc func(*Context) // BeforeFunc is an action to execute before any subcommands are run, but after @@ -23,7 +23,7 @@ type CommandNotFoundFunc func(*Context, string) // is displayed and the execution is interrupted. type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error -// ExitErrHandlerFunc is executed if provided in order to handle ExitError values +// ExitErrHandlerFunc is executed if provided in order to handle exitError values // returned by Actions and Before/After functions. type ExitErrHandlerFunc func(context *Context, err error) @@ -33,11 +33,11 @@ type FlagStringFunc func(Flag) string // FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix // text for a flag's full name. -type FlagNamePrefixFunc func(fullName, placeholder string) string +type FlagNamePrefixFunc func(fullName []string, placeholder string) string // FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help // with the environment variable details. -type FlagEnvHintFunc func(envVar, str string) string +type FlagEnvHintFunc func(envVars []string, str string) string // FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help // with the file path details. diff --git a/vendor/github.com/urfave/cli/go.mod b/vendor/github.com/urfave/cli/v2/go.mod similarity index 82% rename from vendor/github.com/urfave/cli/go.mod rename to vendor/github.com/urfave/cli/v2/go.mod index 7d04d20..c38d41c 100644 --- a/vendor/github.com/urfave/cli/go.mod +++ b/vendor/github.com/urfave/cli/v2/go.mod @@ -1,4 +1,4 @@ -module github.com/urfave/cli +module github.com/urfave/cli/v2 go 1.11 diff --git a/vendor/github.com/urfave/cli/go.sum b/vendor/github.com/urfave/cli/v2/go.sum similarity index 100% rename from vendor/github.com/urfave/cli/go.sum rename to vendor/github.com/urfave/cli/v2/go.sum diff --git a/vendor/github.com/urfave/cli/help.go b/vendor/github.com/urfave/cli/v2/help.go similarity index 91% rename from vendor/github.com/urfave/cli/help.go rename to vendor/github.com/urfave/cli/v2/help.go index 2280e33..c1e974a 100644 --- a/vendor/github.com/urfave/cli/help.go +++ b/vendor/github.com/urfave/cli/v2/help.go @@ -10,7 +10,7 @@ import ( "unicode/utf8" ) -var helpCommand = Command{ +var helpCommand = &Command{ Name: "help", Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", @@ -26,7 +26,7 @@ var helpCommand = Command{ }, } -var helpSubcommand = Command{ +var helpSubcommand = &Command{ Name: "help", Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", @@ -97,7 +97,7 @@ func DefaultAppComplete(c *Context) { DefaultCompleteWithFlags(nil)(c) } -func printCommandSuggestions(commands []Command, writer io.Writer) { +func printCommandSuggestions(commands []*Command, writer io.Writer) { for _, command := range commands { if command.Hidden { continue @@ -135,10 +135,10 @@ 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 { + if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden { continue } - for _, name := range strings.Split(flag.GetName(), ",") { + for _, name := range flag.Names() { name = strings.TrimSpace(name) // this will get total count utf8 letters in flag name count := utf8.RuneCountInString(name) @@ -151,7 +151,7 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) { continue } // match if last argument matches this flag and it is not repeated - if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(flag.GetName()) { + if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) { flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) _, _ = fmt.Fprintln(writer, flagCompletion) } @@ -207,7 +207,7 @@ func ShowCommandHelp(ctx *Context, command string) error { } if ctx.App.CommandNotFound == nil { - return NewExitError(fmt.Sprintf("No help topic for '%v'", command), 3) + return Exit(fmt.Sprintf("No help topic for '%v'", command), 3) } ctx.App.CommandNotFound(ctx, command) @@ -216,7 +216,15 @@ func ShowCommandHelp(ctx *Context, command string) error { // ShowSubcommandHelp prints help for the given subcommand func ShowSubcommandHelp(c *Context) error { - return ShowCommandHelp(c, c.Command.Name) + if c == nil { + return nil + } + + if c.Command != nil { + return ShowCommandHelp(c, c.Command.Name) + } + + return ShowCommandHelp(c, "") } // ShowVersion prints the version number of the App @@ -263,6 +271,7 @@ func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) + err := t.Execute(w, data) if err != nil { // If the writer is closed, t.Execute will fail, and there's nothing @@ -281,24 +290,20 @@ func printHelp(out io.Writer, templ string, data interface{}) { func checkVersion(c *Context) bool { found := false - if VersionFlag.GetName() != "" { - eachName(VersionFlag.GetName(), func(name string) { - if c.GlobalBool(name) || c.Bool(name) { - found = true - } - }) + for _, name := range VersionFlag.Names() { + if c.Bool(name) { + found = true + } } return found } func checkHelp(c *Context) bool { found := false - if HelpFlag.GetName() != "" { - eachName(HelpFlag.GetName(), func(name string) { - if c.GlobalBool(name) || c.Bool(name) { - found = true - } - }) + for _, name := range HelpFlag.Names() { + if c.Bool(name) { + found = true + } } return found } @@ -329,7 +334,7 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) { pos := len(arguments) - 1 lastArg := arguments[pos] - if lastArg != "--"+BashCompletionFlag.GetName() { + if lastArg != "--generate-bash-completion" { return false, arguments } diff --git a/vendor/github.com/urfave/cli/parse.go b/vendor/github.com/urfave/cli/v2/parse.go similarity index 88% rename from vendor/github.com/urfave/cli/parse.go rename to vendor/github.com/urfave/cli/v2/parse.go index 660f538..7df1729 100644 --- a/vendor/github.com/urfave/cli/parse.go +++ b/vendor/github.com/urfave/cli/v2/parse.go @@ -11,13 +11,18 @@ type iterativeParser interface { } // 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 +// 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. -func parseIter(set *flag.FlagSet, ip iterativeParser, args []string) error { +// 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 } diff --git a/vendor/github.com/urfave/cli/sort.go b/vendor/github.com/urfave/cli/v2/sort.go similarity index 100% rename from vendor/github.com/urfave/cli/sort.go rename to vendor/github.com/urfave/cli/v2/sort.go diff --git a/vendor/github.com/urfave/cli/template.go b/vendor/github.com/urfave/cli/v2/template.go similarity index 95% rename from vendor/github.com/urfave/cli/template.go rename to vendor/github.com/urfave/cli/v2/template.go index c631fb9..1cc4bd6 100644 --- a/vendor/github.com/urfave/cli/template.go +++ b/vendor/github.com/urfave/cli/v2/template.go @@ -20,7 +20,6 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} @@ -63,7 +62,6 @@ USAGE: {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} @@ -73,9 +71,9 @@ OPTIONS: {{end}}{{end}} ` -var MarkdownDocTemplate = `% {{ .App.Name }}(8) {{ .App.Description }} - -% {{ .App.Author }} +var MarkdownDocTemplate = `% {{ .App.Name }}(8){{ if .App.Description }} {{ .App.Description }}{{ end }} +{{ range $a := .App.Authors }} +% {{ $a }}{{ end }} # NAME diff --git a/vendor/modules.txt b/vendor/modules.txt index 28643f7..1f0163b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -38,8 +38,8 @@ github.com/src-d/gcfg/token github.com/src-d/gcfg/types # github.com/stretchr/testify v1.4.0 github.com/stretchr/testify/assert -# github.com/urfave/cli v1.22.2 -github.com/urfave/cli +# github.com/urfave/cli/v2 v2.1.1 +github.com/urfave/cli/v2 # github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent # golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4