refactor: urfave v2
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var AppCommand = cli.Command{
|
||||
@ -9,26 +9,26 @@ var AppCommand = cli.Command{
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Manage apps",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []cli.Command{
|
||||
appBackupCommand,
|
||||
appCheckCommand,
|
||||
appCmdCommand,
|
||||
appConfigCommand,
|
||||
appCpCommand,
|
||||
appDeployCommand,
|
||||
appListCommand,
|
||||
appLogsCommand,
|
||||
appNewCommand,
|
||||
appPsCommand,
|
||||
appRemoveCommand,
|
||||
appRestartCommand,
|
||||
appRestoreCommand,
|
||||
appRollbackCommand,
|
||||
appRunCommand,
|
||||
appSecretCommand,
|
||||
appServicesCommand,
|
||||
appUndeployCommand,
|
||||
appUpgradeCommand,
|
||||
appVolumeCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&appBackupCommand,
|
||||
&appCheckCommand,
|
||||
&appCmdCommand,
|
||||
&appConfigCommand,
|
||||
&appCpCommand,
|
||||
&appDeployCommand,
|
||||
&appListCommand,
|
||||
&appLogsCommand,
|
||||
&appNewCommand,
|
||||
&appPsCommand,
|
||||
&appRemoveCommand,
|
||||
&appRestartCommand,
|
||||
&appRestoreCommand,
|
||||
&appRollbackCommand,
|
||||
&appRunCommand,
|
||||
&appSecretCommand,
|
||||
&appServicesCommand,
|
||||
&appUndeployCommand,
|
||||
&appUpgradeCommand,
|
||||
&appVolumeCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -7,26 +7,29 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var snapshot string
|
||||
var snapshotFlag = &cli.StringFlag{
|
||||
Name: "snapshot, s",
|
||||
Name: "snapshot",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Lists specific snapshot",
|
||||
Destination: &snapshot,
|
||||
}
|
||||
|
||||
var includePath string
|
||||
var includePathFlag = &cli.StringFlag{
|
||||
Name: "path, p",
|
||||
Name: "path",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Include path",
|
||||
Destination: &includePath,
|
||||
}
|
||||
|
||||
var resticRepo string
|
||||
var resticRepoFlag = &cli.StringFlag{
|
||||
Name: "repo, r",
|
||||
Name: "repo",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Restic repository",
|
||||
Destination: &resticRepo,
|
||||
}
|
||||
@ -270,10 +273,10 @@ var appBackupCommand = cli.Command{
|
||||
Aliases: []string{"b"},
|
||||
Usage: "Manage app backups",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []cli.Command{
|
||||
appBackupListCommand,
|
||||
appBackupSnapshotsCommand,
|
||||
appBackupDownloadCommand,
|
||||
appBackupCreateCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&appBackupListCommand,
|
||||
&appBackupSnapshotsCommand,
|
||||
&appBackupDownloadCommand,
|
||||
&appBackupCreateCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appCheckCommand = cli.Command{
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appCmdCommand = cli.Command{
|
||||
@ -42,11 +42,13 @@ EXAMPLE:
|
||||
internal.OfflineFlag,
|
||||
internal.ChaosFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Subcommands: []cli.Command{appCmdListCommand},
|
||||
Before: internal.SubCommandBefore,
|
||||
Subcommands: []*cli.Command{
|
||||
&appCmdListCommand,
|
||||
},
|
||||
BashComplete: func(ctx *cli.Context) {
|
||||
args := ctx.Args()
|
||||
switch len(args) {
|
||||
switch args.Len() {
|
||||
case 0:
|
||||
autocomplete.AppNameComplete(ctx)
|
||||
case 1:
|
||||
@ -66,7 +68,7 @@ EXAMPLE:
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("cannot use --local & --user together"))
|
||||
}
|
||||
|
||||
hasCmdArgs, parsedCmdArgs := parseCmdArgs(c.Args(), internal.LocalCmd)
|
||||
hasCmdArgs, parsedCmdArgs := parseCmdArgs(c.Args().Slice(), internal.LocalCmd)
|
||||
|
||||
if _, err := os.Stat(app.Recipe.AbraShPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
@ -76,7 +78,7 @@ EXAMPLE:
|
||||
}
|
||||
|
||||
if internal.LocalCmd {
|
||||
if !(len(c.Args()) >= 2) {
|
||||
if !(c.Args().Len() >= 2) {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
||||
}
|
||||
|
||||
@ -112,7 +114,7 @@ EXAMPLE:
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
if !(len(c.Args()) >= 3) {
|
||||
if !(c.Args().Len() >= 3) {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments"))
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appConfigCommand = cli.Command{
|
||||
|
||||
@ -22,7 +22,7 @@ import (
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appCpCommand = cli.Command{
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appDeployCommand = cli.Command{
|
||||
|
||||
@ -12,13 +12,14 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
status bool
|
||||
statusFlag = &cli.BoolFlag{
|
||||
Name: "status, S",
|
||||
Name: "status",
|
||||
Aliases: []string{"S"},
|
||||
Usage: "Show app deployment status",
|
||||
Destination: &status,
|
||||
}
|
||||
@ -27,7 +28,8 @@ var (
|
||||
var (
|
||||
recipeFilter string
|
||||
recipeFlag = &cli.StringFlag{
|
||||
Name: "recipe, r",
|
||||
Name: "recipe",
|
||||
Aliases: []string{"r"},
|
||||
Value: "",
|
||||
Usage: "Show apps of a specific recipe",
|
||||
Destination: &recipeFilter,
|
||||
@ -37,7 +39,8 @@ var (
|
||||
var (
|
||||
listAppServer string
|
||||
listAppServerFlag = &cli.StringFlag{
|
||||
Name: "server, s",
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "Show apps of a specific server",
|
||||
Destination: &listAppServer,
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appLogsCommand = cli.Command{
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/charmbracelet/lipgloss/table"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appNewDescription = `
|
||||
@ -59,7 +59,7 @@ var appNewCommand = cli.Command{
|
||||
ArgsUsage: "[<recipe>] [<version>]",
|
||||
BashComplete: func(ctx *cli.Context) {
|
||||
args := ctx.Args()
|
||||
switch len(args) {
|
||||
switch args.Len() {
|
||||
case 0:
|
||||
autocomplete.RecipeNameComplete(ctx)
|
||||
case 1:
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
containerTypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appPsCommand = cli.Command{
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appRemoveCommand = cli.Command{
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
upstream "coopcloud.tech/abra/pkg/upstream/service"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appRestartCommand = cli.Command{
|
||||
|
||||
@ -7,12 +7,13 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var targetPath string
|
||||
var targetPathFlag = &cli.StringFlag{
|
||||
Name: "target, t",
|
||||
Name: "target",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Target path",
|
||||
Destination: &targetPath,
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appRollbackCommand = cli.Command{
|
||||
|
||||
@ -14,19 +14,21 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var user string
|
||||
var userFlag = &cli.StringFlag{
|
||||
Name: "user, u",
|
||||
Name: "user",
|
||||
Aliases: []string{"u"},
|
||||
Value: "",
|
||||
Destination: &user,
|
||||
}
|
||||
|
||||
var noTTY bool
|
||||
var noTTYFlag = &cli.BoolFlag{
|
||||
Name: "no-tty, t",
|
||||
Name: "no-tty",
|
||||
Aliases: []string{"t"},
|
||||
Destination: &noTTY,
|
||||
}
|
||||
|
||||
@ -45,11 +47,11 @@ var appRunCommand = cli.Command{
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
|
||||
if len(c.Args()) < 2 {
|
||||
if c.Args().Len() < 2 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided?"))
|
||||
}
|
||||
|
||||
if len(c.Args()) < 3 {
|
||||
if c.Args().Len() < 3 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no <args> provided?"))
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ var appRunCommand = cli.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := c.Args()[2:]
|
||||
cmd := c.Args().Slice()[2:]
|
||||
execCreateOpts := types.ExecConfig{
|
||||
AttachStderr: true,
|
||||
AttachStdin: true,
|
||||
|
||||
@ -17,13 +17,14 @@ import (
|
||||
"coopcloud.tech/abra/pkg/secret"
|
||||
"github.com/docker/docker/api/types"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
allSecrets bool
|
||||
allSecretsFlag = &cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Name: "all",
|
||||
Aliases: []string{"a"},
|
||||
Destination: &allSecrets,
|
||||
Usage: "Generate all secrets",
|
||||
}
|
||||
@ -32,7 +33,8 @@ var (
|
||||
var (
|
||||
rmAllSecrets bool
|
||||
rmAllSecretsFlag = &cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Name: "all",
|
||||
Aliases: []string{"a"},
|
||||
Destination: &rmAllSecrets,
|
||||
Usage: "Remove all secrets",
|
||||
}
|
||||
@ -59,7 +61,7 @@ var appSecretGenerateCommand = cli.Command{
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(c.Args()) == 1 && !allSecrets {
|
||||
if c.Args().Len() == 1 && !allSecrets {
|
||||
err := errors.New("missing arguments <secret>/<version> or '--all'")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
}
|
||||
@ -183,7 +185,7 @@ Example:
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(c.Args()) != 4 {
|
||||
if c.Args().Len() != 4 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?"))
|
||||
}
|
||||
|
||||
@ -419,10 +421,10 @@ var appSecretCommand = cli.Command{
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Manage app secrets",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []cli.Command{
|
||||
appSecretGenerateCommand,
|
||||
appSecretInsertCommand,
|
||||
appSecretRmCommand,
|
||||
appSecretLsCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&appSecretGenerateCommand,
|
||||
&appSecretInsertCommand,
|
||||
&appSecretRmCommand,
|
||||
&appSecretLsCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/service"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
containerTypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appServicesCommand = cli.Command{
|
||||
|
||||
@ -14,13 +14,14 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var prune bool
|
||||
|
||||
var pruneFlag = &cli.BoolFlag{
|
||||
Name: "prune, p",
|
||||
Name: "prune",
|
||||
Aliases: []string{"p"},
|
||||
Destination: &prune,
|
||||
Usage: "Prunes unused containers, networks, and dangling images for an app",
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appUpgradeCommand = cli.Command{
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var appVolumeListCommand = cli.Command{
|
||||
@ -159,8 +159,8 @@ var appVolumeCommand = cli.Command{
|
||||
Aliases: []string{"vl"},
|
||||
Usage: "Manage app volumes",
|
||||
ArgsUsage: "<domain>",
|
||||
Subcommands: []cli.Command{
|
||||
appVolumeListCommand,
|
||||
appVolumeRemoveCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&appVolumeListCommand,
|
||||
&appVolumeRemoveCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var catalogueGenerateCommand = cli.Command{
|
||||
@ -209,7 +209,7 @@ var CatalogueCommand = cli.Command{
|
||||
Usage: "Manage the recipe catalogue",
|
||||
Aliases: []string{"c"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Subcommands: []cli.Command{
|
||||
catalogueGenerateCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&catalogueGenerateCommand,
|
||||
},
|
||||
}
|
||||
|
||||
16
cli/cli.go
16
cli/cli.go
@ -18,7 +18,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/web"
|
||||
charmLog "github.com/charmbracelet/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// AutoCompleteCommand helps people set up auto-complete in their shells
|
||||
@ -159,13 +159,13 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
|_|
|
||||
`,
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
Commands: []cli.Command{
|
||||
app.AppCommand,
|
||||
server.ServerCommand,
|
||||
recipe.RecipeCommand,
|
||||
catalogue.CatalogueCommand,
|
||||
UpgradeCommand,
|
||||
AutoCompleteCommand,
|
||||
Commands: []*cli.Command{
|
||||
&app.AppCommand,
|
||||
&server.ServerCommand,
|
||||
&recipe.RecipeCommand,
|
||||
&catalogue.CatalogueCommand,
|
||||
&UpgradeCommand,
|
||||
&AutoCompleteCommand,
|
||||
},
|
||||
BashComplete: autocomplete.SubcommandComplete,
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Secrets stores the variable from SecretsFlag
|
||||
@ -12,7 +12,8 @@ var Secrets bool
|
||||
|
||||
// SecretsFlag turns on/off automatically generating secrets
|
||||
var SecretsFlag = &cli.BoolFlag{
|
||||
Name: "secrets, S",
|
||||
Name: "secrets",
|
||||
Aliases: []string{"S"},
|
||||
Usage: "Automatically generate secrets",
|
||||
Destination: &Secrets,
|
||||
}
|
||||
@ -22,7 +23,8 @@ var Pass bool
|
||||
|
||||
// PassFlag turns on/off storing generated secrets in pass
|
||||
var PassFlag = &cli.BoolFlag{
|
||||
Name: "pass, p",
|
||||
Name: "pass",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Store the generated secrets in a local pass store",
|
||||
Destination: &Pass,
|
||||
}
|
||||
@ -32,21 +34,24 @@ var PassRemove bool
|
||||
|
||||
// PassRemoveFlag turns on/off removing generated secrets from pass
|
||||
var PassRemoveFlag = &cli.BoolFlag{
|
||||
Name: "pass, p",
|
||||
Name: "pass",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Remove generated secrets from a local pass store",
|
||||
Destination: &PassRemove,
|
||||
}
|
||||
|
||||
var File bool
|
||||
var FileFlag = &cli.BoolFlag{
|
||||
Name: "file, f",
|
||||
Name: "file",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "Treat input as a file",
|
||||
Destination: &File,
|
||||
}
|
||||
|
||||
var Trim bool
|
||||
var TrimFlag = &cli.BoolFlag{
|
||||
Name: "trim, t",
|
||||
Name: "trim",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Trim input",
|
||||
Destination: &Trim,
|
||||
}
|
||||
@ -56,7 +61,8 @@ var Force bool
|
||||
|
||||
// ForceFlag turns on/off force functionality.
|
||||
var ForceFlag = &cli.BoolFlag{
|
||||
Name: "force, f",
|
||||
Name: "force",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "Perform action without further prompt. Use with care!",
|
||||
Destination: &Force,
|
||||
}
|
||||
@ -66,7 +72,8 @@ var Chaos bool
|
||||
|
||||
// ChaosFlag turns on/off chaos functionality.
|
||||
var ChaosFlag = &cli.BoolFlag{
|
||||
Name: "chaos, C",
|
||||
Name: "chaos",
|
||||
Aliases: []string{"C"},
|
||||
Usage: "Proceed with uncommitted recipes changes. Use with care!",
|
||||
Destination: &Chaos,
|
||||
}
|
||||
@ -76,14 +83,16 @@ var Tty bool
|
||||
|
||||
// TtyFlag turns on/off tty mode.
|
||||
var TtyFlag = &cli.BoolFlag{
|
||||
Name: "tty, T",
|
||||
Name: "tty",
|
||||
Aliases: []string{"T"},
|
||||
Usage: "Disables TTY mode to run this command from a script.",
|
||||
Destination: &Tty,
|
||||
}
|
||||
|
||||
var NoInput bool
|
||||
var NoInputFlag = &cli.BoolFlag{
|
||||
Name: "no-input, n",
|
||||
Name: "no-input",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "Toggle non-interactive mode",
|
||||
Destination: &NoInput,
|
||||
}
|
||||
@ -93,7 +102,8 @@ var Debug bool
|
||||
|
||||
// DebugFlag turns on/off verbose logging down to the DEBUG level.
|
||||
var DebugFlag = &cli.BoolFlag{
|
||||
Name: "debug, d",
|
||||
Name: "debug",
|
||||
Aliases: []string{"d"},
|
||||
Destination: &Debug,
|
||||
Usage: "Show DEBUG messages",
|
||||
}
|
||||
@ -103,7 +113,8 @@ var Offline bool
|
||||
|
||||
// DebugFlag turns on/off offline mode.
|
||||
var OfflineFlag = &cli.BoolFlag{
|
||||
Name: "offline, o",
|
||||
Name: "offline",
|
||||
Aliases: []string{"o"},
|
||||
Destination: &Offline,
|
||||
Usage: "Prefer offline & filesystem access when possible",
|
||||
}
|
||||
@ -113,7 +124,8 @@ var ReleaseNotes bool
|
||||
|
||||
// ReleaseNotesFlag turns on/off printing only release notes when upgrading.
|
||||
var ReleaseNotesFlag = &cli.BoolFlag{
|
||||
Name: "releasenotes, r",
|
||||
Name: "releasenotes",
|
||||
Aliases: []string{"r"},
|
||||
Destination: &ReleaseNotes,
|
||||
Usage: "Only show release notes",
|
||||
}
|
||||
@ -123,7 +135,8 @@ var MachineReadable bool
|
||||
|
||||
// MachineReadableFlag turns on/off machine readable output where supported
|
||||
var MachineReadableFlag = &cli.BoolFlag{
|
||||
Name: "machine, m",
|
||||
Name: "machine",
|
||||
Aliases: []string{"m"},
|
||||
Destination: &MachineReadable,
|
||||
Usage: "Output in a machine-readable format (where supported)",
|
||||
}
|
||||
@ -133,49 +146,56 @@ var RC bool
|
||||
|
||||
// RCFlag chooses the latest release candidate for install
|
||||
var RCFlag = &cli.BoolFlag{
|
||||
Name: "rc, r",
|
||||
Name: "rc",
|
||||
Aliases: []string{"r"},
|
||||
Destination: &RC,
|
||||
Usage: "Install the latest release candidate",
|
||||
}
|
||||
|
||||
var Major bool
|
||||
var MajorFlag = &cli.BoolFlag{
|
||||
Name: "major, x",
|
||||
Name: "major",
|
||||
Aliases: []string{"x"},
|
||||
Usage: "Increase the major part of the version",
|
||||
Destination: &Major,
|
||||
}
|
||||
|
||||
var Minor bool
|
||||
var MinorFlag = &cli.BoolFlag{
|
||||
Name: "minor, y",
|
||||
Name: "minor",
|
||||
Aliases: []string{"y"},
|
||||
Usage: "Increase the minor part of the version",
|
||||
Destination: &Minor,
|
||||
}
|
||||
|
||||
var Patch bool
|
||||
var PatchFlag = &cli.BoolFlag{
|
||||
Name: "patch, z",
|
||||
Name: "patch",
|
||||
Aliases: []string{"z"},
|
||||
Usage: "Increase the patch part of the version",
|
||||
Destination: &Patch,
|
||||
}
|
||||
|
||||
var Dry bool
|
||||
var DryFlag = &cli.BoolFlag{
|
||||
Name: "dry-run, r",
|
||||
Name: "dry-run",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Only reports changes that would be made",
|
||||
Destination: &Dry,
|
||||
}
|
||||
|
||||
var Publish bool
|
||||
var PublishFlag = &cli.BoolFlag{
|
||||
Name: "publish, p",
|
||||
Name: "publish",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Publish changes to git.coopcloud.tech",
|
||||
Destination: &Publish,
|
||||
}
|
||||
|
||||
var Domain string
|
||||
var DomainFlag = &cli.StringFlag{
|
||||
Name: "domain, D",
|
||||
Name: "domain",
|
||||
Aliases: []string{"D"},
|
||||
Value: "",
|
||||
Usage: "Choose a domain name",
|
||||
Destination: &Domain,
|
||||
@ -183,7 +203,8 @@ var DomainFlag = &cli.StringFlag{
|
||||
|
||||
var NewAppServer string
|
||||
var NewAppServerFlag = &cli.StringFlag{
|
||||
Name: "server, s",
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "Show apps of a specific server",
|
||||
Destination: &NewAppServer,
|
||||
@ -191,21 +212,24 @@ var NewAppServerFlag = &cli.StringFlag{
|
||||
|
||||
var NoDomainChecks bool
|
||||
var NoDomainChecksFlag = &cli.BoolFlag{
|
||||
Name: "no-domain-checks, D",
|
||||
Name: "no-domain-checks",
|
||||
Aliases: []string{"D"},
|
||||
Usage: "Disable public DNS checks",
|
||||
Destination: &NoDomainChecks,
|
||||
}
|
||||
|
||||
var StdErrOnly bool
|
||||
var StdErrOnlyFlag = &cli.BoolFlag{
|
||||
Name: "stderr, s",
|
||||
Name: "stderr",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Only tail stderr",
|
||||
Destination: &StdErrOnly,
|
||||
}
|
||||
|
||||
var SinceLogs string
|
||||
var SinceLogsFlag = &cli.StringFlag{
|
||||
Name: "since, S",
|
||||
Name: "since",
|
||||
Aliases: []string{"S"},
|
||||
Value: "",
|
||||
Usage: "tail logs since YYYY-MM-DDTHH:MM:SSZ",
|
||||
Destination: &SinceLogs,
|
||||
@ -213,49 +237,56 @@ var SinceLogsFlag = &cli.StringFlag{
|
||||
|
||||
var DontWaitConverge bool
|
||||
var DontWaitConvergeFlag = &cli.BoolFlag{
|
||||
Name: "no-converge-checks, c",
|
||||
Name: "no-converge-checks",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Don't wait for converge logic checks",
|
||||
Destination: &DontWaitConverge,
|
||||
}
|
||||
|
||||
var Watch bool
|
||||
var WatchFlag = &cli.BoolFlag{
|
||||
Name: "watch, w",
|
||||
Name: "watch",
|
||||
Aliases: []string{"w"},
|
||||
Usage: "Watch status by polling repeatedly",
|
||||
Destination: &Watch,
|
||||
}
|
||||
|
||||
var OnlyErrors bool
|
||||
var OnlyErrorFlag = &cli.BoolFlag{
|
||||
Name: "errors, e",
|
||||
Name: "errors",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Only show errors",
|
||||
Destination: &OnlyErrors,
|
||||
}
|
||||
|
||||
var SkipUpdates bool
|
||||
var SkipUpdatesFlag = &cli.BoolFlag{
|
||||
Name: "skip-updates, s",
|
||||
Name: "skip-updates",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Skip updating recipe repositories",
|
||||
Destination: &SkipUpdates,
|
||||
}
|
||||
|
||||
var AllTags bool
|
||||
var AllTagsFlag = &cli.BoolFlag{
|
||||
Name: "all-tags, a",
|
||||
Name: "all-tags",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "List all tags, not just upgrades",
|
||||
Destination: &AllTags,
|
||||
}
|
||||
|
||||
var LocalCmd bool
|
||||
var LocalCmdFlag = &cli.BoolFlag{
|
||||
Name: "local, l",
|
||||
Name: "local",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "Run command locally",
|
||||
Destination: &LocalCmd,
|
||||
}
|
||||
|
||||
var RemoteUser string
|
||||
var RemoteUserFlag = &cli.StringFlag{
|
||||
Name: "user, u",
|
||||
Name: "user",
|
||||
Aliases: []string{"u"},
|
||||
Value: "",
|
||||
Usage: "User to run command within a service context",
|
||||
Destination: &RemoteUser,
|
||||
@ -263,7 +294,8 @@ var RemoteUserFlag = &cli.StringFlag{
|
||||
|
||||
var GitName string
|
||||
var GitNameFlag = &cli.StringFlag{
|
||||
Name: "git-name, gn",
|
||||
Name: "git-name",
|
||||
Aliases: []string{"gn"},
|
||||
Value: "",
|
||||
Usage: "Git (user) name to do commits with",
|
||||
Destination: &GitName,
|
||||
@ -271,7 +303,8 @@ var GitNameFlag = &cli.StringFlag{
|
||||
|
||||
var GitEmail string
|
||||
var GitEmailFlag = &cli.StringFlag{
|
||||
Name: "git-email, ge",
|
||||
Name: "git-email",
|
||||
Aliases: []string{"ge"},
|
||||
Value: "",
|
||||
Usage: "Git email name to do commits with",
|
||||
Destination: &GitEmail,
|
||||
@ -279,7 +312,8 @@ var GitEmailFlag = &cli.StringFlag{
|
||||
|
||||
var AllServices bool
|
||||
var AllServicesFlag = &cli.BoolFlag{
|
||||
Name: "all-services, a",
|
||||
Name: "all-services",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Restart all services",
|
||||
Destination: &AllServices,
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ShowSubcommandHelpAndError exits the program on error, logs the error to the
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ValidateRecipe ensures the recipe arg is valid.
|
||||
@ -125,9 +125,9 @@ func ValidateDomain(c *cli.Context) string {
|
||||
|
||||
// ValidateSubCmdFlags ensures flag order conforms to correct order
|
||||
func ValidateSubCmdFlags(c *cli.Context) bool {
|
||||
for argIdx, arg := range c.Args() {
|
||||
for argIdx, arg := range c.Args().Slice() {
|
||||
if !strings.HasPrefix(arg, "--") {
|
||||
for _, flag := range c.Args()[argIdx:] {
|
||||
for _, flag := range c.Args().Slice()[argIdx:] {
|
||||
if strings.HasPrefix(flag, "--") {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeDiffCommand = cli.Command{
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeFetchCommand = cli.Command{
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeLintCommand = cli.Command{
|
||||
|
||||
@ -10,12 +10,13 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var pattern string
|
||||
var patternFlag = &cli.StringFlag{
|
||||
Name: "pattern, p",
|
||||
Name: "pattern",
|
||||
Aliases: []string{"p"},
|
||||
Value: "",
|
||||
Usage: "Simple string to filter recipes",
|
||||
Destination: &pattern,
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// recipeMetadata is the recipe metadata for the README.md
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// RecipeCommand defines all recipe related sub-commands.
|
||||
@ -19,16 +19,16 @@ for you.
|
||||
Anyone who uses a recipe can become a maintainer. Maintainers typically make
|
||||
sure the recipe is in good working order and the config upgraded in a timely
|
||||
manner.`,
|
||||
Subcommands: []cli.Command{
|
||||
recipeFetchCommand,
|
||||
recipeLintCommand,
|
||||
recipeListCommand,
|
||||
recipeNewCommand,
|
||||
recipeReleaseCommand,
|
||||
recipeSyncCommand,
|
||||
recipeUpgradeCommand,
|
||||
recipeVersionCommand,
|
||||
recipeResetCommand,
|
||||
recipeDiffCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&recipeFetchCommand,
|
||||
&recipeLintCommand,
|
||||
&recipeListCommand,
|
||||
&recipeNewCommand,
|
||||
&recipeReleaseCommand,
|
||||
&recipeSyncCommand,
|
||||
&recipeUpgradeCommand,
|
||||
&recipeVersionCommand,
|
||||
&recipeResetCommand,
|
||||
&recipeDiffCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeReleaseCommand = cli.Command{
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeResetCommand = cli.Command{
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var recipeSyncCommand = cli.Command{
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type imgPin struct {
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func sortServiceByName(versions [][]string) func(i, j int) bool {
|
||||
|
||||
@ -13,12 +13,13 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/server"
|
||||
sshPkg "coopcloud.tech/abra/pkg/ssh"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var local bool
|
||||
var localFlag = &cli.BoolFlag{
|
||||
Name: "local, l",
|
||||
Name: "local",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "Use local server",
|
||||
Destination: &local,
|
||||
}
|
||||
@ -131,7 +132,7 @@ of your ~/.ssh/config. Checks for a valid online domain will be skipped:
|
||||
Before: internal.SubCommandBefore,
|
||||
ArgsUsage: "<name>",
|
||||
Action: func(c *cli.Context) error {
|
||||
if len(c.Args()) > 0 && local || !internal.ValidateSubCmdFlags(c) {
|
||||
if c.Args().Len() > 0 && local || !internal.ValidateSubCmdFlags(c) {
|
||||
err := errors.New("cannot use <name> and --local together")
|
||||
internal.ShowSubcommandHelpAndError(c, err)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/docker/cli/cli/connhelper/ssh"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var serverListCommand = cli.Command{
|
||||
|
||||
@ -9,13 +9,14 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var allFilter bool
|
||||
|
||||
var allFilterFlag = &cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Name: "all",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Remove all unused images not just dangling ones",
|
||||
Destination: &allFilter,
|
||||
}
|
||||
@ -23,7 +24,8 @@ var allFilterFlag = &cli.BoolFlag{
|
||||
var volumesFilter bool
|
||||
|
||||
var volumesFilterFlag = &cli.BoolFlag{
|
||||
Name: "volumes, v",
|
||||
Name: "volumes",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "Prune volumes. This will remove app data, Be Careful!",
|
||||
Destination: &volumesFilter,
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var serverRemoveCommand = cli.Command{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ServerCommand defines the `abra server` command and its subcommands
|
||||
@ -9,10 +9,10 @@ var ServerCommand = cli.Command{
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Manage servers",
|
||||
Subcommands: []cli.Command{
|
||||
serverAddCommand,
|
||||
serverListCommand,
|
||||
serverRemoveCommand,
|
||||
serverPruneCommand,
|
||||
Subcommands: []*cli.Command{
|
||||
&serverAddCommand,
|
||||
&serverListCommand,
|
||||
&serverRemoveCommand,
|
||||
&serverPruneCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -23,21 +23,23 @@ import (
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const SERVER = "localhost"
|
||||
|
||||
var majorUpdate bool
|
||||
var majorFlag = &cli.BoolFlag{
|
||||
Name: "major, m",
|
||||
Name: "major",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "Also check for major updates",
|
||||
Destination: &majorUpdate,
|
||||
}
|
||||
|
||||
var updateAll bool
|
||||
var allFlag = &cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Name: "all",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Update all deployed apps",
|
||||
Destination: &updateAll,
|
||||
}
|
||||
@ -480,9 +482,9 @@ func newAbraApp(version, commit string) *cli.App {
|
||||
|_|
|
||||
`,
|
||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
||||
Commands: []cli.Command{
|
||||
Notify,
|
||||
UpgradeApp,
|
||||
Commands: []*cli.Command{
|
||||
&Notify,
|
||||
&UpgradeApp,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
3
go.mod
3
go.mod
@ -18,6 +18,7 @@ require (
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/schollz/progressbar/v3 v3.14.4
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
golang.org/x/term v0.22.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools/v3 v3.5.1
|
||||
@ -91,6 +92,7 @@ require (
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect
|
||||
@ -133,7 +135,6 @@ require (
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||
github.com/urfave/cli v1.22.15
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
golang.org/x/sys v0.22.0
|
||||
)
|
||||
|
||||
13
go.sum
13
go.sum
@ -49,7 +49,6 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -858,9 +857,6 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -868,9 +864,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
@ -890,8 +883,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
|
||||
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
|
||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
||||
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
@ -913,6 +906,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/app"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// AppNameComplete copletes app names.
|
||||
|
||||
2
vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
Normal file
2
vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
14
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
Normal file
14
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
*.coverprofile
|
||||
*.exe
|
||||
*.orig
|
||||
.*envrc
|
||||
.envrc
|
||||
.idea
|
||||
# goimports is installed here if not available
|
||||
/.local/
|
||||
/site/
|
||||
coverage.txt
|
||||
internal/*/built-example
|
||||
vendor
|
||||
/cmd/urfave-cli-genflags/urfave-cli-genflags
|
||||
*.exe
|
||||
4
vendor/github.com/urfave/cli/v2/.golangci.yaml
generated
vendored
Normal file
4
vendor/github.com/urfave/cli/v2/.golangci.yaml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
linters:
|
||||
enable:
|
||||
- misspell
|
||||
75
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
generated
vendored
Normal file
75
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting urfave-governance@googlegroups.com, a members-only group
|
||||
that is world-postable. All complaints will be reviewed and investigated and
|
||||
will result in a response that is deemed necessary and appropriate to the
|
||||
circumstances. The project team is obligated to maintain confidentiality with
|
||||
regard to the reporter of an incident. Further details of specific enforcement
|
||||
policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
21
vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
Normal file
21
vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 urfave/cli maintainers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
26
vendor/github.com/urfave/cli/v2/Makefile
generated
vendored
Normal file
26
vendor/github.com/urfave/cli/v2/Makefile
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# NOTE: this Makefile is meant to provide a simplified entry point for humans to
|
||||
# run all of the critical steps to verify one's changes are harmonious in
|
||||
# nature. Keeping target bodies to one line each and abstaining from make magic
|
||||
# are very important so that maintainers and contributors can focus their
|
||||
# attention on files that are primarily Go.
|
||||
|
||||
GO_RUN_BUILD := go run internal/build/build.go
|
||||
|
||||
.PHONY: all
|
||||
all: generate vet test check-binary-size gfmrun yamlfmt v2diff
|
||||
|
||||
# NOTE: this is a special catch-all rule to run any of the commands
|
||||
# defined in internal/build/build.go with optional arguments passed
|
||||
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
|
||||
#
|
||||
# $ make test GFLAGS='--packages cli'
|
||||
%:
|
||||
$(GO_RUN_BUILD) $(GFLAGS) $* $(FLAGS)
|
||||
|
||||
.PHONY: docs
|
||||
docs:
|
||||
mkdocs build
|
||||
|
||||
.PHONY: serve-docs
|
||||
serve-docs:
|
||||
mkdocs serve
|
||||
19
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
Normal file
19
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# cli
|
||||
|
||||
[](https://github.com/urfave/cli/actions/workflows/cli.yml)
|
||||
[](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||
[](https://goreportcard.com/report/github.com/urfave/cli/v2)
|
||||
[](https://app.codecov.io/gh/urfave/cli/tree/v2-maint)
|
||||
|
||||
cli is a simple, fast, and fun package for building command line apps in Go. The
|
||||
goal is to enable developers to write fast and distributable command line
|
||||
applications in an expressive way.
|
||||
|
||||
## Documentation
|
||||
|
||||
More documentation is available in [`./docs`](./docs) or the hosted
|
||||
documentation site at <https://cli.urfave.org>.
|
||||
|
||||
## License
|
||||
|
||||
See [`LICENSE`](./LICENSE)
|
||||
536
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
Normal file
536
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
Normal file
@ -0,0 +1,536 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const suggestDidYouMeanTemplate = "Did you mean %q?"
|
||||
|
||||
var (
|
||||
changeLogURL = "https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md"
|
||||
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
|
||||
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
|
||||
errInvalidActionType = NewExitError("ERROR invalid Action type. "+
|
||||
fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+
|
||||
fmt.Sprintf("See %s", appActionDeprecationURL), 2)
|
||||
ignoreFlagPrefix = "test." // this is to ignore test flags when adding flags from other packages
|
||||
|
||||
SuggestFlag SuggestFlagFunc = nil // initialized in suggestions.go unless built with urfave_cli_no_suggest
|
||||
SuggestCommand SuggestCommandFunc = nil // initialized in suggestions.go unless built with urfave_cli_no_suggest
|
||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||
)
|
||||
|
||||
// App is the main structure of a cli application. It is recommended that
|
||||
// an app be created with the cli.NewApp() function
|
||||
type App struct {
|
||||
// The name of the program. Defaults to path.Base(os.Args[0])
|
||||
Name string
|
||||
// Full name of command for help, defaults to Name
|
||||
HelpName string
|
||||
// Description of the program.
|
||||
Usage string
|
||||
// Text to override the USAGE section of help
|
||||
UsageText string
|
||||
// Whether this command supports arguments
|
||||
Args bool
|
||||
// Description of the program argument format.
|
||||
ArgsUsage string
|
||||
// Version of the program
|
||||
Version string
|
||||
// Description of the program
|
||||
Description string
|
||||
// DefaultCommand is the (optional) name of a command
|
||||
// to run if no command names are passed as CLI arguments.
|
||||
DefaultCommand string
|
||||
// List of commands to execute
|
||||
Commands []*Command
|
||||
// List of flags to parse
|
||||
Flags []Flag
|
||||
// Boolean to enable bash completion commands
|
||||
EnableBashCompletion bool
|
||||
// Boolean to hide built-in help command and help flag
|
||||
HideHelp bool
|
||||
// Boolean to hide built-in help command but keep help flag.
|
||||
// Ignored if HideHelp is true.
|
||||
HideHelpCommand bool
|
||||
// Boolean to hide built-in version flag and the VERSION section of help
|
||||
HideVersion bool
|
||||
// categories contains the categorized commands and is populated on app startup
|
||||
categories CommandCategories
|
||||
// flagCategories contains the categorized flags and is populated on app startup
|
||||
flagCategories FlagCategories
|
||||
// An action to execute when the shell completion flag is set
|
||||
BashComplete BashCompleteFunc
|
||||
// An action to execute before any subcommands are run, but after the context is ready
|
||||
// If a non-nil error is returned, no subcommands are run
|
||||
Before BeforeFunc
|
||||
// An action to execute after any subcommands are run, but after the subcommand has finished
|
||||
// It is run even if Action() panics
|
||||
After AfterFunc
|
||||
// The action to execute when no subcommands are specified
|
||||
Action ActionFunc
|
||||
// Execute this function if the proper command cannot be found
|
||||
CommandNotFound CommandNotFoundFunc
|
||||
// Execute this function if a usage error occurs
|
||||
OnUsageError OnUsageErrorFunc
|
||||
// Execute this function when an invalid flag is accessed from the context
|
||||
InvalidFlagAccessHandler InvalidFlagAccessFunc
|
||||
// Compilation date
|
||||
Compiled time.Time
|
||||
// List of all authors who contributed
|
||||
Authors []*Author
|
||||
// Copyright of the binary if any
|
||||
Copyright string
|
||||
// Reader reader to write input to (useful for tests)
|
||||
Reader io.Reader
|
||||
// Writer writer to write output to
|
||||
Writer io.Writer
|
||||
// ErrWriter writes error output
|
||||
ErrWriter io.Writer
|
||||
// ExitErrHandler processes any error encountered while running an App before
|
||||
// it is returned to the caller. If no function is provided, HandleExitCoder
|
||||
// is used as the default behavior.
|
||||
ExitErrHandler ExitErrHandlerFunc
|
||||
// Other custom info
|
||||
Metadata map[string]interface{}
|
||||
// Carries a function which returns app specific info.
|
||||
ExtraInfo func() map[string]string
|
||||
// CustomAppHelpTemplate the text template for app help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
CustomAppHelpTemplate string
|
||||
// SliceFlagSeparator is used to customize the separator for SliceFlag, the default is ","
|
||||
SliceFlagSeparator string
|
||||
// DisableSliceFlagSeparator is used to disable SliceFlagSeparator, the default is false
|
||||
DisableSliceFlagSeparator bool
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
// Enable suggestions for commands and flags
|
||||
Suggest bool
|
||||
// Allows global flags set by libraries which use flag.XXXVar(...) directly
|
||||
// to be parsed through this library
|
||||
AllowExtFlags bool
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool
|
||||
|
||||
didSetup bool
|
||||
separator separatorSpec
|
||||
|
||||
rootCommand *Command
|
||||
}
|
||||
|
||||
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
|
||||
|
||||
type SuggestCommandFunc func(commands []*Command, provided string) string
|
||||
|
||||
// Tries to find out when this binary was compiled.
|
||||
// Returns the current time if it fails to find it.
|
||||
func compileTime() time.Time {
|
||||
info, err := os.Stat(os.Args[0])
|
||||
if err != nil {
|
||||
return time.Now()
|
||||
}
|
||||
return info.ModTime()
|
||||
}
|
||||
|
||||
// NewApp creates a new cli Application with some reasonable defaults for Name,
|
||||
// Usage, Version and Action.
|
||||
func NewApp() *App {
|
||||
return &App{
|
||||
Name: filepath.Base(os.Args[0]),
|
||||
Usage: "A new cli application",
|
||||
UsageText: "",
|
||||
BashComplete: DefaultAppComplete,
|
||||
Action: helpCommand.Action,
|
||||
Compiled: compileTime(),
|
||||
Reader: os.Stdin,
|
||||
Writer: os.Stdout,
|
||||
ErrWriter: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// Setup runs initialization code to ensure all data structures are ready for
|
||||
// `Run` or inspection prior to `Run`. It is internally called by `Run`, but
|
||||
// will return early if setup has already happened.
|
||||
func (a *App) Setup() {
|
||||
if a.didSetup {
|
||||
return
|
||||
}
|
||||
|
||||
a.didSetup = true
|
||||
|
||||
if a.Name == "" {
|
||||
a.Name = filepath.Base(os.Args[0])
|
||||
}
|
||||
|
||||
if a.HelpName == "" {
|
||||
a.HelpName = a.Name
|
||||
}
|
||||
|
||||
if a.Usage == "" {
|
||||
a.Usage = "A new cli application"
|
||||
}
|
||||
|
||||
if a.Version == "" {
|
||||
a.HideVersion = true
|
||||
}
|
||||
|
||||
if a.BashComplete == nil {
|
||||
a.BashComplete = DefaultAppComplete
|
||||
}
|
||||
|
||||
if a.Action == nil {
|
||||
a.Action = helpCommand.Action
|
||||
}
|
||||
|
||||
if a.Compiled == (time.Time{}) {
|
||||
a.Compiled = compileTime()
|
||||
}
|
||||
|
||||
if a.Reader == nil {
|
||||
a.Reader = os.Stdin
|
||||
}
|
||||
|
||||
if a.Writer == nil {
|
||||
a.Writer = os.Stdout
|
||||
}
|
||||
|
||||
if a.ErrWriter == nil {
|
||||
a.ErrWriter = os.Stderr
|
||||
}
|
||||
|
||||
if a.AllowExtFlags {
|
||||
// add global flags added by other packages
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
// skip test flags
|
||||
if !strings.HasPrefix(f.Name, ignoreFlagPrefix) {
|
||||
a.Flags = append(a.Flags, &extFlag{f})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if len(a.SliceFlagSeparator) != 0 {
|
||||
a.separator.customized = true
|
||||
a.separator.sep = a.SliceFlagSeparator
|
||||
}
|
||||
|
||||
if a.DisableSliceFlagSeparator {
|
||||
a.separator.customized = true
|
||||
a.separator.disabled = true
|
||||
}
|
||||
|
||||
for _, c := range a.Commands {
|
||||
cname := c.Name
|
||||
if c.HelpName != "" {
|
||||
cname = c.HelpName
|
||||
}
|
||||
c.separator = a.separator
|
||||
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname)
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
}
|
||||
|
||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
||||
if !a.HideHelpCommand {
|
||||
a.appendCommand(helpCommand)
|
||||
}
|
||||
|
||||
if HelpFlag != nil {
|
||||
a.appendFlag(HelpFlag)
|
||||
}
|
||||
}
|
||||
|
||||
if !a.HideVersion {
|
||||
a.appendFlag(VersionFlag)
|
||||
}
|
||||
|
||||
a.categories = newCommandCategories()
|
||||
for _, command := range a.Commands {
|
||||
a.categories.AddCommand(command.Category, command)
|
||||
}
|
||||
sort.Sort(a.categories.(*commandCategories))
|
||||
|
||||
a.flagCategories = newFlagCategoriesFromFlags(a.Flags)
|
||||
|
||||
if a.Metadata == nil {
|
||||
a.Metadata = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) newRootCommand() *Command {
|
||||
return &Command{
|
||||
Name: a.Name,
|
||||
Usage: a.Usage,
|
||||
UsageText: a.UsageText,
|
||||
Description: a.Description,
|
||||
ArgsUsage: a.ArgsUsage,
|
||||
BashComplete: a.BashComplete,
|
||||
Before: a.Before,
|
||||
After: a.After,
|
||||
Action: a.Action,
|
||||
OnUsageError: a.OnUsageError,
|
||||
Subcommands: a.Commands,
|
||||
Flags: a.Flags,
|
||||
flagCategories: a.flagCategories,
|
||||
HideHelp: a.HideHelp,
|
||||
HideHelpCommand: a.HideHelpCommand,
|
||||
UseShortOptionHandling: a.UseShortOptionHandling,
|
||||
HelpName: a.HelpName,
|
||||
CustomHelpTemplate: a.CustomAppHelpTemplate,
|
||||
categories: a.categories,
|
||||
SkipFlagParsing: a.SkipFlagParsing,
|
||||
isRoot: true,
|
||||
separator: a.separator,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
||||
return flagSet(a.Name, a.Flags, a.separator)
|
||||
}
|
||||
|
||||
func (a *App) useShortOptionHandling() bool {
|
||||
return a.UseShortOptionHandling
|
||||
}
|
||||
|
||||
// Run is the entry point to the cli app. Parses the arguments slice and routes
|
||||
// to the proper flag/args combination
|
||||
func (a *App) Run(arguments []string) (err error) {
|
||||
return a.RunContext(context.Background(), arguments)
|
||||
}
|
||||
|
||||
// RunContext is like Run except it takes a Context that will be
|
||||
// passed to its commands and sub-commands. Through this, you can
|
||||
// propagate timeouts and cancellation requests
|
||||
func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||
a.Setup()
|
||||
|
||||
// handle the completion flag separately from the flagset since
|
||||
// completion could be attempted after a flag, but before its value was put
|
||||
// on the command line. this causes the flagset to interpret the completion
|
||||
// flag name as the value of the flag before it which is undesirable
|
||||
// note that we can only do this because the shell autocomplete function
|
||||
// always appends the completion flag at the end of the command
|
||||
shellComplete, arguments := checkShellCompleteFlag(a, arguments)
|
||||
|
||||
cCtx := NewContext(a, nil, &Context{Context: ctx})
|
||||
cCtx.shellComplete = shellComplete
|
||||
|
||||
a.rootCommand = a.newRootCommand()
|
||||
cCtx.Command = a.rootCommand
|
||||
|
||||
if err := checkDuplicatedCmds(a.rootCommand); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.rootCommand.Run(cCtx, arguments...)
|
||||
}
|
||||
|
||||
// RunAsSubcommand is for legacy/compatibility purposes only. New code should only
|
||||
// use App.RunContext. This function is slated to be removed in v3.
|
||||
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
||||
a.Setup()
|
||||
|
||||
cCtx := NewContext(a, nil, ctx)
|
||||
cCtx.shellComplete = ctx.shellComplete
|
||||
|
||||
a.rootCommand = a.newRootCommand()
|
||||
cCtx.Command = a.rootCommand
|
||||
|
||||
return a.rootCommand.Run(cCtx, ctx.Args().Slice()...)
|
||||
}
|
||||
|
||||
func (a *App) suggestFlagFromError(err error, command string) (string, error) {
|
||||
flag, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := a.Flags
|
||||
hideHelp := a.HideHelp
|
||||
if command != "" {
|
||||
cmd := a.Command(command)
|
||||
if cmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = cmd.Flags
|
||||
hideHelp = hideHelp || cmd.HideHelp
|
||||
}
|
||||
|
||||
if SuggestFlag == nil {
|
||||
return "", err
|
||||
}
|
||||
suggestion := SuggestFlag(flags, flag, hideHelp)
|
||||
if len(suggestion) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate+"\n\n", suggestion), nil
|
||||
}
|
||||
|
||||
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
||||
//
|
||||
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
||||
// to cli.App.Run. This will cause the application to exit with the given error
|
||||
// code in the cli.ExitCoder
|
||||
func (a *App) RunAndExitOnError() {
|
||||
if err := a.Run(os.Args); err != nil {
|
||||
_, _ = fmt.Fprintln(a.ErrWriter, err)
|
||||
OsExiter(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Command returns the named command on App. Returns nil if the command does not exist
|
||||
func (a *App) Command(name string) *Command {
|
||||
for _, c := range a.Commands {
|
||||
if c.HasName(name) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VisibleCategories returns a slice of categories and commands that are
|
||||
// Hidden=false
|
||||
func (a *App) VisibleCategories() []CommandCategory {
|
||||
ret := []CommandCategory{}
|
||||
for _, category := range a.categories.Categories() {
|
||||
if visible := func() CommandCategory {
|
||||
if len(category.VisibleCommands()) > 0 {
|
||||
return category
|
||||
}
|
||||
return nil
|
||||
}(); visible != nil {
|
||||
ret = append(ret, visible)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (a *App) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range a.Commands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, command)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the categories with the flags they contain
|
||||
func (a *App) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if a.flagCategories == nil {
|
||||
return []VisibleFlagCategory{}
|
||||
}
|
||||
return a.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (a *App) VisibleFlags() []Flag {
|
||||
return visibleFlags(a.Flags)
|
||||
}
|
||||
|
||||
func (a *App) appendFlag(fl Flag) {
|
||||
if !hasFlag(a.Flags, fl) {
|
||||
a.Flags = append(a.Flags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) appendCommand(c *Command) {
|
||||
if !hasCommand(a.Commands, c) {
|
||||
a.Commands = append(a.Commands, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) handleExitCoder(cCtx *Context, err error) {
|
||||
if a.ExitErrHandler != nil {
|
||||
a.ExitErrHandler(cCtx, err)
|
||||
} else {
|
||||
HandleExitCoder(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) argsWithDefaultCommand(oldArgs Args) Args {
|
||||
if a.DefaultCommand != "" {
|
||||
rawArgs := append([]string{a.DefaultCommand}, oldArgs.Slice()...)
|
||||
newArgs := args(rawArgs)
|
||||
|
||||
return &newArgs
|
||||
}
|
||||
|
||||
return oldArgs
|
||||
}
|
||||
|
||||
func runFlagActions(c *Context, fs []Flag) error {
|
||||
for _, f := range fs {
|
||||
isSet := false
|
||||
for _, name := range f.Names() {
|
||||
if c.IsSet(name) {
|
||||
isSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isSet {
|
||||
if af, ok := f.(ActionableFlag); ok {
|
||||
if err := af.RunAction(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Author represents someone who has contributed to a cli project.
|
||||
type Author struct {
|
||||
Name string // The Authors name
|
||||
Email string // The Authors email
|
||||
}
|
||||
|
||||
// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
|
||||
func (a *Author) String() string {
|
||||
e := ""
|
||||
if a.Email != "" {
|
||||
e = " <" + a.Email + ">"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%v", a.Name, e)
|
||||
}
|
||||
|
||||
// HandleAction attempts to figure out which Action signature was used. If
|
||||
// it's an ActionFunc or a func with the legacy signature for Action, the func
|
||||
// is run!
|
||||
func HandleAction(action interface{}, cCtx *Context) (err error) {
|
||||
switch a := action.(type) {
|
||||
case ActionFunc:
|
||||
return a(cCtx)
|
||||
case func(*Context) error:
|
||||
return a(cCtx)
|
||||
case func(*Context): // deprecated function signature
|
||||
a(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
return errInvalidActionType
|
||||
}
|
||||
|
||||
func checkStringSliceIncludes(want string, sSlice []string) bool {
|
||||
found := false
|
||||
for _, s := range sSlice {
|
||||
if want == s {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
54
vendor/github.com/urfave/cli/v2/args.go
generated
vendored
Normal file
54
vendor/github.com/urfave/cli/v2/args.go
generated
vendored
Normal file
@ -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
|
||||
}
|
||||
186
vendor/github.com/urfave/cli/v2/category.go
generated
vendored
Normal file
186
vendor/github.com/urfave/cli/v2/category.go
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
package cli
|
||||
|
||||
import "sort"
|
||||
|
||||
// CommandCategories interface allows for category manipulation
|
||||
type CommandCategories interface {
|
||||
// AddCommand adds a command to a category, creating a new category if necessary.
|
||||
AddCommand(category string, command *Command)
|
||||
// Categories returns a slice of categories sorted by name
|
||||
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
|
||||
}
|
||||
|
||||
// FlagCategories interface allows for category manipulation
|
||||
type FlagCategories interface {
|
||||
// AddFlags adds a flag to a category, creating a new category if necessary.
|
||||
AddFlag(category string, fl Flag)
|
||||
// VisibleCategories returns a slice of visible flag categories sorted by name
|
||||
VisibleCategories() []VisibleFlagCategory
|
||||
}
|
||||
|
||||
type defaultFlagCategories struct {
|
||||
m map[string]*defaultVisibleFlagCategory
|
||||
}
|
||||
|
||||
func newFlagCategories() FlagCategories {
|
||||
return &defaultFlagCategories{
|
||||
m: map[string]*defaultVisibleFlagCategory{},
|
||||
}
|
||||
}
|
||||
|
||||
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
|
||||
fc := newFlagCategories()
|
||||
|
||||
var categorized bool
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cat := cf.GetCategory(); cat != "" && cf.IsVisible() {
|
||||
fc.AddFlag(cat, cf)
|
||||
categorized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if categorized {
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cf.GetCategory() == "" && cf.IsVisible() {
|
||||
fc.AddFlag("", fl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fc
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
|
||||
if _, ok := f.m[category]; !ok {
|
||||
f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
|
||||
}
|
||||
|
||||
f.m[category].m[fl.String()] = fl
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
|
||||
catNames := []string{}
|
||||
for name := range f.m {
|
||||
catNames = append(catNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(catNames)
|
||||
|
||||
ret := make([]VisibleFlagCategory, len(catNames))
|
||||
for i, name := range catNames {
|
||||
ret[i] = f.m[name]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategory is a category containing flags.
|
||||
type VisibleFlagCategory interface {
|
||||
// Name returns the category name string
|
||||
Name() string
|
||||
// Flags returns a slice of VisibleFlag sorted by name
|
||||
Flags() []VisibleFlag
|
||||
}
|
||||
|
||||
type defaultVisibleFlagCategory struct {
|
||||
name string
|
||||
m map[string]Flag
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Name() string {
|
||||
return fc.name
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
|
||||
vfNames := []string{}
|
||||
for flName, fl := range fc.m {
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
if vf.IsVisible() {
|
||||
vfNames = append(vfNames, flName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(vfNames)
|
||||
|
||||
ret := make([]VisibleFlag, len(vfNames))
|
||||
for i, flName := range vfNames {
|
||||
ret[i] = fc.m[flName].(VisibleFlag)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
25
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
Normal file
25
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Package cli provides a minimal framework for creating and organizing command line
|
||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
||||
// cli application can be written as follows:
|
||||
//
|
||||
// func main() {
|
||||
// (&cli.App{}).Run(os.Args)
|
||||
// }
|
||||
//
|
||||
// Of course this application does not do much, so let's make this an actual application:
|
||||
//
|
||||
// func main() {
|
||||
// app := &cli.App{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// app.Run(os.Args)
|
||||
// }
|
||||
package cli
|
||||
|
||||
//go:generate make -C cmd/urfave-cli-genflags run
|
||||
421
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
Normal file
421
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
Normal file
@ -0,0 +1,421 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Command is a subcommand for a cli.App.
|
||||
type Command struct {
|
||||
// The name of the command
|
||||
Name string
|
||||
// A list of aliases for the command
|
||||
Aliases []string
|
||||
// A short description of the usage of this command
|
||||
Usage string
|
||||
// Custom text to show on USAGE section of help
|
||||
UsageText string
|
||||
// A longer explanation of how the command works
|
||||
Description string
|
||||
// Whether this command supports arguments
|
||||
Args bool
|
||||
// A short description of the arguments of this command
|
||||
ArgsUsage string
|
||||
// The category the command is part of
|
||||
Category string
|
||||
// The function to call when checking for bash command completions
|
||||
BashComplete BashCompleteFunc
|
||||
// An action to execute before any sub-subcommands are run, but after the context is ready
|
||||
// If a non-nil error is returned, no sub-subcommands are run
|
||||
Before BeforeFunc
|
||||
// An action to execute after any subcommands are run, but after the subcommand has finished
|
||||
// It is run even if Action() panics
|
||||
After AfterFunc
|
||||
// The function to call when this command is invoked
|
||||
Action ActionFunc
|
||||
// Execute this function if a usage error occurs.
|
||||
OnUsageError OnUsageErrorFunc
|
||||
// List of child commands
|
||||
Subcommands []*Command
|
||||
// List of flags to parse
|
||||
Flags []Flag
|
||||
flagCategories FlagCategories
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool
|
||||
// Boolean to hide built-in help command and help flag
|
||||
HideHelp bool
|
||||
// Boolean to hide built-in help command but keep help flag
|
||||
// Ignored if HideHelp is true.
|
||||
HideHelpCommand bool
|
||||
// Boolean to hide this command from help or completion
|
||||
Hidden bool
|
||||
// Boolean to enable short-option handling so user can combine several
|
||||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
|
||||
// Full name of command for help, defaults to full command name, including parent commands.
|
||||
HelpName string
|
||||
commandNamePath []string
|
||||
|
||||
// CustomHelpTemplate the text template for the command help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
CustomHelpTemplate string
|
||||
|
||||
// categories contains the categorized commands and is populated on app startup
|
||||
categories CommandCategories
|
||||
|
||||
// if this is a root "special" command
|
||||
isRoot bool
|
||||
|
||||
separator separatorSpec
|
||||
}
|
||||
|
||||
type Commands []*Command
|
||||
|
||||
type CommandsByName []*Command
|
||||
|
||||
func (c CommandsByName) Len() int {
|
||||
return len(c)
|
||||
}
|
||||
|
||||
func (c CommandsByName) Less(i, j int) bool {
|
||||
return lexicographicLess(c[i].Name, c[j].Name)
|
||||
}
|
||||
|
||||
func (c CommandsByName) Swap(i, j int) {
|
||||
c[i], c[j] = c[j], c[i]
|
||||
}
|
||||
|
||||
// FullName returns the full name of the command.
|
||||
// For subcommands this ensures that parent commands are part of the command path
|
||||
func (c *Command) FullName() string {
|
||||
if c.commandNamePath == nil {
|
||||
return c.Name
|
||||
}
|
||||
return strings.Join(c.commandNamePath, " ")
|
||||
}
|
||||
|
||||
func (cmd *Command) Command(name string) *Command {
|
||||
for _, c := range cmd.Subcommands {
|
||||
if c.HasName(name) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Command) setup(ctx *Context) {
|
||||
if c.Command(helpCommand.Name) == nil && !c.HideHelp {
|
||||
if !c.HideHelpCommand {
|
||||
c.Subcommands = append(c.Subcommands, helpCommand)
|
||||
}
|
||||
}
|
||||
|
||||
if !c.HideHelp && HelpFlag != nil {
|
||||
// append help to flags
|
||||
c.appendFlag(HelpFlag)
|
||||
}
|
||||
|
||||
if ctx.App.UseShortOptionHandling {
|
||||
c.UseShortOptionHandling = true
|
||||
}
|
||||
|
||||
c.categories = newCommandCategories()
|
||||
for _, command := range c.Subcommands {
|
||||
c.categories.AddCommand(command.Category, command)
|
||||
}
|
||||
sort.Sort(c.categories.(*commandCategories))
|
||||
|
||||
for _, scmd := range c.Subcommands {
|
||||
if scmd.HelpName == "" {
|
||||
scmd.HelpName = fmt.Sprintf("%s %s", c.HelpName, scmd.Name)
|
||||
}
|
||||
scmd.separator = c.separator
|
||||
}
|
||||
|
||||
if c.BashComplete == nil {
|
||||
c.BashComplete = DefaultCompleteWithFlags(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
|
||||
|
||||
if !c.isRoot {
|
||||
c.setup(cCtx)
|
||||
if err := checkDuplicatedCmds(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a := args(arguments)
|
||||
set, err := c.parseFlags(&a, cCtx.shellComplete)
|
||||
cCtx.flagSet = set
|
||||
|
||||
if checkCompletions(cCtx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if c.OnUsageError != nil {
|
||||
err = c.OnUsageError(cCtx, err, !c.isRoot)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(cCtx.App.Writer, "%s %s\n\n", "Incorrect Usage:", err.Error())
|
||||
if cCtx.App.Suggest {
|
||||
if suggestion, err := c.suggestFlagFromError(err, ""); err == nil {
|
||||
fmt.Fprintf(cCtx.App.Writer, "%s", suggestion)
|
||||
}
|
||||
}
|
||||
if !c.HideHelp {
|
||||
if c.isRoot {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
} else {
|
||||
_ = ShowCommandHelp(cCtx.parentContext, c.Name)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if checkHelp(cCtx) {
|
||||
return helpCommand.Action(cCtx)
|
||||
}
|
||||
|
||||
if c.isRoot && !cCtx.App.HideVersion && checkVersion(cCtx) {
|
||||
ShowVersion(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.After != nil && !cCtx.shellComplete {
|
||||
defer func() {
|
||||
afterErr := c.After(cCtx)
|
||||
if afterErr != nil {
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
if err != nil {
|
||||
err = newMultiError(err, afterErr)
|
||||
} else {
|
||||
err = afterErr
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
cerr := cCtx.checkRequiredFlags(c.Flags)
|
||||
if cerr != nil {
|
||||
_ = helpCommand.Action(cCtx)
|
||||
return cerr
|
||||
}
|
||||
|
||||
if c.Before != nil && !cCtx.shellComplete {
|
||||
beforeErr := c.Before(cCtx)
|
||||
if beforeErr != nil {
|
||||
cCtx.App.handleExitCoder(cCtx, beforeErr)
|
||||
err = beforeErr
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = runFlagActions(cCtx, c.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var cmd *Command
|
||||
args := cCtx.Args()
|
||||
if args.Present() {
|
||||
name := args.First()
|
||||
cmd = c.Command(name)
|
||||
if cmd == nil {
|
||||
hasDefault := cCtx.App.DefaultCommand != ""
|
||||
isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames())
|
||||
|
||||
var (
|
||||
isDefaultSubcommand = false
|
||||
defaultHasSubcommands = false
|
||||
)
|
||||
|
||||
if hasDefault {
|
||||
dc := cCtx.App.Command(cCtx.App.DefaultCommand)
|
||||
defaultHasSubcommands = len(dc.Subcommands) > 0
|
||||
for _, dcSub := range dc.Subcommands {
|
||||
if checkStringSliceIncludes(name, dcSub.Names()) {
|
||||
isDefaultSubcommand = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isFlagName || (hasDefault && (defaultHasSubcommands && isDefaultSubcommand)) {
|
||||
argsWithDefault := cCtx.App.argsWithDefaultCommand(args)
|
||||
if !reflect.DeepEqual(args, argsWithDefault) {
|
||||
cmd = cCtx.App.rootCommand.Command(argsWithDefault.First())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if c.isRoot && cCtx.App.DefaultCommand != "" {
|
||||
if dc := cCtx.App.Command(cCtx.App.DefaultCommand); dc != c {
|
||||
cmd = dc
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
newcCtx := NewContext(cCtx.App, nil, cCtx)
|
||||
newcCtx.Command = cmd
|
||||
return cmd.Run(newcCtx, cCtx.Args().Slice()...)
|
||||
}
|
||||
|
||||
if c.Action == nil {
|
||||
c.Action = helpCommand.Action
|
||||
}
|
||||
|
||||
err = c.Action(cCtx)
|
||||
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Command) newFlagSet() (*flag.FlagSet, error) {
|
||||
return flagSet(c.Name, c.Flags, c.separator)
|
||||
}
|
||||
|
||||
func (c *Command) useShortOptionHandling() bool {
|
||||
return c.UseShortOptionHandling
|
||||
}
|
||||
|
||||
func (c *Command) suggestFlagFromError(err error, command string) (string, error) {
|
||||
flag, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := c.Flags
|
||||
hideHelp := c.HideHelp
|
||||
if command != "" {
|
||||
cmd := c.Command(command)
|
||||
if cmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = cmd.Flags
|
||||
hideHelp = hideHelp || cmd.HideHelp
|
||||
}
|
||||
|
||||
suggestion := SuggestFlag(flags, flag, hideHelp)
|
||||
if len(suggestion) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion) + "\n\n", nil
|
||||
}
|
||||
|
||||
func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) {
|
||||
set, err := c.newFlagSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.SkipFlagParsing {
|
||||
return set, set.Parse(append([]string{"--"}, args.Tail()...))
|
||||
}
|
||||
|
||||
err = parseIter(set, c, args.Tail(), shellComplete)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = normalizeFlags(c.Flags, set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// Names returns the names including short names and aliases.
|
||||
func (c *Command) Names() []string {
|
||||
return append([]string{c.Name}, c.Aliases...)
|
||||
}
|
||||
|
||||
// HasName returns true if Command.Name matches given name
|
||||
func (c *Command) HasName(name string) bool {
|
||||
for _, n := range c.Names() {
|
||||
if n == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// VisibleCategories returns a slice of categories and commands that are
|
||||
// Hidden=false
|
||||
func (c *Command) VisibleCategories() []CommandCategory {
|
||||
ret := []CommandCategory{}
|
||||
for _, category := range c.categories.Categories() {
|
||||
if visible := func() CommandCategory {
|
||||
if len(category.VisibleCommands()) > 0 {
|
||||
return category
|
||||
}
|
||||
return nil
|
||||
}(); visible != nil {
|
||||
ret = append(ret, visible)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (c *Command) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range c.Subcommands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, command)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if c.flagCategories == nil {
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
}
|
||||
return c.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (c *Command) VisibleFlags() []Flag {
|
||||
return visibleFlags(c.Flags)
|
||||
}
|
||||
|
||||
func (c *Command) appendFlag(fl Flag) {
|
||||
if !hasFlag(c.Flags, fl) {
|
||||
c.Flags = append(c.Flags, fl)
|
||||
}
|
||||
}
|
||||
|
||||
func hasCommand(commands []*Command, command *Command) bool {
|
||||
for _, existing := range commands {
|
||||
if command == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkDuplicatedCmds(parent *Command) error {
|
||||
seen := make(map[string]struct{})
|
||||
for _, c := range parent.Subcommands {
|
||||
for _, name := range c.Names() {
|
||||
if _, exists := seen[name]; exists {
|
||||
return fmt.Errorf("parent command [%s] has duplicated subcommand name or alias: %s", parent.Name, name)
|
||||
}
|
||||
seen[name] = struct{}{}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
272
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
Normal file
272
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Context is a type that is passed through to
|
||||
// each Handler action in a cli application. Context
|
||||
// can be used to retrieve context-specific args and
|
||||
// parsed command-line options.
|
||||
type Context struct {
|
||||
context.Context
|
||||
App *App
|
||||
Command *Command
|
||||
shellComplete bool
|
||||
flagSet *flag.FlagSet
|
||||
parentContext *Context
|
||||
}
|
||||
|
||||
// NewContext creates a new context. For use in when invoking an App or Command action.
|
||||
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
||||
c := &Context{App: app, flagSet: set, parentContext: parentCtx}
|
||||
if parentCtx != nil {
|
||||
c.Context = parentCtx.Context
|
||||
c.shellComplete = parentCtx.shellComplete
|
||||
if parentCtx.flagSet == nil {
|
||||
parentCtx.flagSet = &flag.FlagSet{}
|
||||
}
|
||||
}
|
||||
|
||||
c.Command = &Command{}
|
||||
|
||||
if c.Context == nil {
|
||||
c.Context = context.Background()
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// NumFlags returns the number of flags set
|
||||
func (cCtx *Context) NumFlags() int {
|
||||
return cCtx.flagSet.NFlag()
|
||||
}
|
||||
|
||||
// Set sets a context flag to a value.
|
||||
func (cCtx *Context) Set(name, value string) error {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return fs.Set(name, value)
|
||||
}
|
||||
|
||||
return fmt.Errorf("no such flag -%s", name)
|
||||
}
|
||||
|
||||
// IsSet determines if the flag was actually set
|
||||
func (cCtx *Context) IsSet(name string) bool {
|
||||
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
isSet := false
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
if f.Name == name {
|
||||
isSet = true
|
||||
}
|
||||
})
|
||||
if isSet {
|
||||
return true
|
||||
}
|
||||
|
||||
f := cCtx.lookupFlag(name)
|
||||
if f == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if f.IsSet() {
|
||||
return true
|
||||
}
|
||||
|
||||
// now redo flagset search on aliases
|
||||
aliases := f.Names()
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
for _, alias := range aliases {
|
||||
if f.Name == alias {
|
||||
isSet = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if isSet {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// LocalFlagNames returns a slice of flag names used in this context.
|
||||
func (cCtx *Context) LocalFlagNames() []string {
|
||||
var names []string
|
||||
cCtx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
// Check the flags which have been set via env or file
|
||||
if cCtx.Command != nil && cCtx.Command.Flags != nil {
|
||||
for _, f := range cCtx.Command.Flags {
|
||||
if f.IsSet() {
|
||||
names = append(names, f.Names()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort out the duplicates since flag could be set via multiple
|
||||
// paths
|
||||
m := map[string]struct{}{}
|
||||
var unames []string
|
||||
for _, name := range names {
|
||||
if _, ok := m[name]; !ok {
|
||||
m[name] = struct{}{}
|
||||
unames = append(unames, name)
|
||||
}
|
||||
}
|
||||
|
||||
return unames
|
||||
}
|
||||
|
||||
// FlagNames returns a slice of flag names used by the this context and all of
|
||||
// its parent contexts.
|
||||
func (cCtx *Context) FlagNames() []string {
|
||||
var names []string
|
||||
for _, pCtx := range cCtx.Lineage() {
|
||||
names = append(names, pCtx.LocalFlagNames()...)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// Lineage returns *this* context and all of its ancestor contexts in order from
|
||||
// child to parent
|
||||
func (cCtx *Context) Lineage() []*Context {
|
||||
var lineage []*Context
|
||||
|
||||
for cur := cCtx; cur != nil; cur = cur.parentContext {
|
||||
lineage = append(lineage, cur)
|
||||
}
|
||||
|
||||
return lineage
|
||||
}
|
||||
|
||||
// Count returns the num of occurrences of this flag
|
||||
func (cCtx *Context) Count(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
if cf, ok := fs.Lookup(name).Value.(Countable); ok {
|
||||
return cf.Count()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Value returns the value of the flag corresponding to `name`
|
||||
func (cCtx *Context) Value(name string) interface{} {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return fs.Lookup(name).Value.(flag.Getter).Get()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Args returns the command line arguments associated with the context.
|
||||
func (cCtx *Context) Args() Args {
|
||||
ret := args(cCtx.flagSet.Args())
|
||||
return &ret
|
||||
}
|
||||
|
||||
// NArg returns the number of the command line arguments.
|
||||
func (cCtx *Context) NArg() int {
|
||||
return cCtx.Args().Len()
|
||||
}
|
||||
|
||||
func (cCtx *Context) lookupFlag(name string) Flag {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.Command == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range c.Command.Flags {
|
||||
for _, n := range f.Names() {
|
||||
if n == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cCtx.App != nil {
|
||||
for _, f := range cCtx.App.Flags {
|
||||
for _, n := range f.Names() {
|
||||
if n == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.flagSet == nil {
|
||||
continue
|
||||
}
|
||||
if f := c.flagSet.Lookup(name); f != nil {
|
||||
return c.flagSet
|
||||
}
|
||||
}
|
||||
cCtx.onInvalidFlag(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
|
||||
var missingFlags []string
|
||||
for _, f := range flags {
|
||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
||||
var flagPresent bool
|
||||
var flagName string
|
||||
|
||||
flagNames := f.Names()
|
||||
flagName = flagNames[0]
|
||||
|
||||
for _, key := range flagNames {
|
||||
if cCtx.IsSet(strings.TrimSpace(key)) {
|
||||
flagPresent = true
|
||||
}
|
||||
}
|
||||
|
||||
if !flagPresent && flagName != "" {
|
||||
missingFlags = append(missingFlags, flagName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingFlags) != 0 {
|
||||
return &errRequiredFlags{missingFlags: missingFlags}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) onInvalidFlag(name string) {
|
||||
for cCtx != nil {
|
||||
if cCtx.App != nil && cCtx.App.InvalidFlagAccessHandler != nil {
|
||||
cCtx.App.InvalidFlagAccessHandler(cCtx, name)
|
||||
break
|
||||
}
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
}
|
||||
|
||||
func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
|
||||
return func(f *flag.Flag) {
|
||||
nameParts := strings.Split(f.Name, ",")
|
||||
name := strings.TrimSpace(nameParts[0])
|
||||
|
||||
for _, part := range nameParts {
|
||||
part = strings.TrimSpace(part)
|
||||
if len(part) > len(name) {
|
||||
name = part
|
||||
}
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
*names = append(*names, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
203
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
Normal file
203
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
//go:build !urfave_cli_no_docs
|
||||
// +build !urfave_cli_no_docs
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/cpuguy83/go-md2man/v2/md2man"
|
||||
)
|
||||
|
||||
// ToMarkdown creates a markdown string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMarkdown() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w, 0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string with section number for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToManWithSection(sectionNumber int) (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w, sectionNumber); err != nil {
|
||||
return "", err
|
||||
}
|
||||
man := md2man.Render(w.Bytes())
|
||||
return string(man), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMan() (string, error) {
|
||||
man, err := a.ToManWithSection(8)
|
||||
return man, err
|
||||
}
|
||||
|
||||
type cliTemplate struct {
|
||||
App *App
|
||||
SectionNum int
|
||||
Commands []string
|
||||
GlobalArgs []string
|
||||
SynopsisArgs []string
|
||||
}
|
||||
|
||||
func (a *App) writeDocTemplate(w io.Writer, sectionNum int) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.ExecuteTemplate(w, name, &cliTemplate{
|
||||
App: a,
|
||||
SectionNum: sectionNum,
|
||||
Commands: prepareCommands(a.Commands, 0),
|
||||
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
||||
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
||||
})
|
||||
}
|
||||
|
||||
func prepareCommands(commands []*Command, level int) []string {
|
||||
var coms []string
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
usageText := prepareUsageText(command)
|
||||
|
||||
usage := prepareUsage(command, usageText)
|
||||
|
||||
prepared := fmt.Sprintf("%s %s\n\n%s%s",
|
||||
strings.Repeat("#", level+2),
|
||||
strings.Join(command.Names(), ", "),
|
||||
usage,
|
||||
usageText,
|
||||
)
|
||||
|
||||
flags := prepareArgsWithValues(command.VisibleFlags())
|
||||
if len(flags) > 0 {
|
||||
prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n"))
|
||||
}
|
||||
|
||||
coms = append(coms, prepared)
|
||||
|
||||
// recursively iterate subcommands
|
||||
if len(command.Subcommands) > 0 {
|
||||
coms = append(
|
||||
coms,
|
||||
prepareCommands(command.Subcommands, level+1)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return coms
|
||||
}
|
||||
|
||||
func prepareArgsWithValues(flags []Flag) []string {
|
||||
return prepareFlags(flags, ", ", "**", "**", `""`, true)
|
||||
}
|
||||
|
||||
func prepareArgsSynopsis(flags []Flag) []string {
|
||||
return prepareFlags(flags, "|", "[", "]", "[value]", false)
|
||||
}
|
||||
|
||||
func prepareFlags(
|
||||
flags []Flag,
|
||||
sep, opener, closer, value string,
|
||||
addDetails bool,
|
||||
) []string {
|
||||
args := []string{}
|
||||
for _, f := range flags {
|
||||
flag, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
modifiedArg := opener
|
||||
|
||||
for _, s := range flag.Names() {
|
||||
trimmed := strings.TrimSpace(s)
|
||||
if len(modifiedArg) > len(opener) {
|
||||
modifiedArg += sep
|
||||
}
|
||||
if len(trimmed) > 1 {
|
||||
modifiedArg += fmt.Sprintf("--%s", trimmed)
|
||||
} else {
|
||||
modifiedArg += fmt.Sprintf("-%s", trimmed)
|
||||
}
|
||||
}
|
||||
modifiedArg += closer
|
||||
if flag.TakesValue() {
|
||||
modifiedArg += fmt.Sprintf("=%s", value)
|
||||
}
|
||||
|
||||
if addDetails {
|
||||
modifiedArg += flagDetails(flag)
|
||||
}
|
||||
|
||||
args = append(args, modifiedArg+"\n")
|
||||
|
||||
}
|
||||
sort.Strings(args)
|
||||
return args
|
||||
}
|
||||
|
||||
// flagDetails returns a string containing the flags metadata
|
||||
func flagDetails(flag DocGenerationFlag) string {
|
||||
description := flag.GetUsage()
|
||||
if flag.TakesValue() {
|
||||
defaultText := flag.GetDefaultText()
|
||||
if defaultText == "" {
|
||||
defaultText = flag.GetValue()
|
||||
}
|
||||
if defaultText != "" {
|
||||
description += " (default: " + defaultText + ")"
|
||||
}
|
||||
}
|
||||
return ": " + description
|
||||
}
|
||||
|
||||
func prepareUsageText(command *Command) string {
|
||||
if command.UsageText == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Remove leading and trailing newlines
|
||||
preparedUsageText := strings.Trim(command.UsageText, "\n")
|
||||
|
||||
var usageText string
|
||||
if strings.Contains(preparedUsageText, "\n") {
|
||||
// Format multi-line string as a code block using the 4 space schema to allow for embedded markdown such
|
||||
// that it will not break the continuous code block.
|
||||
for _, ln := range strings.Split(preparedUsageText, "\n") {
|
||||
usageText += fmt.Sprintf(" %s\n", ln)
|
||||
}
|
||||
} else {
|
||||
// Style a single line as a note
|
||||
usageText = fmt.Sprintf(">%s\n", preparedUsageText)
|
||||
}
|
||||
|
||||
return usageText
|
||||
}
|
||||
|
||||
func prepareUsage(command *Command, usageText string) string {
|
||||
if command.Usage == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
usage := command.Usage + "\n"
|
||||
// Add a newline to the Usage IFF there is a UsageText
|
||||
if usageText != "" {
|
||||
usage += "\n"
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
178
vendor/github.com/urfave/cli/v2/errors.go
generated
vendored
Normal file
178
vendor/github.com/urfave/cli/v2/errors.go
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// OsExiter is the function used when the app exits. If not set defaults to os.Exit.
|
||||
var OsExiter = os.Exit
|
||||
|
||||
// ErrWriter is used to write errors to the user. This can be anything
|
||||
// implementing the io.Writer interface and defaults to os.Stderr.
|
||||
var ErrWriter io.Writer = os.Stderr
|
||||
|
||||
// MultiError is an error that wraps multiple errors.
|
||||
type MultiError interface {
|
||||
error
|
||||
Errors() []error
|
||||
}
|
||||
|
||||
// newMultiError creates a new MultiError. Pass in one or more errors.
|
||||
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))
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// ErrorFormatter is the interface that will suitably format the error output
|
||||
type ErrorFormatter interface {
|
||||
Format(s fmt.State, verb rune)
|
||||
}
|
||||
|
||||
// ExitCoder is the interface checked by `App` and `Command` for a custom exit
|
||||
// code
|
||||
type ExitCoder interface {
|
||||
error
|
||||
ExitCode() int
|
||||
}
|
||||
|
||||
type exitError struct {
|
||||
exitCode int
|
||||
err error
|
||||
}
|
||||
|
||||
// NewExitError calls Exit to create a new ExitCoder.
|
||||
//
|
||||
// Deprecated: This function is a duplicate of Exit and will eventually be removed.
|
||||
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
||||
return Exit(message, exitCode)
|
||||
}
|
||||
|
||||
// Exit wraps a message and exit code into an error, which by default is
|
||||
// handled with a call to os.Exit during default error handling.
|
||||
//
|
||||
// This is the simplest way to trigger a non-zero exit code for an App without
|
||||
// having to call os.Exit manually. During testing, this behavior can be avoided
|
||||
// by overriding the ExitErrHandler function on an App or the package-global
|
||||
// OsExiter function.
|
||||
func Exit(message interface{}, exitCode int) ExitCoder {
|
||||
var err error
|
||||
|
||||
switch e := message.(type) {
|
||||
case ErrorFormatter:
|
||||
err = fmt.Errorf("%+v", message)
|
||||
case error:
|
||||
err = e
|
||||
default:
|
||||
err = fmt.Errorf("%+v", message)
|
||||
}
|
||||
|
||||
return &exitError{
|
||||
err: err,
|
||||
exitCode: exitCode,
|
||||
}
|
||||
}
|
||||
|
||||
func (ee *exitError) Error() string {
|
||||
return ee.err.Error()
|
||||
}
|
||||
|
||||
func (ee *exitError) ExitCode() int {
|
||||
return ee.exitCode
|
||||
}
|
||||
|
||||
func (ee *exitError) Unwrap() error {
|
||||
return ee.err
|
||||
}
|
||||
|
||||
// HandleExitCoder handles errors implementing ExitCoder by printing their
|
||||
// message and calling OsExiter with the given exit code.
|
||||
//
|
||||
// If the given error instead implements MultiError, each error will be checked
|
||||
// for the ExitCoder interface, and OsExiter will be called with the last exit
|
||||
// code found, or exit code 1 if no ExitCoder is found.
|
||||
//
|
||||
// This function is the default error-handling behavior for an App.
|
||||
func HandleExitCoder(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if exitErr, ok := err.(ExitCoder); ok {
|
||||
if err.Error() != "" {
|
||||
if _, ok := exitErr.(ErrorFormatter); ok {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "%+v\n", err)
|
||||
} else {
|
||||
_, _ = fmt.Fprintln(ErrWriter, err)
|
||||
}
|
||||
}
|
||||
OsExiter(exitErr.ExitCode())
|
||||
return
|
||||
}
|
||||
|
||||
if multiErr, ok := err.(MultiError); ok {
|
||||
code := handleMultiError(multiErr)
|
||||
OsExiter(code)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func handleMultiError(multiErr MultiError) int {
|
||||
code := 1
|
||||
for _, merr := range multiErr.Errors() {
|
||||
if multiErr2, ok := merr.(MultiError); ok {
|
||||
code = handleMultiError(multiErr2)
|
||||
} else if merr != nil {
|
||||
fmt.Fprintln(ErrWriter, merr)
|
||||
if exitErr, ok := merr.(ExitCoder); ok {
|
||||
code = exitErr.ExitCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
196
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
Normal file
196
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// ToFishCompletion creates a fish completion string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToFishCompletion() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeFishCompletionTemplate(&w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
type fishCompletionTemplate struct {
|
||||
App *App
|
||||
Completions []string
|
||||
AllCommands []string
|
||||
}
|
||||
|
||||
func (a *App) writeFishCompletionTemplate(w io.Writer) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(FishCompletionTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allCommands := []string{}
|
||||
|
||||
// Add global flags
|
||||
completions := a.prepareFishFlags(a.VisibleFlags(), allCommands)
|
||||
|
||||
// Add help flag
|
||||
if !a.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{HelpFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add version flag
|
||||
if !a.HideVersion {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{VersionFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add commands and their flags
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishCommands(a.VisibleCommands(), &allCommands, []string{})...,
|
||||
)
|
||||
|
||||
return t.ExecuteTemplate(w, name, &fishCompletionTemplate{
|
||||
App: a,
|
||||
Completions: completions,
|
||||
AllCommands: allCommands,
|
||||
})
|
||||
}
|
||||
|
||||
func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
var completion strings.Builder
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -r -c %s -n '%s' -a '%s'",
|
||||
a.Name,
|
||||
a.fishSubcommandHelper(previousCommands),
|
||||
strings.Join(command.Names(), " "),
|
||||
))
|
||||
|
||||
if command.Usage != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(command.Usage)))
|
||||
}
|
||||
|
||||
if !command.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags([]Flag{HelpFlag}, command.Names())...,
|
||||
)
|
||||
}
|
||||
|
||||
*allCommands = append(*allCommands, command.Names()...)
|
||||
completions = append(completions, completion.String())
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags(command.VisibleFlags(), command.Names())...,
|
||||
)
|
||||
|
||||
// recursively iterate subcommands
|
||||
if len(command.Subcommands) > 0 {
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishCommands(
|
||||
command.Subcommands, allCommands, command.Names(),
|
||||
)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, f := range flags {
|
||||
flag, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
completion := &strings.Builder{}
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -c %s -n '%s'",
|
||||
a.Name,
|
||||
a.fishSubcommandHelper(previousCommands),
|
||||
))
|
||||
|
||||
fishAddFileFlag(f, completion)
|
||||
|
||||
for idx, opt := range flag.Names() {
|
||||
if idx == 0 {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -l %s", strings.TrimSpace(opt),
|
||||
))
|
||||
} else {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -s %s", strings.TrimSpace(opt),
|
||||
))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if flag.TakesValue() {
|
||||
completion.WriteString(" -r")
|
||||
}
|
||||
|
||||
if flag.GetUsage() != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(flag.GetUsage())))
|
||||
}
|
||||
|
||||
completions = append(completions, completion.String())
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||
switch f := flag.(type) {
|
||||
case *GenericFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringSliceFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *PathFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
}
|
||||
completion.WriteString(" -f")
|
||||
}
|
||||
|
||||
func (a *App) fishSubcommandHelper(allCommands []string) string {
|
||||
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", a.Name)
|
||||
if len(allCommands) > 0 {
|
||||
fishHelper = fmt.Sprintf(
|
||||
"__fish_seen_subcommand_from %s",
|
||||
strings.Join(allCommands, " "),
|
||||
)
|
||||
}
|
||||
return fishHelper
|
||||
|
||||
}
|
||||
|
||||
func escapeSingleQuotes(input string) string {
|
||||
return strings.Replace(input, `'`, `\'`, -1)
|
||||
}
|
||||
131
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
Normal file
131
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
# NOTE: this file is used by the tool defined in
|
||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||
# `Spec` type that maps to this file structure.
|
||||
flag_types:
|
||||
bool:
|
||||
struct_fields:
|
||||
- name: Count
|
||||
type: int
|
||||
pointer: true
|
||||
- name: DisableDefaultText
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, bool) error"
|
||||
float64:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, float64) error"
|
||||
Float64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []float64) error"
|
||||
int:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int) error"
|
||||
IntSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []int) error"
|
||||
int64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int64) error"
|
||||
Int64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []int64) error"
|
||||
uint:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint) error"
|
||||
UintSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []uint) error"
|
||||
uint64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint64) error"
|
||||
Uint64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: Action
|
||||
type: "func(*Context, []uint64) error"
|
||||
string:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, string) error"
|
||||
StringSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: separator
|
||||
type: separatorSpec
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, []string) error"
|
||||
- name: KeepSpace
|
||||
type: bool
|
||||
time.Duration:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, time.Duration) error"
|
||||
Timestamp:
|
||||
value_pointer: true
|
||||
struct_fields:
|
||||
- name: Layout
|
||||
type: string
|
||||
- name: Timezone
|
||||
type: "*time.Location"
|
||||
- name: Action
|
||||
type: "func(*Context, *time.Time) error"
|
||||
Generic:
|
||||
no_destination_pointer: true
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, interface{}) error"
|
||||
Path:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, Path) error"
|
||||
419
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
Normal file
419
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const defaultPlaceholder = "value"
|
||||
|
||||
const (
|
||||
defaultSliceFlagSeparator = ","
|
||||
disableSliceFlagSeparator = false
|
||||
)
|
||||
|
||||
var (
|
||||
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||
|
||||
commaWhitespace = regexp.MustCompile("[, ]+.*")
|
||||
)
|
||||
|
||||
// BashCompletionFlag enables bash-completion for all commands and subcommands
|
||||
var BashCompletionFlag Flag = &BoolFlag{
|
||||
Name: "generate-bash-completion",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
// VersionFlag prints the version for the application
|
||||
var VersionFlag Flag = &BoolFlag{
|
||||
Name: "version",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print the version",
|
||||
DisableDefaultText: true,
|
||||
}
|
||||
|
||||
// HelpFlag prints the help for all commands and subcommands.
|
||||
// Set to nil to disable the flag. The subcommand
|
||||
// will still be added unless HideHelp or HideHelpCommand is set to true.
|
||||
var HelpFlag Flag = &BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
Usage: "show help",
|
||||
DisableDefaultText: true,
|
||||
}
|
||||
|
||||
// FlagStringer converts a flag definition to a string. This is used by help
|
||||
// to display a flag.
|
||||
var FlagStringer FlagStringFunc = stringifyFlag
|
||||
|
||||
// Serializer is used to circumvent the limitations of flag.FlagSet.Set
|
||||
type Serializer interface {
|
||||
Serialize() string
|
||||
}
|
||||
|
||||
// FlagNamePrefixer converts a full flag name and its placeholder into the help
|
||||
// message flag prefix. This is used by the default FlagStringer.
|
||||
var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames
|
||||
|
||||
// FlagEnvHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagEnvHinter FlagEnvHintFunc = withEnvHint
|
||||
|
||||
// FlagFileHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagFileHinter FlagFileHintFunc = withFileHint
|
||||
|
||||
// FlagsByName is a slice of Flag.
|
||||
type FlagsByName []Flag
|
||||
|
||||
func (f FlagsByName) Len() int {
|
||||
return len(f)
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
if len(f[j].Names()) == 0 {
|
||||
return false
|
||||
} else if len(f[i].Names()) == 0 {
|
||||
return true
|
||||
}
|
||||
return lexicographicLess(f[i].Names()[0], f[j].Names()[0])
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
f[i], f[j] = f[j], f[i]
|
||||
}
|
||||
|
||||
// ActionableFlag is an interface that wraps Flag interface and RunAction operation.
|
||||
type ActionableFlag interface {
|
||||
Flag
|
||||
RunAction(*Context) error
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
type Flag interface {
|
||||
fmt.Stringer
|
||||
// Apply Flag settings to the given flag set
|
||||
Apply(*flag.FlagSet) error
|
||||
Names() []string
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// RequiredFlag is an interface that allows us to mark flags as required
|
||||
// it allows flags required flags to be backwards compatible with the Flag interface
|
||||
type RequiredFlag interface {
|
||||
Flag
|
||||
|
||||
IsRequired() bool
|
||||
}
|
||||
|
||||
// DocGenerationFlag is an interface that allows documentation generation for the flag
|
||||
type DocGenerationFlag interface {
|
||||
Flag
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
TakesValue() bool
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
GetUsage() string
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
GetValue() string
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
GetDefaultText() string
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
GetEnvVars() []string
|
||||
}
|
||||
|
||||
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||
type DocGenerationSliceFlag interface {
|
||||
DocGenerationFlag
|
||||
|
||||
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||
IsSliceFlag() bool
|
||||
}
|
||||
|
||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||
type VisibleFlag interface {
|
||||
Flag
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
// CategorizableFlag is an interface that allows us to potentially
|
||||
// use a flag in a categorized representation.
|
||||
type CategorizableFlag interface {
|
||||
VisibleFlag
|
||||
|
||||
GetCategory() string
|
||||
}
|
||||
|
||||
// Countable is an interface to enable detection of flag values which support
|
||||
// repetitive flags
|
||||
type Countable interface {
|
||||
Count() int
|
||||
}
|
||||
|
||||
func flagSet(name string, flags []Flag, spec separatorSpec) (*flag.FlagSet, error) {
|
||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||
|
||||
for _, f := range flags {
|
||||
if c, ok := f.(customizedSeparator); ok {
|
||||
c.WithSeparatorSpec(spec)
|
||||
}
|
||||
if err := f.Apply(set); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
set.SetOutput(io.Discard)
|
||||
return set, nil
|
||||
}
|
||||
|
||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||
switch ff.Value.(type) {
|
||||
case Serializer:
|
||||
_ = set.Set(name, ff.Value.(Serializer).Serialize())
|
||||
default:
|
||||
_ = set.Set(name, ff.Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
||||
visited := make(map[string]bool)
|
||||
set.Visit(func(f *flag.Flag) {
|
||||
visited[f.Name] = true
|
||||
})
|
||||
for _, f := range flags {
|
||||
parts := f.Names()
|
||||
if len(parts) == 1 {
|
||||
continue
|
||||
}
|
||||
var ff *flag.Flag
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if visited[name] {
|
||||
if ff != nil {
|
||||
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
||||
}
|
||||
ff = set.Lookup(name)
|
||||
}
|
||||
}
|
||||
if ff == nil {
|
||||
continue
|
||||
}
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if !visited[name] {
|
||||
copyFlag(name, ff, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
|
||||
visible = append(visible, f)
|
||||
}
|
||||
}
|
||||
return visible
|
||||
}
|
||||
|
||||
func prefixFor(name string) (prefix string) {
|
||||
if len(name) == 1 {
|
||||
prefix = "-"
|
||||
} else {
|
||||
prefix = "--"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the placeholder, if any, and the unquoted usage string.
|
||||
func unquoteUsage(usage string) (string, string) {
|
||||
for i := 0; i < len(usage); i++ {
|
||||
if usage[i] == '`' {
|
||||
for j := i + 1; j < len(usage); j++ {
|
||||
if usage[j] == '`' {
|
||||
name := usage[i+1 : j]
|
||||
usage = usage[:i] + name + usage[j+1:]
|
||||
return name, usage
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return "", usage
|
||||
}
|
||||
|
||||
func prefixedNames(names []string, placeholder string) string {
|
||||
var prefixed string
|
||||
for i, name := range names {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
prefixed += prefixFor(name) + name
|
||||
if placeholder != "" {
|
||||
prefixed += " " + placeholder
|
||||
}
|
||||
if i < len(names)-1 {
|
||||
prefixed += ", "
|
||||
}
|
||||
}
|
||||
return prefixed
|
||||
}
|
||||
|
||||
func envFormat(envVars []string, prefix, sep, suffix string) string {
|
||||
if len(envVars) > 0 {
|
||||
return fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultEnvFormat(envVars []string) string {
|
||||
return envFormat(envVars, "$", ", $", "")
|
||||
}
|
||||
|
||||
func withEnvHint(envVars []string, str string) string {
|
||||
envText := ""
|
||||
if runtime.GOOS != "windows" || os.Getenv("PSHOME") != "" {
|
||||
envText = defaultEnvFormat(envVars)
|
||||
} else {
|
||||
envText = envFormat(envVars, "%", "%, %", "%")
|
||||
}
|
||||
return str + envText
|
||||
}
|
||||
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
// v1 -> v2 migration warning zone:
|
||||
// Strip off anything after the first found comma or space, which
|
||||
// *hopefully* makes it a tiny bit more obvious that unexpected behavior is
|
||||
// caused by using the v1 form of stringly typed "Name".
|
||||
ret = append(ret, commaWhitespace.ReplaceAllString(part, ""))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func withFileHint(filePath, str string) string {
|
||||
fileText := ""
|
||||
if filePath != "" {
|
||||
fileText = fmt.Sprintf(" [%s]", filePath)
|
||||
}
|
||||
return str + fileText
|
||||
}
|
||||
|
||||
func formatDefault(format string) string {
|
||||
return " (default: " + format + ")"
|
||||
}
|
||||
|
||||
func stringifyFlag(f Flag) string {
|
||||
// enforce DocGeneration interface on flags to avoid reflection
|
||||
df, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||
needsPlaceholder := df.TakesValue()
|
||||
|
||||
if needsPlaceholder && placeholder == "" {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
|
||||
defaultValueString := ""
|
||||
|
||||
// set default text for all flags except bool flags
|
||||
// for bool flags display default text if DisableDefaultText is not
|
||||
// set
|
||||
if bf, ok := f.(*BoolFlag); !ok || !bf.DisableDefaultText {
|
||||
if s := df.GetDefaultText(); s != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||
}
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||
|
||||
pn := prefixedNames(df.Names(), placeholder)
|
||||
sliceFlag, ok := f.(DocGenerationSliceFlag)
|
||||
if ok && sliceFlag.IsSliceFlag() {
|
||||
pn = pn + " [ " + pn + " ]"
|
||||
}
|
||||
|
||||
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||
}
|
||||
|
||||
func hasFlag(flags []Flag, fl Flag) bool {
|
||||
for _, existing := range flags {
|
||||
if fl == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Return the first value from a list of environment variables and files
|
||||
// (which may or may not exist), a description of where the value was found,
|
||||
// and a boolean which is true if a value was found.
|
||||
func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhere string, found bool) {
|
||||
for _, envVar := range envVars {
|
||||
envVar = strings.TrimSpace(envVar)
|
||||
if value, found := syscall.Getenv(envVar); found {
|
||||
return value, fmt.Sprintf("environment variable %q", envVar), true
|
||||
}
|
||||
}
|
||||
for _, fileVar := range strings.Split(filePath, ",") {
|
||||
if fileVar != "" {
|
||||
if data, err := os.ReadFile(fileVar); err == nil {
|
||||
return string(data), fmt.Sprintf("file %q", filePath), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
type customizedSeparator interface {
|
||||
WithSeparatorSpec(separatorSpec)
|
||||
}
|
||||
|
||||
type separatorSpec struct {
|
||||
sep string
|
||||
disabled bool
|
||||
customized bool
|
||||
}
|
||||
|
||||
func (s separatorSpec) flagSplitMultiValues(val string) []string {
|
||||
var (
|
||||
disabled bool = s.disabled
|
||||
sep string = s.sep
|
||||
)
|
||||
if !s.customized {
|
||||
disabled = disableSliceFlagSeparator
|
||||
sep = defaultSliceFlagSeparator
|
||||
}
|
||||
if disabled {
|
||||
return []string{val}
|
||||
}
|
||||
|
||||
return strings.Split(val, sep)
|
||||
}
|
||||
178
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
Normal file
178
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// boolValue needs to implement the boolFlag internal interface in flag
|
||||
// to be able to capture bool fields and values
|
||||
//
|
||||
// type boolFlag interface {
|
||||
// Value
|
||||
// IsBoolFlag() bool
|
||||
// }
|
||||
type boolValue struct {
|
||||
destination *bool
|
||||
count *int
|
||||
}
|
||||
|
||||
func newBoolValue(val bool, p *bool, count *int) *boolValue {
|
||||
*p = val
|
||||
return &boolValue{
|
||||
destination: p,
|
||||
count: count,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
err = errors.New("parse error")
|
||||
return err
|
||||
}
|
||||
*b.destination = v
|
||||
if b.count != nil {
|
||||
*b.count = *b.count + 1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *boolValue) Get() interface{} { return *b.destination }
|
||||
|
||||
func (b *boolValue) String() string {
|
||||
if b.destination != nil {
|
||||
return strconv.FormatBool(*b.destination)
|
||||
}
|
||||
return strconv.FormatBool(false)
|
||||
}
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func (b *boolValue) Count() int {
|
||||
if b.count != nil && *b.count > 0 {
|
||||
return *b.count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *BoolFlag) TakesValue() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *BoolFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *BoolFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *BoolFlag) GetValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *BoolFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%v", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *BoolFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *BoolFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Bool(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valBool, err := strconv.ParseBool(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as bool value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valBool
|
||||
} else {
|
||||
// empty value implies that the env is defined but set to empty string, we have to assume that this is
|
||||
// what the user wants. If user doesnt want this then the env needs to be deleted or the flag removed from
|
||||
// file
|
||||
f.Value = false
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
count := f.Count
|
||||
dest := f.Destination
|
||||
|
||||
if count == nil {
|
||||
count = new(int)
|
||||
}
|
||||
|
||||
// since count will be incremented for each alias as well
|
||||
// subtract number of aliases from overall count
|
||||
*count -= len(f.Aliases)
|
||||
|
||||
if dest == nil {
|
||||
dest = new(bool)
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
value := newBoolValue(f.Value, dest, count)
|
||||
set.Var(value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *BoolFlag) Get(ctx *Context) bool {
|
||||
return ctx.Bool(f.Name)
|
||||
}
|
||||
|
||||
// Bool looks up the value of a local BoolFlag, returns
|
||||
// false if not found
|
||||
func (cCtx *Context) Bool(name string) bool {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupBool(name, fs)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseBool(f.Value.String())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return false
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
Normal file
108
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *DurationFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *DurationFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *DurationFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *DurationFlag) GetValue() string {
|
||||
return f.Value.String()
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *DurationFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return f.defaultValue.String()
|
||||
}
|
||||
return f.Value.String()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *DurationFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valDuration, err := time.ParseDuration(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as duration value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valDuration
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.DurationVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Duration(name, f.Value, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *DurationFlag) Get(ctx *Context) time.Duration {
|
||||
return ctx.Duration(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *DurationFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Duration(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Duration looks up the value of a local DurationFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Duration(name string) time.Duration {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupDuration(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := time.ParseDuration(f.Value.String())
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
48
vendor/github.com/urfave/cli/v2/flag_ext.go
generated
vendored
Normal file
48
vendor/github.com/urfave/cli/v2/flag_ext.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package cli
|
||||
|
||||
import "flag"
|
||||
|
||||
type extFlag struct {
|
||||
f *flag.Flag
|
||||
}
|
||||
|
||||
func (e *extFlag) Apply(fs *flag.FlagSet) error {
|
||||
fs.Var(e.f.Value, e.f.Name, e.f.Usage)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *extFlag) Names() []string {
|
||||
return []string{e.f.Name}
|
||||
}
|
||||
|
||||
func (e *extFlag) IsSet() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *extFlag) String() string {
|
||||
return FlagStringer(e)
|
||||
}
|
||||
|
||||
func (e *extFlag) IsVisible() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *extFlag) TakesValue() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *extFlag) GetUsage() string {
|
||||
return e.f.Usage
|
||||
}
|
||||
|
||||
func (e *extFlag) GetValue() string {
|
||||
return e.f.Value.String()
|
||||
}
|
||||
|
||||
func (e *extFlag) GetDefaultText() string {
|
||||
return e.f.DefValue
|
||||
}
|
||||
|
||||
func (e *extFlag) GetEnvVars() []string {
|
||||
return nil
|
||||
}
|
||||
107
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
Normal file
107
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Float64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Float64Flag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Float64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Float64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Float64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%v", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Float64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valFloat, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valFloat
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Float64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Float64(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64Flag) Get(ctx *Context) float64 {
|
||||
return ctx.Float64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64 looks up the value of a local Float64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Float64(name string) float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
216
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
Normal file
216
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Float64Slice wraps []float64 to satisfy flag.Value
|
||||
type Float64Slice struct {
|
||||
slice []float64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewFloat64Slice makes a *Float64Slice with default values
|
||||
func NewFloat64Slice(defaults ...float64) *Float64Slice {
|
||||
return &Float64Slice{slice: append([]float64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (f *Float64Slice) clone() *Float64Slice {
|
||||
n := &Float64Slice{
|
||||
slice: make([]float64, len(f.slice)),
|
||||
hasBeenSet: f.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, f.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
func (f *Float64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into a float64 and appends it to the list of values
|
||||
func (f *Float64Slice) Set(value string) error {
|
||||
if !f.hasBeenSet {
|
||||
f.slice = []float64{}
|
||||
f.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &f.slice)
|
||||
f.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range f.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.slice = append(f.slice, tmp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Float64Slice) String() string {
|
||||
v := f.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]float64, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows Float64Slice to fulfill Serializer
|
||||
func (f *Float64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(f.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of float64s set by this flag
|
||||
func (f *Float64Slice) Value() []float64 {
|
||||
return f.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of float64s set by this flag
|
||||
func (f *Float64Slice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *Float64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Float64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Float64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Float64SliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Float64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Float64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Float64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]float64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Float64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Float64Slice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Float64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
|
||||
return ctx.Float64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Float64Slice(name string) []float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Float64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
131
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
Normal file
131
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Generic is a generic parseable type identified by a specific flag
|
||||
type Generic interface {
|
||||
Set(value string) error
|
||||
String() string
|
||||
}
|
||||
|
||||
type stringGeneric struct {
|
||||
value string
|
||||
}
|
||||
|
||||
func (s *stringGeneric) Set(value string) error {
|
||||
s.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringGeneric) String() string {
|
||||
return s.value
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *GenericFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *GenericFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *GenericFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *GenericFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *GenericFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val != nil {
|
||||
return val.String()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *GenericFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply takes the flagset and calls Set on the generic flag with the value
|
||||
// provided by the user for parsing by the flag
|
||||
func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
if f.Value != nil {
|
||||
f.defaultValue = &stringGeneric{value: f.Value.String()}
|
||||
f.defaultValueSet = true
|
||||
}
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
if err := f.Value.Set(val); err != nil {
|
||||
return fmt.Errorf("could not parse %q from %s as value for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *GenericFlag) Get(ctx *Context) interface{} {
|
||||
return ctx.Generic(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *GenericFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Generic(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Generic(name string) interface{} {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupGeneric(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
109
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
Normal file
109
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *IntFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *IntFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *IntFlag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *IntFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *IntFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = int(valInt)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.IntVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Int(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntFlag) Get(ctx *Context) int {
|
||||
return ctx.Int(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int looks up the value of a local IntFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupInt(name string, set *flag.FlagSet) int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(parsed)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
Normal file
108
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Int64Flag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Int64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Int64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Int64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Int64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Int64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Int64(name, f.Value, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64Flag) Get(ctx *Context) int64 {
|
||||
return ctx.Int64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64 looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int64(name string) int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
215
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
Normal file
215
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Int64Slice wraps []int64 to satisfy flag.Value
|
||||
type Int64Slice struct {
|
||||
slice []int64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewInt64Slice makes an *Int64Slice with default values
|
||||
func NewInt64Slice(defaults ...int64) *Int64Slice {
|
||||
return &Int64Slice{slice: append([]int64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Int64Slice) clone() *Int64Slice {
|
||||
n := &Int64Slice{
|
||||
slice: make([]int64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
func (i *Int64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Int64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int64{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Int64Slice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]int64, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows Int64Slice to fulfill Serializer
|
||||
func (i *Int64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *Int64Slice) Value() []int64 {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *Int64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Int64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Int64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Int64SliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Int64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Int64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Int64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]int64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Int64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Int64Slice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Int64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
|
||||
return ctx.Int64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Int64Slice(name string) []int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Int64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
226
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
Normal file
226
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IntSlice wraps []int to satisfy flag.Value
|
||||
type IntSlice struct {
|
||||
slice []int
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewIntSlice makes an *IntSlice with default values
|
||||
func NewIntSlice(defaults ...int) *IntSlice {
|
||||
return &IntSlice{slice: append([]int{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *IntSlice) clone() *IntSlice {
|
||||
n := &IntSlice{
|
||||
slice: make([]int, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *IntSlice) SetInt(value int) {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, value)
|
||||
}
|
||||
|
||||
func (i *IntSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *IntSlice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []int{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, int(tmp))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *IntSlice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]int, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows IntSlice to fulfill Serializer
|
||||
func (i *IntSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *IntSlice) Value() []int {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *IntSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *IntSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *IntSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *IntSliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.Itoa(i))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *IntSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *IntSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *IntSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]int, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *IntSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(IntSlice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *IntSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntSliceFlag) Get(ctx *Context) []int {
|
||||
return ctx.IntSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.IntSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) IntSlice(name string) []int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupIntSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*IntSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
Normal file
102
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Path = string
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *PathFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *PathFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *PathFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *PathFlag) GetValue() string {
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *PathFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *PathFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.String(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *PathFlag) Get(ctx *Context) string {
|
||||
return ctx.Path(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *PathFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Path(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Path looks up the value of a local PathFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) Path(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupPath(name, fs)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func lookupPath(name string, set *flag.FlagSet) string {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
100
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
Normal file
100
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *StringFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *StringFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *StringFlag) GetValue() string {
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *StringFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *StringFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.String(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringFlag) Get(ctx *Context) string {
|
||||
return ctx.String(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.String(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String looks up the value of a local StringFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) String(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupString(name, fs)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func lookupString(name string, set *flag.FlagSet) string {
|
||||
if f := set.Lookup(name); f != nil {
|
||||
return f.Value.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
216
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
Normal file
216
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StringSlice wraps a []string to satisfy flag.Value
|
||||
type StringSlice struct {
|
||||
slice []string
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
keepSpace bool
|
||||
}
|
||||
|
||||
// NewStringSlice creates a *StringSlice with default values
|
||||
func NewStringSlice(defaults ...string) *StringSlice {
|
||||
return &StringSlice{slice: append([]string{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (s *StringSlice) clone() *StringSlice {
|
||||
n := &StringSlice{
|
||||
slice: make([]string, len(s.slice)),
|
||||
hasBeenSet: s.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, s.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set appends the string value to the list of values
|
||||
func (s *StringSlice) Set(value string) error {
|
||||
if !s.hasBeenSet {
|
||||
s.slice = []string{}
|
||||
s.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &s.slice)
|
||||
s.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, t := range s.separator.flagSplitMultiValues(value) {
|
||||
if !s.keepSpace {
|
||||
t = strings.TrimSpace(t)
|
||||
}
|
||||
s.slice = append(s.slice, t)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StringSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
s.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (s *StringSlice) String() string {
|
||||
return fmt.Sprintf("%s", s.slice)
|
||||
}
|
||||
|
||||
// Serialize allows StringSlice to fulfill Serializer
|
||||
func (s *StringSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(s.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of strings set by this flag
|
||||
func (s *StringSlice) Value() []string {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of strings set by this flag
|
||||
func (s *StringSlice) Get() interface{} {
|
||||
return *s
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *StringSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *StringSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *StringSliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, s := range f.Value.Value() {
|
||||
if len(s) > 0 {
|
||||
defaultVals = append(defaultVals, strconv.Quote(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *StringSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *StringSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *StringSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]string, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *StringSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(StringSlice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
setValue.keepSpace = f.KeepSpace
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if !f.KeepSpace {
|
||||
s = strings.TrimSpace(s)
|
||||
}
|
||||
if err := setValue.Set(s); err != nil {
|
||||
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *StringSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringSliceFlag) Get(ctx *Context) []string {
|
||||
return ctx.StringSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.StringSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) StringSlice(name string) []string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupStringSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*StringSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
205
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
Normal file
205
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp wrap to satisfy golang's flag interface.
|
||||
type Timestamp struct {
|
||||
timestamp *time.Time
|
||||
hasBeenSet bool
|
||||
layout string
|
||||
location *time.Location
|
||||
}
|
||||
|
||||
// Timestamp constructor
|
||||
func NewTimestamp(timestamp time.Time) *Timestamp {
|
||||
return &Timestamp{timestamp: ×tamp}
|
||||
}
|
||||
|
||||
// Set the timestamp value directly
|
||||
func (t *Timestamp) SetTimestamp(value time.Time) {
|
||||
if !t.hasBeenSet {
|
||||
t.timestamp = &value
|
||||
t.hasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
// Set the timestamp string layout for future parsing
|
||||
func (t *Timestamp) SetLayout(layout string) {
|
||||
t.layout = layout
|
||||
}
|
||||
|
||||
// Set perceived timezone of the to-be parsed time string
|
||||
func (t *Timestamp) SetLocation(loc *time.Location) {
|
||||
t.location = loc
|
||||
}
|
||||
|
||||
// Parses the string value to timestamp
|
||||
func (t *Timestamp) Set(value string) error {
|
||||
var timestamp time.Time
|
||||
var err error
|
||||
|
||||
if t.location != nil {
|
||||
timestamp, err = time.ParseInLocation(t.layout, value, t.location)
|
||||
} else {
|
||||
timestamp, err = time.Parse(t.layout, value)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.timestamp = ×tamp
|
||||
t.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (t *Timestamp) String() string {
|
||||
return fmt.Sprintf("%#v", t.timestamp)
|
||||
}
|
||||
|
||||
// Value returns the timestamp value stored in the flag
|
||||
func (t *Timestamp) Value() *time.Time {
|
||||
return t.timestamp
|
||||
}
|
||||
|
||||
// Get returns the flag structure
|
||||
func (t *Timestamp) Get() interface{} {
|
||||
return *t
|
||||
}
|
||||
|
||||
// clone timestamp
|
||||
func (t *Timestamp) clone() *Timestamp {
|
||||
tc := &Timestamp{
|
||||
timestamp: nil,
|
||||
hasBeenSet: t.hasBeenSet,
|
||||
layout: t.layout,
|
||||
location: nil,
|
||||
}
|
||||
if t.timestamp != nil {
|
||||
tts := *t.timestamp
|
||||
tc.timestamp = &tts
|
||||
}
|
||||
if t.location != nil {
|
||||
loc := *t.location
|
||||
tc.location = &loc
|
||||
}
|
||||
return tc
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *TimestampFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *TimestampFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *TimestampFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *TimestampFlag) GetValue() string {
|
||||
if f.Value != nil && f.Value.timestamp != nil {
|
||||
return f.Value.timestamp.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *TimestampFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
val := f.Value
|
||||
if f.defaultValueSet {
|
||||
val = f.defaultValue
|
||||
}
|
||||
|
||||
if val != nil && val.timestamp != nil {
|
||||
return val.timestamp.String()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *TimestampFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||
if f.Layout == "" {
|
||||
return fmt.Errorf("timestamp Layout is required")
|
||||
}
|
||||
if f.Value == nil {
|
||||
f.Value = &Timestamp{}
|
||||
}
|
||||
f.Value.SetLayout(f.Layout)
|
||||
f.Value.SetLocation(f.Timezone)
|
||||
|
||||
f.defaultValue = f.Value.clone()
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if err := f.Value.Set(val); err != nil {
|
||||
return fmt.Errorf("could not parse %q as timestamp value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
if f.Destination != nil {
|
||||
*f.Destination = *f.Value
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *TimestampFlag) Get(ctx *Context) *time.Time {
|
||||
return ctx.Timestamp(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *TimestampFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Timestamp(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (cCtx *Context) Timestamp(name string) *time.Time {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupTimestamp(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fetches the timestamp value from the local timestampWrap
|
||||
func lookupTimestamp(name string, set *flag.FlagSet) *time.Time {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
return (f.Value.(*Timestamp)).Value()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
Normal file
108
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *UintFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *UintFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = uint(valInt)
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.UintVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Uint(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *UintFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *UintFlag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *UintFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintFlag) Get(ctx *Context) uint {
|
||||
return ctx.Uint(f.Name)
|
||||
}
|
||||
|
||||
// Uint looks up the value of a local UintFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Uint(name string) uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupUint(name string, set *flag.FlagSet) uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint(parsed)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
108
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
Normal file
108
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64Flag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Uint64Flag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Uint64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
||||
// set default value so that environment wont be able to overwrite it
|
||||
f.defaultValue = f.Value
|
||||
f.defaultValueSet = true
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Uint64Var(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Uint64(name, f.Value, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Uint64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Uint64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Uint64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.defaultValueSet {
|
||||
return fmt.Sprintf("%d", f.defaultValue)
|
||||
}
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64Flag) Get(ctx *Context) uint64 {
|
||||
return ctx.Uint64(f.Name)
|
||||
}
|
||||
|
||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Uint64(name string) uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64(name, fs)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
219
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
Normal file
219
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Uint64Slice wraps []int64 to satisfy flag.Value
|
||||
type Uint64Slice struct {
|
||||
slice []uint64
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUint64Slice makes an *Uint64Slice with default values
|
||||
func NewUint64Slice(defaults ...uint64) *Uint64Slice {
|
||||
return &Uint64Slice{slice: append([]uint64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Uint64Slice) clone() *Uint64Slice {
|
||||
n := &Uint64Slice{
|
||||
slice: make([]uint64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Uint64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint64{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Uint64Slice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Uint64Slice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint64, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint64%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows Uint64Slice to fulfill Serializer
|
||||
func (i *Uint64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Value() []uint64 {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Uint64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Uint64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Uint64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Uint64SliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Uint64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Uint64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Uint64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Uint64Slice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Uint64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
|
||||
return ctx.Uint64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Uint64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Uint64Slice(name string) []uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUint64Slice(name string, set *flag.FlagSet) []uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Uint64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
230
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
Normal file
230
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// UintSlice wraps []int to satisfy flag.Value
|
||||
type UintSlice struct {
|
||||
slice []uint
|
||||
separator separatorSpec
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUintSlice makes an *UintSlice with default values
|
||||
func NewUintSlice(defaults ...uint) *UintSlice {
|
||||
return &UintSlice{slice: append([]uint{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *UintSlice) clone() *UintSlice {
|
||||
n := &UintSlice{
|
||||
slice: make([]uint, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *UintSlice) SetUint(value uint) {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, value)
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *UintSlice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range i.separator.flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, uint(tmp))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *UintSlice) WithSeparatorSpec(spec separatorSpec) {
|
||||
i.separator = spec
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *UintSlice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows UintSlice to fulfill Serializer
|
||||
func (i *UintSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Value() []uint {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *UintSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *UintSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *UintSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *UintSliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *UintSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *UintSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *UintSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(UintSlice)
|
||||
setValue.WithSeparatorSpec(f.separator)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range f.separator.flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *UintSliceFlag) WithSeparatorSpec(spec separatorSpec) {
|
||||
f.separator = spec
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintSliceFlag) Get(ctx *Context) []uint {
|
||||
return ctx.UintSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *UintSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.UintSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) UintSlice(name string) []uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUintSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUintSlice(name string, set *flag.FlagSet) []uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*UintSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
47
vendor/github.com/urfave/cli/v2/funcs.go
generated
vendored
Normal file
47
vendor/github.com/urfave/cli/v2/funcs.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package cli
|
||||
|
||||
// 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
|
||||
// the context is ready if a non-nil error is returned, no subcommands are run
|
||||
type BeforeFunc func(*Context) error
|
||||
|
||||
// AfterFunc is an action to execute after any subcommands are run, but after the
|
||||
// subcommand has finished it is run even if Action() panics
|
||||
type AfterFunc func(*Context) error
|
||||
|
||||
// ActionFunc is the action to execute when no subcommands are specified
|
||||
type ActionFunc func(*Context) error
|
||||
|
||||
// CommandNotFoundFunc is executed if the proper command cannot be found
|
||||
type CommandNotFoundFunc func(*Context, string)
|
||||
|
||||
// OnUsageErrorFunc is executed if a usage error occurs. This is useful for displaying
|
||||
// customized usage error messages. This function is able to replace the
|
||||
// original error messages. If this function is not set, the "Incorrect usage"
|
||||
// is displayed and the execution is interrupted.
|
||||
type OnUsageErrorFunc func(cCtx *Context, err error, isSubcommand bool) error
|
||||
|
||||
// InvalidFlagAccessFunc is executed when an invalid flag is accessed from the context.
|
||||
type InvalidFlagAccessFunc func(*Context, string)
|
||||
|
||||
// ExitErrHandlerFunc is executed if provided in order to handle exitError values
|
||||
// returned by Actions and Before/After functions.
|
||||
type ExitErrHandlerFunc func(cCtx *Context, err error)
|
||||
|
||||
// FlagStringFunc is used by the help generation to display a flag, which is
|
||||
// expected to be a single line.
|
||||
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 []string, placeholder string) string
|
||||
|
||||
// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help
|
||||
// with the environment variable details.
|
||||
type FlagEnvHintFunc func(envVars []string, str string) string
|
||||
|
||||
// FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help
|
||||
// with the file path details.
|
||||
type FlagFileHintFunc func(filePath, str string) string
|
||||
2724
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
Normal file
2724
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
564
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
Normal file
564
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
Normal file
@ -0,0 +1,564 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
helpName = "help"
|
||||
helpAlias = "h"
|
||||
)
|
||||
|
||||
// this instance is to avoid recursion in the ShowCommandHelp which can
|
||||
// add a help command again
|
||||
var helpCommandDontUse = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
}
|
||||
|
||||
var helpCommand = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
Action: func(cCtx *Context) error {
|
||||
args := cCtx.Args()
|
||||
argsPresent := args.First() != ""
|
||||
firstArg := args.First()
|
||||
|
||||
// This action can be triggered by a "default" action of a command
|
||||
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||
//
|
||||
// 1 $ app
|
||||
// 2 $ app help
|
||||
// 3 $ app foo
|
||||
// 4 $ app help foo
|
||||
// 5 $ app foo help
|
||||
// 6 $ app foo -h (with no other sub-commands nor flags defined)
|
||||
|
||||
// Case 4. when executing a help command set the context to parent
|
||||
// to allow resolution of subsequent args. This will transform
|
||||
// $ app help foo
|
||||
// to
|
||||
// $ app foo
|
||||
// which will then be handled as case 3
|
||||
if cCtx.Command.Name == helpName || cCtx.Command.Name == helpAlias {
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
|
||||
// Case 4. $ app hello foo
|
||||
// foo is the command for which help needs to be shown
|
||||
if argsPresent {
|
||||
return ShowCommandHelp(cCtx, firstArg)
|
||||
}
|
||||
|
||||
// Case 1 & 2
|
||||
// Special case when running help on main app itself as opposed to individual
|
||||
// commands/subcommands
|
||||
if cCtx.parentContext.App == nil {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 3, 5
|
||||
if (len(cCtx.Command.Subcommands) == 1 && !cCtx.Command.HideHelp && !cCtx.Command.HideHelpCommand) ||
|
||||
(len(cCtx.Command.Subcommands) == 0 && cCtx.Command.HideHelp) {
|
||||
templ := cCtx.Command.CustomHelpTemplate
|
||||
if templ == "" {
|
||||
templ = CommandHelpTemplate
|
||||
}
|
||||
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 6, handling incorporated in the callee itself
|
||||
return ShowSubcommandHelp(cCtx)
|
||||
},
|
||||
}
|
||||
|
||||
// Prints help for the App or Command
|
||||
type helpPrinter func(w io.Writer, templ string, data interface{})
|
||||
|
||||
// Prints help for the App or Command with custom template function.
|
||||
type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
|
||||
|
||||
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
||||
// this calls HelpPrinterCustom using only the default template functions.
|
||||
//
|
||||
// If custom logic for printing help is required, this function can be
|
||||
// overridden. If the ExtraInfo field is defined on an App, this function
|
||||
// should not be modified, as HelpPrinterCustom will be used directly in order
|
||||
// to capture the extra information.
|
||||
var HelpPrinter helpPrinter = printHelp
|
||||
|
||||
// HelpPrinterCustom is a function that writes the help output. It is used as
|
||||
// the default implementation of HelpPrinter, and may be called directly if
|
||||
// the ExtraInfo field is set on an App.
|
||||
//
|
||||
// In the default implementation, if the customFuncs argument contains a
|
||||
// "wrapAt" key, which is a function which takes no arguments and returns
|
||||
// an int, this int value will be used to produce a "wrap" function used
|
||||
// by the default template to wrap long lines.
|
||||
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
|
||||
|
||||
// VersionPrinter prints the version for the App
|
||||
var VersionPrinter = printVersion
|
||||
|
||||
// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
|
||||
func ShowAppHelpAndExit(c *Context, exitCode int) {
|
||||
_ = ShowAppHelp(c)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowAppHelp is an action that displays the help.
|
||||
func ShowAppHelp(cCtx *Context) error {
|
||||
tpl := cCtx.App.CustomAppHelpTemplate
|
||||
if tpl == "" {
|
||||
tpl = AppHelpTemplate
|
||||
}
|
||||
|
||||
if cCtx.App.ExtraInfo == nil {
|
||||
HelpPrinter(cCtx.App.Writer, tpl, cCtx.App)
|
||||
return nil
|
||||
}
|
||||
|
||||
customAppData := func() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ExtraInfo": cCtx.App.ExtraInfo,
|
||||
}
|
||||
}
|
||||
HelpPrinterCustom(cCtx.App.Writer, tpl, cCtx.App, customAppData())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
||||
func DefaultAppComplete(cCtx *Context) {
|
||||
DefaultCompleteWithFlags(nil)(cCtx)
|
||||
}
|
||||
|
||||
func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
|
||||
for _, name := range command.Names() {
|
||||
_, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage)
|
||||
}
|
||||
} else {
|
||||
for _, name := range command.Names() {
|
||||
_, _ = fmt.Fprintf(writer, "%s\n", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cliArgContains(flagName string) bool {
|
||||
for _, name := range strings.Split(flagName, ",") {
|
||||
name = strings.TrimSpace(name)
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
for _, a := range os.Args {
|
||||
if a == flag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
|
||||
cur := strings.TrimPrefix(lastArg, "-")
|
||||
cur = strings.TrimPrefix(cur, "-")
|
||||
for _, flag := range flags {
|
||||
if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden {
|
||||
continue
|
||||
}
|
||||
for _, name := range flag.Names() {
|
||||
name = strings.TrimSpace(name)
|
||||
// this will get total count utf8 letters in flag name
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2 // reuse this count to generate single - or -- in flag completion
|
||||
}
|
||||
// if flag name has more than one utf8 letter and last argument in cli has -- prefix then
|
||||
// skip flag completion for short flags example -v or -x
|
||||
if strings.HasPrefix(lastArg, "--") && count == 1 {
|
||||
continue
|
||||
}
|
||||
// match if last argument matches this flag and it is not repeated
|
||||
if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) {
|
||||
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
_, _ = fmt.Fprintln(writer, flagCompletion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) {
|
||||
return func(cCtx *Context) {
|
||||
var lastArg string
|
||||
|
||||
// TODO: This shouldnt depend on os.Args rather it should
|
||||
// depend on root arguments passed to App
|
||||
if len(os.Args) > 2 {
|
||||
lastArg = os.Args[len(os.Args)-2]
|
||||
}
|
||||
|
||||
if lastArg != "" {
|
||||
if strings.HasPrefix(lastArg, "-") {
|
||||
if cmd != nil {
|
||||
printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
printFlagSuggestions(lastArg, cCtx.App.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
printCommandSuggestions(cmd.Subcommands, cCtx.App.Writer)
|
||||
return
|
||||
}
|
||||
|
||||
printCommandSuggestions(cCtx.Command.Subcommands, cCtx.App.Writer)
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandHelpAndExit - exits with code after showing help
|
||||
func ShowCommandHelpAndExit(c *Context, command string, code int) {
|
||||
_ = ShowCommandHelp(c, command)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ShowCommandHelp prints help for the given command
|
||||
func ShowCommandHelp(ctx *Context, command string) error {
|
||||
|
||||
commands := ctx.App.Commands
|
||||
if ctx.Command.Subcommands != nil {
|
||||
commands = ctx.Command.Subcommands
|
||||
}
|
||||
for _, c := range commands {
|
||||
if c.HasName(command) {
|
||||
if !ctx.App.HideHelpCommand && !c.HasName(helpName) && len(c.Subcommands) != 0 && c.Command(helpName) == nil {
|
||||
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
||||
}
|
||||
if !ctx.App.HideHelp && HelpFlag != nil {
|
||||
c.appendFlag(HelpFlag)
|
||||
}
|
||||
templ := c.CustomHelpTemplate
|
||||
if templ == "" {
|
||||
if len(c.Subcommands) == 0 {
|
||||
templ = CommandHelpTemplate
|
||||
} else {
|
||||
templ = SubcommandHelpTemplate
|
||||
}
|
||||
}
|
||||
|
||||
HelpPrinter(ctx.App.Writer, templ, c)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.App.CommandNotFound == nil {
|
||||
errMsg := fmt.Sprintf("No help topic for '%v'", command)
|
||||
if ctx.App.Suggest && SuggestCommand != nil {
|
||||
if suggestion := SuggestCommand(ctx.Command.Subcommands, command); suggestion != "" {
|
||||
errMsg += ". " + suggestion
|
||||
}
|
||||
}
|
||||
return Exit(errMsg, 3)
|
||||
}
|
||||
|
||||
ctx.App.CommandNotFound(ctx, command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||
func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
|
||||
_ = ShowSubcommandHelp(c)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowSubcommandHelp prints help for the given subcommand
|
||||
func ShowSubcommandHelp(cCtx *Context) error {
|
||||
if cCtx == nil {
|
||||
return nil
|
||||
}
|
||||
// use custom template when provided (fixes #1703)
|
||||
templ := SubcommandHelpTemplate
|
||||
if cCtx.Command != nil && cCtx.Command.CustomHelpTemplate != "" {
|
||||
templ = cCtx.Command.CustomHelpTemplate
|
||||
}
|
||||
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowVersion prints the version number of the App
|
||||
func ShowVersion(cCtx *Context) {
|
||||
VersionPrinter(cCtx)
|
||||
}
|
||||
|
||||
func printVersion(cCtx *Context) {
|
||||
_, _ = fmt.Fprintf(cCtx.App.Writer, "%v version %v\n", cCtx.App.Name, cCtx.App.Version)
|
||||
}
|
||||
|
||||
// ShowCompletions prints the lists of commands within a given context
|
||||
func ShowCompletions(cCtx *Context) {
|
||||
c := cCtx.Command
|
||||
if c != nil && c.BashComplete != nil {
|
||||
c.BashComplete(cCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandCompletions prints the custom completions for a given command
|
||||
func ShowCommandCompletions(ctx *Context, command string) {
|
||||
c := ctx.Command.Command(command)
|
||||
if c != nil {
|
||||
if c.BashComplete != nil {
|
||||
c.BashComplete(ctx)
|
||||
} else {
|
||||
DefaultCompleteWithFlags(c)(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// printHelpCustom is the default implementation of HelpPrinterCustom.
|
||||
//
|
||||
// The customFuncs map will be combined with a default template.FuncMap to
|
||||
// allow using arbitrary functions in template rendering.
|
||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||
|
||||
const maxLineLength = 10000
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"join": strings.Join,
|
||||
"subtract": subtract,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
|
||||
"offset": offset,
|
||||
"offsetCommands": offsetCommands,
|
||||
}
|
||||
|
||||
if customFuncs["wrapAt"] != nil {
|
||||
if wa, ok := customFuncs["wrapAt"]; ok {
|
||||
if waf, ok := wa.(func() int); ok {
|
||||
wrapAt := waf()
|
||||
customFuncs["wrap"] = func(input string, offset int) string {
|
||||
return wrap(input, offset, wrapAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range customFuncs {
|
||||
funcMap[key] = value
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||
templates := map[string]string{
|
||||
"helpNameTemplate": helpNameTemplate,
|
||||
"usageTemplate": usageTemplate,
|
||||
"descriptionTemplate": descriptionTemplate,
|
||||
"visibleCommandTemplate": visibleCommandTemplate,
|
||||
"copyrightTemplate": copyrightTemplate,
|
||||
"versionTemplate": versionTemplate,
|
||||
"visibleFlagCategoryTemplate": visibleFlagCategoryTemplate,
|
||||
"visibleFlagTemplate": visibleFlagTemplate,
|
||||
"visibleGlobalFlagCategoryTemplate": strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1),
|
||||
"authorsTemplate": authorsTemplate,
|
||||
"visibleCommandCategoryTemplate": visibleCommandCategoryTemplate,
|
||||
}
|
||||
for name, value := range templates {
|
||||
if _, err := t.New(name).Parse(value); err != nil {
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := t.Execute(w, data)
|
||||
if err != nil {
|
||||
// If the writer is closed, t.Execute will fail, and there's nothing
|
||||
// we can do to recover.
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
_ = w.Flush()
|
||||
}
|
||||
|
||||
func printHelp(out io.Writer, templ string, data interface{}) {
|
||||
HelpPrinterCustom(out, templ, data, nil)
|
||||
}
|
||||
|
||||
func checkVersion(cCtx *Context) bool {
|
||||
found := false
|
||||
for _, name := range VersionFlag.Names() {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func checkHelp(cCtx *Context) bool {
|
||||
if HelpFlag == nil {
|
||||
return false
|
||||
}
|
||||
found := false
|
||||
for _, name := range HelpFlag.Names() {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
|
||||
if !a.EnableBashCompletion {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
pos := len(arguments) - 1
|
||||
lastArg := arguments[pos]
|
||||
|
||||
if lastArg != "--generate-bash-completion" {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
return true, arguments[:pos]
|
||||
}
|
||||
|
||||
func checkCompletions(cCtx *Context) bool {
|
||||
if !cCtx.shellComplete {
|
||||
return false
|
||||
}
|
||||
|
||||
if args := cCtx.Args(); args.Present() {
|
||||
name := args.First()
|
||||
if cmd := cCtx.Command.Command(name); cmd != nil {
|
||||
// let the command handle the completion
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ShowCompletions(cCtx)
|
||||
return true
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func indent(spaces int, v string) string {
|
||||
pad := strings.Repeat(" ", spaces)
|
||||
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||
}
|
||||
|
||||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func wrap(input string, offset int, wrapAt int) string {
|
||||
var ss []string
|
||||
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
padding := strings.Repeat(" ", offset)
|
||||
|
||||
for i, line := range lines {
|
||||
if line == "" {
|
||||
ss = append(ss, line)
|
||||
} else {
|
||||
wrapped := wrapLine(line, offset, wrapAt, padding)
|
||||
if i == 0 {
|
||||
ss = append(ss, wrapped)
|
||||
} else {
|
||||
ss = append(ss, padding+wrapped)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(ss, "\n")
|
||||
}
|
||||
|
||||
func wrapLine(input string, offset int, wrapAt int, padding string) string {
|
||||
if wrapAt <= offset || len(input) <= wrapAt-offset {
|
||||
return input
|
||||
}
|
||||
|
||||
lineWidth := wrapAt - offset
|
||||
words := strings.Fields(input)
|
||||
if len(words) == 0 {
|
||||
return input
|
||||
}
|
||||
|
||||
wrapped := words[0]
|
||||
spaceLeft := lineWidth - len(wrapped)
|
||||
for _, word := range words[1:] {
|
||||
if len(word)+1 > spaceLeft {
|
||||
wrapped += "\n" + padding + word
|
||||
spaceLeft = lineWidth - len(word)
|
||||
} else {
|
||||
wrapped += " " + word
|
||||
spaceLeft -= 1 + len(word)
|
||||
}
|
||||
}
|
||||
|
||||
return wrapped
|
||||
}
|
||||
|
||||
func offset(input string, fixed int) int {
|
||||
return len(input) + fixed
|
||||
}
|
||||
|
||||
// this function tries to find the max width of the names column
|
||||
// so say we have the following rows for help
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// We want to offset the 2nd row usage by some amount so that everything
|
||||
// is aligned
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// to find that offset we find the length of all the rows and use the max
|
||||