Convert CLI to urfave v2
Followed the Migration Guide at https://cli.urfave.org/migrate-v1-to-v2/ The major changes not pointed out in the migration guide are: - context.Args() no longer produces a []slice, so context.Args().Slice() in substitued - All cli.Global***** are deprecated (the migration guide is somewhat unclear on this) Signed-off-by: Derek Nola <derek.nola@suse.com> Vendor in urfave cli/v2 Signed-off-by: Derek Nola <derek.nola@suse.com> Fix NewStringSlice calls Signed-off-by: Derek Nola <derek.nola@suse.com>
This commit is contained in:
parent
d4d228926c
commit
132485adb0
@ -34,14 +34,14 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/namespaces"
|
"github.com/containerd/containerd/v2/pkg/namespaces"
|
||||||
"github.com/containerd/containerd/v2/pkg/oci"
|
"github.com/containerd/containerd/v2/pkg/oci"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var densityCommand = cli.Command{
|
var densityCommand = &cli.Command{
|
||||||
Name: "density",
|
Name: "density",
|
||||||
Usage: "Stress tests density of containers running on a system",
|
Usage: "Stress tests density of containers running on a system",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "count",
|
Name: "count",
|
||||||
Usage: "Number of containers to run",
|
Usage: "Number of containers to run",
|
||||||
Value: 10,
|
Value: 10,
|
||||||
@ -58,14 +58,14 @@ var densityCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
config := config{
|
config := config{
|
||||||
Address: cliContext.GlobalString("address"),
|
Address: cliContext.String("address"),
|
||||||
Duration: cliContext.GlobalDuration("duration"),
|
Duration: cliContext.Duration("duration"),
|
||||||
Concurrency: cliContext.GlobalInt("concurrent"),
|
Concurrency: cliContext.Int("concurrent"),
|
||||||
Exec: cliContext.GlobalBool("exec"),
|
Exec: cliContext.Bool("exec"),
|
||||||
Image: cliContext.GlobalString("image"),
|
Image: cliContext.String("image"),
|
||||||
JSON: cliContext.GlobalBool("json"),
|
JSON: cliContext.Bool("json"),
|
||||||
Metrics: cliContext.GlobalString("metrics"),
|
Metrics: cliContext.String("metrics"),
|
||||||
Snapshotter: cliContext.GlobalString("snapshotter"),
|
Snapshotter: cliContext.String("snapshotter"),
|
||||||
}
|
}
|
||||||
client, err := config.newClient()
|
client, err := config.newClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -34,7 +34,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/plugins"
|
"github.com/containerd/containerd/v2/plugins"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
metrics "github.com/docker/go-metrics"
|
metrics "github.com/docker/go-metrics"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -63,9 +63,10 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.HelpFlag = cli.BoolFlag{
|
cli.HelpFlag = &cli.BoolFlag{
|
||||||
Name: "help, h",
|
Name: "help",
|
||||||
Usage: "Show help",
|
Aliases: []string{"h"},
|
||||||
|
Usage: "Show help",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,85 +130,91 @@ func main() {
|
|||||||
app.Name = "containerd-stress"
|
app.Name = "containerd-stress"
|
||||||
app.Description = "stress test a containerd daemon"
|
app.Description = "stress test a containerd daemon"
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Set debug output in the logs",
|
Usage: "Set debug output in the logs",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "address,a",
|
Name: "address",
|
||||||
Value: "/run/containerd/containerd.sock",
|
Aliases: []string{"a"},
|
||||||
Usage: "Path to the containerd socket",
|
Value: "/run/containerd/containerd.sock",
|
||||||
|
Usage: "Path to the containerd socket",
|
||||||
},
|
},
|
||||||
cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "concurrent,c",
|
Name: "concurrent",
|
||||||
Value: 1,
|
Aliases: []string{"c"},
|
||||||
Usage: "Set the concurrency of the stress test",
|
Value: 1,
|
||||||
|
Usage: "Set the concurrency of the stress test",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "cri",
|
Name: "cri",
|
||||||
Usage: "Utilize CRI to create pods for the stress test. This requires a runtime that matches CRI runtime handler. Example: --runtime runc",
|
Usage: "Utilize CRI to create pods for the stress test. This requires a runtime that matches CRI runtime handler. Example: --runtime runc",
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "duration,d",
|
Name: "duration",
|
||||||
Value: 1 * time.Minute,
|
Aliases: []string{"d"},
|
||||||
Usage: "Set the duration of the stress test",
|
Value: 1 * time.Minute,
|
||||||
|
Usage: "Set the duration of the stress test",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Usage: "Add execs to the stress tests (non-CRI only)",
|
Usage: "Add execs to the stress tests (non-CRI only)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "image,i",
|
Name: "image",
|
||||||
Value: "docker.io/library/alpine:latest",
|
Aliases: []string{"i"},
|
||||||
Usage: "Image to be utilized for testing",
|
Value: "docker.io/library/alpine:latest",
|
||||||
|
Usage: "Image to be utilized for testing",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "json,j",
|
Name: "json",
|
||||||
Usage: "Output results in json format",
|
Aliases: []string{"j"},
|
||||||
|
Usage: "Output results in json format",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "metrics,m",
|
Name: "metrics",
|
||||||
Usage: "Address to serve the metrics API",
|
Aliases: []string{"m"},
|
||||||
|
Usage: "Address to serve the metrics API",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "runtime",
|
Name: "runtime",
|
||||||
Usage: "Set the runtime to stress test",
|
Usage: "Set the runtime to stress test",
|
||||||
Value: plugins.RuntimeRuncV2,
|
Value: plugins.RuntimeRuncV2,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "snapshotter",
|
Name: "snapshotter",
|
||||||
Usage: "Set the snapshotter to use",
|
Usage: "Set the snapshotter to use",
|
||||||
Value: "overlayfs",
|
Value: "overlayfs",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Before = func(context *cli.Context) error {
|
app.Before = func(context *cli.Context) error {
|
||||||
if context.GlobalBool("json") {
|
if context.Bool("json") {
|
||||||
if err := log.SetLevel("warn"); err != nil {
|
if err := log.SetLevel("warn"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if context.GlobalBool("debug") {
|
if context.Bool("debug") {
|
||||||
if err := log.SetLevel("debug"); err != nil {
|
if err := log.SetLevel("debug"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []*cli.Command{
|
||||||
densityCommand,
|
densityCommand,
|
||||||
}
|
}
|
||||||
app.Action = func(context *cli.Context) error {
|
app.Action = func(context *cli.Context) error {
|
||||||
config := config{
|
config := config{
|
||||||
Address: context.GlobalString("address"),
|
Address: context.String("address"),
|
||||||
Duration: context.GlobalDuration("duration"),
|
Duration: context.Duration("duration"),
|
||||||
Concurrency: context.GlobalInt("concurrent"),
|
Concurrency: context.Int("concurrent"),
|
||||||
CRI: context.GlobalBool("cri"),
|
CRI: context.Bool("cri"),
|
||||||
Exec: context.GlobalBool("exec"),
|
Exec: context.Bool("exec"),
|
||||||
Image: context.GlobalString("image"),
|
Image: context.String("image"),
|
||||||
JSON: context.GlobalBool("json"),
|
JSON: context.Bool("json"),
|
||||||
Metrics: context.GlobalString("metrics"),
|
Metrics: context.String("metrics"),
|
||||||
Runtime: context.GlobalString("runtime"),
|
Runtime: context.String("runtime"),
|
||||||
Snapshotter: context.GlobalString("snapshotter"),
|
Snapshotter: context.String("snapshotter"),
|
||||||
}
|
}
|
||||||
if config.Metrics != "" {
|
if config.Metrics != "" {
|
||||||
return serve(config)
|
return serve(config)
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
"github.com/containerd/plugin/registry"
|
"github.com/containerd/plugin/registry"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error {
|
func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error {
|
||||||
@ -78,10 +78,10 @@ func defaultConfig() *srvconfig.Config {
|
|||||||
return platformAgnosticDefaultConfig()
|
return platformAgnosticDefaultConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
var configCommand = cli.Command{
|
var configCommand = &cli.Command{
|
||||||
Name: "config",
|
Name: "config",
|
||||||
Usage: "Information on the containerd config",
|
Usage: "Information on the containerd config",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
{
|
{
|
||||||
Name: "default",
|
Name: "default",
|
||||||
Usage: "See the output of the default config",
|
Usage: "See the output of the default config",
|
||||||
@ -95,7 +95,7 @@ var configCommand = cli.Command{
|
|||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
config := defaultConfig()
|
config := defaultConfig()
|
||||||
ctx := gocontext.Background()
|
ctx := gocontext.Background()
|
||||||
if err := srvconfig.LoadConfig(ctx, context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
if err := srvconfig.LoadConfig(ctx, context.String("config"), config); err != nil && !os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ var configCommand = cli.Command{
|
|||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
config := defaultConfig()
|
config := defaultConfig()
|
||||||
ctx := gocontext.Background()
|
ctx := gocontext.Background()
|
||||||
if err := srvconfig.LoadConfig(ctx, context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
if err := srvconfig.LoadConfig(ctx, context.String("config"), config); err != nil && !os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/version"
|
"github.com/containerd/containerd/v2/version"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -57,13 +57,15 @@ func init() {
|
|||||||
cli.VersionPrinter = func(c *cli.Context) {
|
cli.VersionPrinter = func(c *cli.Context) {
|
||||||
fmt.Println(c.App.Name, version.Package, c.App.Version, version.Revision)
|
fmt.Println(c.App.Name, version.Package, c.App.Version, version.Revision)
|
||||||
}
|
}
|
||||||
cli.VersionFlag = cli.BoolFlag{
|
cli.VersionFlag = &cli.BoolFlag{
|
||||||
Name: "version, v",
|
Name: "version",
|
||||||
Usage: "Print the version",
|
Aliases: []string{"v"},
|
||||||
|
Usage: "Print the version",
|
||||||
}
|
}
|
||||||
cli.HelpFlag = cli.BoolFlag{
|
cli.HelpFlag = &cli.BoolFlag{
|
||||||
Name: "help, h",
|
Name: "help",
|
||||||
Usage: "Show help",
|
Aliases: []string{"h"},
|
||||||
|
Usage: "Show help",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,30 +87,33 @@ at the default file location. The *containerd config* command can be used to
|
|||||||
generate the default configuration for containerd. The output of that command
|
generate the default configuration for containerd. The output of that command
|
||||||
can be used and modified as necessary as a custom configuration.`
|
can be used and modified as necessary as a custom configuration.`
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "config,c",
|
Name: "config",
|
||||||
Usage: "Path to the configuration file",
|
Aliases: []string{"c"},
|
||||||
Value: filepath.Join(defaults.DefaultConfigDir, "config.toml"),
|
Usage: "Path to the configuration file",
|
||||||
|
Value: filepath.Join(defaults.DefaultConfigDir, "config.toml"),
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "log-level,l",
|
Name: "log-level",
|
||||||
Usage: "Set the logging level [trace, debug, info, warn, error, fatal, panic]",
|
Aliases: []string{"l"},
|
||||||
|
Usage: "Set the logging level [trace, debug, info, warn, error, fatal, panic]",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "address,a",
|
Name: "address",
|
||||||
Usage: "Address for containerd's GRPC server",
|
Aliases: []string{"a"},
|
||||||
|
Usage: "Address for containerd's GRPC server",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Usage: "containerd root directory",
|
Usage: "containerd root directory",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "state",
|
Name: "state",
|
||||||
Usage: "containerd state directory",
|
Usage: "containerd state directory",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Flags = append(app.Flags, serviceFlags()...)
|
app.Flags = append(app.Flags, serviceFlags()...)
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []*cli.Command{
|
||||||
configCommand,
|
configCommand,
|
||||||
publishCommand,
|
publishCommand,
|
||||||
ociHook,
|
ociHook,
|
||||||
@ -126,9 +131,9 @@ can be used and modified as necessary as a custom configuration.`
|
|||||||
|
|
||||||
// Only try to load the config if it either exists, or the user explicitly
|
// Only try to load the config if it either exists, or the user explicitly
|
||||||
// told us to load this path.
|
// told us to load this path.
|
||||||
configPath := context.GlobalString("config")
|
configPath := context.String("config")
|
||||||
_, err := os.Stat(configPath)
|
_, err := os.Stat(configPath)
|
||||||
if !os.IsNotExist(err) || context.GlobalIsSet("config") {
|
if !os.IsNotExist(err) || context.IsSet("config") {
|
||||||
if err := srvconfig.LoadConfig(ctx, configPath, config); err != nil {
|
if err := srvconfig.LoadConfig(ctx, configPath, config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -336,7 +341,7 @@ func applyFlags(context *cli.Context, config *srvconfig.Config) error {
|
|||||||
d: &config.GRPC.Address,
|
d: &config.GRPC.Address,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
if s := context.GlobalString(v.name); s != "" {
|
if s := context.String(v.name); s != "" {
|
||||||
*v.d = s
|
*v.d = s
|
||||||
if v.name == "root" || v.name == "state" {
|
if v.name == "root" || v.name == "state" {
|
||||||
absPath, err := filepath.Abs(s)
|
absPath, err := filepath.Abs(s)
|
||||||
@ -354,7 +359,7 @@ func applyFlags(context *cli.Context, config *srvconfig.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setLogLevel(context *cli.Context, config *srvconfig.Config) error {
|
func setLogLevel(context *cli.Context, config *srvconfig.Config) error {
|
||||||
l := context.GlobalString("log-level")
|
l := context.String("log-level")
|
||||||
if l == "" {
|
if l == "" {
|
||||||
l = config.Debug.Level
|
l = config.Debug.Level
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,10 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/pkg/oci"
|
"github.com/containerd/containerd/v2/pkg/oci"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ociHook = cli.Command{
|
var ociHook = &cli.Command{
|
||||||
Name: "oci-hook",
|
Name: "oci-hook",
|
||||||
Usage: "Provides a base for OCI runtime hooks to allow arguments to be injected.",
|
Usage: "Provides a base for OCI runtime hooks to allow arguments to be injected.",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -45,7 +45,7 @@ var ociHook = cli.Command{
|
|||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
ctx = newTemplateContext(state, spec)
|
ctx = newTemplateContext(state, spec)
|
||||||
args = []string(context.Args())
|
args = context.Args().Slice()
|
||||||
env = os.Environ()
|
env = os.Environ()
|
||||||
)
|
)
|
||||||
if err := newList(&args).render(ctx); err != nil {
|
if err := newList(&args).render(ctx); err != nil {
|
||||||
|
@ -30,21 +30,21 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/protobuf/proto"
|
"github.com/containerd/containerd/v2/protobuf/proto"
|
||||||
"github.com/containerd/containerd/v2/protobuf/types"
|
"github.com/containerd/containerd/v2/protobuf/types"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/backoff"
|
"google.golang.org/grpc/backoff"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
)
|
)
|
||||||
|
|
||||||
var publishCommand = cli.Command{
|
var publishCommand = &cli.Command{
|
||||||
Name: "publish",
|
Name: "publish",
|
||||||
Usage: "Binary to publish events to containerd",
|
Usage: "Binary to publish events to containerd",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "namespace",
|
Name: "namespace",
|
||||||
Usage: "Namespace to publish to",
|
Usage: "Namespace to publish to",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "topic",
|
Name: "topic",
|
||||||
Usage: "Topic of the event",
|
Usage: "Topic of the event",
|
||||||
},
|
},
|
||||||
@ -59,7 +59,7 @@ var publishCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
client, err := connectEvents(context.GlobalString("address"))
|
client, err := connectEvents(context.String("address"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/v2/cmd/containerd/server"
|
"github.com/containerd/containerd/v2/cmd/containerd/server"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// serviceFlags returns an array of flags for configuring containerd to run
|
// serviceFlags returns an array of flags for configuring containerd to run
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/cmd/containerd/server"
|
"github.com/containerd/containerd/v2/cmd/containerd/server"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
"golang.org/x/sys/windows/svc"
|
"golang.org/x/sys/windows/svc"
|
||||||
"golang.org/x/sys/windows/svc/debug"
|
"golang.org/x/sys/windows/svc/debug"
|
||||||
@ -53,25 +53,25 @@ const defaultServiceName = "containerd"
|
|||||||
// as a Windows service under control of SCM.
|
// as a Windows service under control of SCM.
|
||||||
func serviceFlags() []cli.Flag {
|
func serviceFlags() []cli.Flag {
|
||||||
return []cli.Flag{
|
return []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "service-name",
|
Name: "service-name",
|
||||||
Usage: "Set the Windows service name",
|
Usage: "Set the Windows service name",
|
||||||
Value: defaultServiceName,
|
Value: defaultServiceName,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "register-service",
|
Name: "register-service",
|
||||||
Usage: "Register the service and exit",
|
Usage: "Register the service and exit",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "unregister-service",
|
Name: "unregister-service",
|
||||||
Usage: "Unregister the service and exit",
|
Usage: "Unregister the service and exit",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "run-service",
|
Name: "run-service",
|
||||||
Usage: "",
|
Usage: "",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "log-file",
|
Name: "log-file",
|
||||||
Usage: "Path to the containerd log file",
|
Usage: "Path to the containerd log file",
|
||||||
},
|
},
|
||||||
@ -80,7 +80,7 @@ func serviceFlags() []cli.Flag {
|
|||||||
|
|
||||||
// applyPlatformFlags applies platform-specific flags.
|
// applyPlatformFlags applies platform-specific flags.
|
||||||
func applyPlatformFlags(context *cli.Context) {
|
func applyPlatformFlags(context *cli.Context) {
|
||||||
serviceNameFlag = context.GlobalString("service-name")
|
serviceNameFlag = context.String("service-name")
|
||||||
if serviceNameFlag == "" {
|
if serviceNameFlag == "" {
|
||||||
serviceNameFlag = defaultServiceName
|
serviceNameFlag = defaultServiceName
|
||||||
}
|
}
|
||||||
@ -101,9 +101,9 @@ func applyPlatformFlags(context *cli.Context) {
|
|||||||
d: &runServiceFlag,
|
d: &runServiceFlag,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
*v.d = context.GlobalBool(v.name)
|
*v.d = context.Bool(v.name)
|
||||||
}
|
}
|
||||||
logFileFlag = context.GlobalString("log-file")
|
logFileFlag = context.String("log-file")
|
||||||
}
|
}
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands/containers"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands/containers"
|
||||||
@ -46,7 +46,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/version"
|
"github.com/containerd/containerd/v2/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var extraCmds = []cli.Command{}
|
var extraCmds = []*cli.Command{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Discard grpc logs so that they don't mess with our stdio
|
// Discard grpc logs so that they don't mess with our stdio
|
||||||
@ -55,13 +55,15 @@ func init() {
|
|||||||
cli.VersionPrinter = func(c *cli.Context) {
|
cli.VersionPrinter = func(c *cli.Context) {
|
||||||
fmt.Println(c.App.Name, version.Package, c.App.Version)
|
fmt.Println(c.App.Name, version.Package, c.App.Version)
|
||||||
}
|
}
|
||||||
cli.VersionFlag = cli.BoolFlag{
|
cli.VersionFlag = &cli.BoolFlag{
|
||||||
Name: "version, v",
|
Name: "version",
|
||||||
Usage: "Print the version",
|
Aliases: []string{"v"},
|
||||||
|
Usage: "Print the version",
|
||||||
}
|
}
|
||||||
cli.HelpFlag = cli.BoolFlag{
|
cli.HelpFlag = &cli.BoolFlag{
|
||||||
Name: "help, h",
|
Name: "help",
|
||||||
Usage: "Show help",
|
Aliases: []string{"h"},
|
||||||
|
Usage: "Show help",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,32 +88,34 @@ containerd CLI
|
|||||||
`
|
`
|
||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Enable debug output in logs",
|
Usage: "Enable debug output in logs",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "address, a",
|
Name: "address",
|
||||||
Usage: "Address for containerd's GRPC server",
|
Aliases: []string{"a"},
|
||||||
Value: defaults.DefaultAddress,
|
Usage: "Address for containerd's GRPC server",
|
||||||
EnvVar: "CONTAINERD_ADDRESS",
|
Value: defaults.DefaultAddress,
|
||||||
|
EnvVars: []string{"CONTAINERD_ADDRESS"},
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "timeout",
|
Name: "timeout",
|
||||||
Usage: "Total timeout for ctr commands",
|
Usage: "Total timeout for ctr commands",
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "connect-timeout",
|
Name: "connect-timeout",
|
||||||
Usage: "Timeout for connecting to containerd",
|
Usage: "Timeout for connecting to containerd",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "namespace, n",
|
Name: "namespace",
|
||||||
Usage: "Namespace to use with commands",
|
Aliases: []string{"n"},
|
||||||
Value: namespaces.Default,
|
Usage: "Namespace to use with commands",
|
||||||
EnvVar: namespaces.NamespaceEnvVar,
|
Value: namespaces.Default,
|
||||||
|
EnvVars: []string{namespaces.NamespaceEnvVar},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Commands = append([]cli.Command{
|
app.Commands = append([]*cli.Command{
|
||||||
plugins.Command,
|
plugins.Command,
|
||||||
versionCmd.Command,
|
versionCmd.Command,
|
||||||
containers.Command,
|
containers.Command,
|
||||||
@ -131,7 +135,7 @@ containerd CLI
|
|||||||
deprecations.Command,
|
deprecations.Command,
|
||||||
}, extraCmds...)
|
}, extraCmds...)
|
||||||
app.Before = func(context *cli.Context) error {
|
app.Before = func(context *cli.Context) error {
|
||||||
if context.GlobalBool("debug") {
|
if context.Bool("debug") {
|
||||||
return log.SetLevel("debug")
|
return log.SetLevel("debug")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/epoch"
|
"github.com/containerd/containerd/v2/pkg/epoch"
|
||||||
"github.com/containerd/containerd/v2/pkg/namespaces"
|
"github.com/containerd/containerd/v2/pkg/namespaces"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppContext returns the context for a command. Should only be called once per
|
// AppContext returns the context for a command. Should only be called once per
|
||||||
@ -34,8 +34,8 @@ import (
|
|||||||
func AppContext(context *cli.Context) (gocontext.Context, gocontext.CancelFunc) {
|
func AppContext(context *cli.Context) (gocontext.Context, gocontext.CancelFunc) {
|
||||||
var (
|
var (
|
||||||
ctx = gocontext.Background()
|
ctx = gocontext.Background()
|
||||||
timeout = context.GlobalDuration("timeout")
|
timeout = context.Duration("timeout")
|
||||||
namespace = context.GlobalString("namespace")
|
namespace = context.String("namespace")
|
||||||
cancel gocontext.CancelFunc
|
cancel gocontext.CancelFunc
|
||||||
)
|
)
|
||||||
ctx = namespaces.WithNamespace(ctx, namespace)
|
ctx = namespaces.WithNamespace(ctx, namespace)
|
||||||
@ -55,9 +55,9 @@ func AppContext(context *cli.Context) (gocontext.Context, gocontext.CancelFunc)
|
|||||||
|
|
||||||
// NewClient returns a new containerd client
|
// NewClient returns a new containerd client
|
||||||
func NewClient(context *cli.Context, opts ...containerd.Opt) (*containerd.Client, gocontext.Context, gocontext.CancelFunc, error) {
|
func NewClient(context *cli.Context, opts ...containerd.Opt) (*containerd.Client, gocontext.Context, gocontext.CancelFunc, error) {
|
||||||
timeoutOpt := containerd.WithTimeout(context.GlobalDuration("connect-timeout"))
|
timeoutOpt := containerd.WithTimeout(context.Duration("connect-timeout"))
|
||||||
opts = append(opts, timeoutOpt)
|
opts = append(opts, timeoutOpt)
|
||||||
client, err := containerd.New(context.GlobalString("address"), opts...)
|
client, err := containerd.New(context.String("address"), opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -26,71 +26,73 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/defaults"
|
"github.com/containerd/containerd/v2/defaults"
|
||||||
"github.com/containerd/containerd/v2/pkg/atomicfile"
|
"github.com/containerd/containerd/v2/pkg/atomicfile"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// SnapshotterFlags are cli flags specifying snapshotter names
|
// SnapshotterFlags are cli flags specifying snapshotter names
|
||||||
SnapshotterFlags = []cli.Flag{
|
SnapshotterFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "snapshotter",
|
Name: "snapshotter",
|
||||||
Usage: "Snapshotter name. Empty value stands for the default value.",
|
Usage: "Snapshotter name. Empty value stands for the default value.",
|
||||||
EnvVar: "CONTAINERD_SNAPSHOTTER",
|
EnvVars: []string{"CONTAINERD_SNAPSHOTTER"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotterLabels are cli flags specifying labels which will be added to the new snapshot for container.
|
// SnapshotterLabels are cli flags specifying labels which will be added to the new snapshot for container.
|
||||||
SnapshotterLabels = cli.StringSliceFlag{
|
SnapshotterLabels = &cli.StringSliceFlag{
|
||||||
Name: "snapshotter-label",
|
Name: "snapshotter-label",
|
||||||
Usage: "Labels added to the new snapshot for this container.",
|
Usage: "Labels added to the new snapshot for this container.",
|
||||||
}
|
}
|
||||||
|
|
||||||
// LabelFlag is a cli flag specifying labels
|
// LabelFlag is a cli flag specifying labels
|
||||||
LabelFlag = cli.StringSliceFlag{
|
LabelFlag = &cli.StringSliceFlag{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Labels to attach to the image",
|
Usage: "Labels to attach to the image",
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegistryFlags are cli flags specifying registry options
|
// RegistryFlags are cli flags specifying registry options
|
||||||
RegistryFlags = []cli.Flag{
|
RegistryFlags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-verify,k",
|
Name: "skip-verify",
|
||||||
Usage: "Skip SSL certificate validation",
|
Aliases: []string{"k"},
|
||||||
|
Usage: "Skip SSL certificate validation",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "plain-http",
|
Name: "plain-http",
|
||||||
Usage: "Allow connections using plain HTTP",
|
Usage: "Allow connections using plain HTTP",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "user,u",
|
Name: "user",
|
||||||
Usage: "User[:password] Registry user and password",
|
Aliases: []string{"u"},
|
||||||
|
Usage: "User[:password] Registry user and password",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "refresh",
|
Name: "refresh",
|
||||||
Usage: "Refresh token for authorization server",
|
Usage: "Refresh token for authorization server",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "hosts-dir",
|
Name: "hosts-dir",
|
||||||
// compatible with "/etc/docker/certs.d"
|
// compatible with "/etc/docker/certs.d"
|
||||||
Usage: "Custom hosts configuration directory",
|
Usage: "Custom hosts configuration directory",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "tlscacert",
|
Name: "tlscacert",
|
||||||
Usage: "Path to TLS root CA",
|
Usage: "Path to TLS root CA",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "tlscert",
|
Name: "tlscert",
|
||||||
Usage: "Path to TLS client certificate",
|
Usage: "Path to TLS client certificate",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "tlskey",
|
Name: "tlskey",
|
||||||
Usage: "Path to TLS client key",
|
Usage: "Path to TLS client key",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "http-dump",
|
Name: "http-dump",
|
||||||
Usage: "Dump all HTTP request/responses when interacting with container registry",
|
Usage: "Dump all HTTP request/responses when interacting with container registry",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "http-trace",
|
Name: "http-trace",
|
||||||
Usage: "Enable HTTP tracing for registry interactions",
|
Usage: "Enable HTTP tracing for registry interactions",
|
||||||
},
|
},
|
||||||
@ -98,12 +100,12 @@ var (
|
|||||||
|
|
||||||
// RuntimeFlags are cli flags specifying runtime
|
// RuntimeFlags are cli flags specifying runtime
|
||||||
RuntimeFlags = []cli.Flag{
|
RuntimeFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "runtime",
|
Name: "runtime",
|
||||||
Usage: "Runtime name or absolute path to runtime binary",
|
Usage: "Runtime name or absolute path to runtime binary",
|
||||||
Value: defaults.DefaultRuntime,
|
Value: defaults.DefaultRuntime,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "runtime-config-path",
|
Name: "runtime-config-path",
|
||||||
Usage: "Optional runtime config path",
|
Usage: "Optional runtime config path",
|
||||||
},
|
},
|
||||||
@ -111,117 +113,120 @@ var (
|
|||||||
|
|
||||||
// ContainerFlags are cli flags specifying container options
|
// ContainerFlags are cli flags specifying container options
|
||||||
ContainerFlags = []cli.Flag{
|
ContainerFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "config,c",
|
Name: "config",
|
||||||
Usage: "Path to the runtime-specific spec config file",
|
Aliases: []string{"c"},
|
||||||
|
Usage: "Path to the runtime-specific spec config file",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cwd",
|
Name: "cwd",
|
||||||
Usage: "Specify the working directory of the process",
|
Usage: "Specify the working directory of the process",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "env",
|
Name: "env",
|
||||||
Usage: "Specify additional container environment variables (e.g. FOO=bar)",
|
Usage: "Specify additional container environment variables (e.g. FOO=bar)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "env-file",
|
Name: "env-file",
|
||||||
Usage: "Specify additional container environment variables in a file(e.g. FOO=bar, one per line)",
|
Usage: "Specify additional container environment variables in a file(e.g. FOO=bar, one per line)",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Specify additional labels (e.g. foo=bar)",
|
Usage: "Specify additional labels (e.g. foo=bar)",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "annotation",
|
Name: "annotation",
|
||||||
Usage: "Specify additional OCI annotations (e.g. foo=bar)",
|
Usage: "Specify additional OCI annotations (e.g. foo=bar)",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "mount",
|
Name: "mount",
|
||||||
Usage: "Specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)",
|
Usage: "Specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "net-host",
|
Name: "net-host",
|
||||||
Usage: "Enable host networking for the container",
|
Usage: "Enable host networking for the container",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "privileged",
|
Name: "privileged",
|
||||||
Usage: "Run privileged container",
|
Usage: "Run privileged container",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "read-only",
|
Name: "read-only",
|
||||||
Usage: "Set the containers filesystem as readonly",
|
Usage: "Set the containers filesystem as readonly",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "sandbox",
|
Name: "sandbox",
|
||||||
Usage: "Create the container in the given sandbox",
|
Usage: "Create the container in the given sandbox",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "tty,t",
|
Name: "tty",
|
||||||
Usage: "Allocate a TTY for the container",
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Allocate a TTY for the container",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "with-ns",
|
Name: "with-ns",
|
||||||
Usage: "Specify existing Linux namespaces to join at container runtime (format '<nstype>:<path>')",
|
Usage: "Specify existing Linux namespaces to join at container runtime (format '<nstype>:<path>')",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "pid-file",
|
Name: "pid-file",
|
||||||
Usage: "File path to write the task's pid",
|
Usage: "File path to write the task's pid",
|
||||||
},
|
},
|
||||||
cli.IntSliceFlag{
|
&cli.IntSliceFlag{
|
||||||
Name: "gpus",
|
Name: "gpus",
|
||||||
Usage: "Add gpus to the container",
|
Usage: "Add gpus to the container",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "allow-new-privs",
|
Name: "allow-new-privs",
|
||||||
Usage: "Turn off OCI spec's NoNewPrivileges feature flag",
|
Usage: "Turn off OCI spec's NoNewPrivileges feature flag",
|
||||||
},
|
},
|
||||||
cli.Uint64Flag{
|
&cli.Uint64Flag{
|
||||||
Name: "memory-limit",
|
Name: "memory-limit",
|
||||||
Usage: "Memory limit (in bytes) for the container",
|
Usage: "Memory limit (in bytes) for the container",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "cap-add",
|
Name: "cap-add",
|
||||||
Usage: "Add Linux capabilities (Set capabilities with 'CAP_' prefix)",
|
Usage: "Add Linux capabilities (Set capabilities with 'CAP_' prefix)",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "cap-drop",
|
Name: "cap-drop",
|
||||||
Usage: "Drop Linux capabilities (Set capabilities with 'CAP_' prefix)",
|
Usage: "Drop Linux capabilities (Set capabilities with 'CAP_' prefix)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "seccomp",
|
Name: "seccomp",
|
||||||
Usage: "Enable the default seccomp profile",
|
Usage: "Enable the default seccomp profile",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "seccomp-profile",
|
Name: "seccomp-profile",
|
||||||
Usage: "File path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile",
|
Usage: "File path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "apparmor-default-profile",
|
Name: "apparmor-default-profile",
|
||||||
Usage: "Enable AppArmor with the default profile with the specified name, e.g. \"cri-containerd.apparmor.d\"",
|
Usage: "Enable AppArmor with the default profile with the specified name, e.g. \"cri-containerd.apparmor.d\"",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "apparmor-profile",
|
Name: "apparmor-profile",
|
||||||
Usage: "Enable AppArmor with an existing custom profile",
|
Usage: "Enable AppArmor with an existing custom profile",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "blockio-config-file",
|
Name: "blockio-config-file",
|
||||||
Usage: "File path to blockio class definitions. By default class definitions are not loaded.",
|
Usage: "File path to blockio class definitions. By default class definitions are not loaded.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "blockio-class",
|
Name: "blockio-class",
|
||||||
Usage: "Name of the blockio class to associate the container with",
|
Usage: "Name of the blockio class to associate the container with",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "rdt-class",
|
Name: "rdt-class",
|
||||||
Usage: "Name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.",
|
Usage: "Name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "hostname",
|
Name: "hostname",
|
||||||
Usage: "Set the container's host name",
|
Usage: "Set the container's host name",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "user,u",
|
Name: "user",
|
||||||
Usage: "Username or user id, group optional (format: <name|uid>[:<group|gid>])",
|
Aliases: []string{"u"},
|
||||||
|
Usage: "Username or user id, group optional (format: <name|uid>[:<group|gid>])",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -23,37 +23,37 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
||||||
runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
|
runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RuntimeFlags = append(RuntimeFlags, cli.StringFlag{
|
RuntimeFlags = append(RuntimeFlags, &cli.StringFlag{
|
||||||
Name: "runc-binary",
|
Name: "runc-binary",
|
||||||
Usage: "Specify runc-compatible binary",
|
Usage: "Specify runc-compatible binary",
|
||||||
}, cli.StringFlag{
|
}, &cli.StringFlag{
|
||||||
Name: "runc-root",
|
Name: "runc-root",
|
||||||
Usage: "Specify runc-compatible root",
|
Usage: "Specify runc-compatible root",
|
||||||
}, cli.BoolFlag{
|
}, &cli.BoolFlag{
|
||||||
Name: "runc-systemd-cgroup",
|
Name: "runc-systemd-cgroup",
|
||||||
Usage: "Start runc with systemd cgroup manager",
|
Usage: "Start runc with systemd cgroup manager",
|
||||||
})
|
})
|
||||||
ContainerFlags = append(ContainerFlags, cli.BoolFlag{
|
ContainerFlags = append(ContainerFlags, &cli.BoolFlag{
|
||||||
Name: "rootfs",
|
Name: "rootfs",
|
||||||
Usage: "Use custom rootfs that is not managed by containerd snapshotter",
|
Usage: "Use custom rootfs that is not managed by containerd snapshotter",
|
||||||
}, cli.BoolFlag{
|
}, &cli.BoolFlag{
|
||||||
Name: "no-pivot",
|
Name: "no-pivot",
|
||||||
Usage: "Disable use of pivot-root (linux only)",
|
Usage: "Disable use of pivot-root (linux only)",
|
||||||
}, cli.Int64Flag{
|
}, &cli.Int64Flag{
|
||||||
Name: "cpu-quota",
|
Name: "cpu-quota",
|
||||||
Usage: "Limit CPU CFS quota",
|
Usage: "Limit CPU CFS quota",
|
||||||
Value: -1,
|
Value: -1,
|
||||||
}, cli.Uint64Flag{
|
}, &cli.Uint64Flag{
|
||||||
Name: "cpu-period",
|
Name: "cpu-period",
|
||||||
Usage: "Limit CPU CFS period",
|
Usage: "Limit CPU CFS period",
|
||||||
}, cli.StringFlag{
|
}, &cli.StringFlag{
|
||||||
Name: "rootfs-propagation",
|
Name: "rootfs-propagation",
|
||||||
Usage: "Set the propagation of the container rootfs",
|
Usage: "Set the propagation of the container rootfs",
|
||||||
}, cli.StringSliceFlag{
|
}, &cli.StringSliceFlag{
|
||||||
Name: "device",
|
Name: "device",
|
||||||
Usage: "File path to a device to add to the container; or a path to a directory tree of devices to add to the container",
|
Usage: "File path to a device to add to the container; or a path to a directory tree of devices to add to the container",
|
||||||
})
|
})
|
||||||
|
@ -17,23 +17,21 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
ContainerFlags = append(ContainerFlags,
|
ContainerFlags = append(ContainerFlags,
|
||||||
cli.Uint64Flag{
|
&cli.Uint64Flag{
|
||||||
Name: "cpu-count",
|
Name: "cpu-count",
|
||||||
Usage: "Number of CPUs available to the container",
|
Usage: "Number of CPUs available to the container",
|
||||||
},
|
}, &cli.Uint64Flag{
|
||||||
cli.Uint64Flag{
|
|
||||||
Name: "cpu-shares",
|
Name: "cpu-shares",
|
||||||
Usage: "The relative number of CPU shares given to the container relative to other workloads. Between 0 and 10,000.",
|
Usage: "The relative number of CPU shares given to the container relative to other workloads. Between 0 and 10,000.",
|
||||||
},
|
}, &cli.Uint64Flag{
|
||||||
cli.Uint64Flag{
|
|
||||||
Name: "cpu-max",
|
Name: "cpu-max",
|
||||||
Usage: "The number of processor cycles threads in a container can use per 10,000 cycles. Set to a percentage times 100. Between 1 and 10,000",
|
Usage: "The number of processor cycles threads in a container can use per 10,000 cycles. Set to a percentage times 100. Between 1 and 10,000",
|
||||||
}, cli.StringSliceFlag{
|
}, &cli.StringSliceFlag{
|
||||||
Name: "device",
|
Name: "device",
|
||||||
Usage: "Identifier of a device to add to the container (e.g. class://5B45201D-F2F2-4F3B-85BB-30FF1F953599)",
|
Usage: "Identifier of a device to add to the container (e.g. class://5B45201D-F2F2-4F3B-85BB-30FF1F953599)",
|
||||||
})
|
})
|
||||||
|
@ -23,23 +23,23 @@ import (
|
|||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkpointCommand = cli.Command{
|
var checkpointCommand = &cli.Command{
|
||||||
Name: "checkpoint",
|
Name: "checkpoint",
|
||||||
Usage: "Checkpoint a container",
|
Usage: "Checkpoint a container",
|
||||||
ArgsUsage: "CONTAINER REF",
|
ArgsUsage: "CONTAINER REF",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "rw",
|
Name: "rw",
|
||||||
Usage: "Include the rw layer in the checkpoint",
|
Usage: "Include the rw layer in the checkpoint",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "image",
|
Name: "image",
|
||||||
Usage: "Include the image in the checkpoint",
|
Usage: "Include the image in the checkpoint",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "task",
|
Name: "task",
|
||||||
Usage: "Checkpoint container task",
|
Usage: "Checkpoint container task",
|
||||||
},
|
},
|
||||||
|
@ -31,15 +31,15 @@ import (
|
|||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for managing containers
|
// Command is the cli command for managing containers
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "containers",
|
Name: "containers",
|
||||||
Usage: "Manage containers",
|
Usage: "Manage containers",
|
||||||
Aliases: []string{"c", "container"},
|
Aliases: []string{"c", "container"},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
createCommand,
|
createCommand,
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
infoCommand,
|
infoCommand,
|
||||||
@ -50,12 +50,11 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var createCommand = cli.Command{
|
var createCommand = &cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Usage: "Create container",
|
Usage: "Create container",
|
||||||
ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]",
|
ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]",
|
||||||
SkipArgReorder: true,
|
Flags: append(commands.RuntimeFlags, append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...)...),
|
||||||
Flags: append(commands.RuntimeFlags, append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...)...),
|
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
id string
|
id string
|
||||||
@ -91,20 +90,21 @@ var createCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List containers",
|
Usage: "List containers",
|
||||||
ArgsUsage: "[flags] [<filter>, ...]",
|
ArgsUsage: "[flags] [<filter>, ...]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the container id",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the container id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
filters = context.Args()
|
filters = context.Args().Slice()
|
||||||
quiet = context.Bool("quiet")
|
quiet = context.Bool("quiet")
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
@ -145,13 +145,13 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var deleteCommand = cli.Command{
|
var deleteCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "Delete one or more existing containers",
|
Usage: "Delete one or more existing containers",
|
||||||
ArgsUsage: "[flags] CONTAINER [CONTAINER, ...]",
|
ArgsUsage: "[flags] CONTAINER [CONTAINER, ...]",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "keep-snapshot",
|
Name: "keep-snapshot",
|
||||||
Usage: "Do not clean up snapshot with container",
|
Usage: "Do not clean up snapshot with container",
|
||||||
},
|
},
|
||||||
@ -171,7 +171,7 @@ var deleteCommand = cli.Command{
|
|||||||
if context.NArg() == 0 {
|
if context.NArg() == 0 {
|
||||||
return fmt.Errorf("must specify at least one container to delete: %w", errdefs.ErrInvalidArgument)
|
return fmt.Errorf("must specify at least one container to delete: %w", errdefs.ErrInvalidArgument)
|
||||||
}
|
}
|
||||||
for _, arg := range context.Args() {
|
for _, arg := range context.Args().Slice() {
|
||||||
if err := deleteContainer(ctx, client, arg, deleteOpts...); err != nil {
|
if err := deleteContainer(ctx, client, arg, deleteOpts...); err != nil {
|
||||||
if exitErr == nil {
|
if exitErr == nil {
|
||||||
exitErr = err
|
exitErr = err
|
||||||
@ -206,7 +206,7 @@ func deleteContainer(ctx context.Context, client *containerd.Client, id string,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var setLabelsCommand = cli.Command{
|
var setLabelsCommand = &cli.Command{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Set and clear labels for a container",
|
Usage: "Set and clear labels for a container",
|
||||||
ArgsUsage: "[flags] CONTAINER [<key>=<value>, ...]",
|
ArgsUsage: "[flags] CONTAINER [<key>=<value>, ...]",
|
||||||
@ -244,12 +244,12 @@ var setLabelsCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var infoCommand = cli.Command{
|
var infoCommand = &cli.Command{
|
||||||
Name: "info",
|
Name: "info",
|
||||||
Usage: "Get info about a container",
|
Usage: "Get info about a container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "spec",
|
Name: "spec",
|
||||||
Usage: "Only display the spec",
|
Usage: "Only display the spec",
|
||||||
},
|
},
|
||||||
|
@ -26,19 +26,19 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var restoreCommand = cli.Command{
|
var restoreCommand = &cli.Command{
|
||||||
Name: "restore",
|
Name: "restore",
|
||||||
Usage: "Restore a container from checkpoint",
|
Usage: "Restore a container from checkpoint",
|
||||||
ArgsUsage: "CONTAINER REF",
|
ArgsUsage: "CONTAINER REF",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "rw",
|
Name: "rw",
|
||||||
Usage: "Restore the rw layer from the checkpoint",
|
Usage: "Restore the rw layer from the checkpoint",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "live",
|
Name: "live",
|
||||||
Usage: "Restore the runtime and memory data from the checkpoint",
|
Usage: "Restore the runtime and memory data from the checkpoint",
|
||||||
},
|
},
|
||||||
@ -136,7 +136,7 @@ var restoreCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return cli.NewExitError("", int(code))
|
return cli.Exit("", int(code))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -35,12 +35,12 @@ import (
|
|||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Command is the cli command for managing content
|
// Command is the cli command for managing content
|
||||||
Command = cli.Command{
|
Command = &cli.Command{
|
||||||
Name: "content",
|
Name: "content",
|
||||||
Usage: "Manage content",
|
Usage: "Manage content",
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
@ -59,7 +59,7 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
getCommand = cli.Command{
|
getCommand = &cli.Command{
|
||||||
Name: "get",
|
Name: "get",
|
||||||
Usage: "Get the data for an object",
|
Usage: "Get the data for an object",
|
||||||
ArgsUsage: "[<digest>, ...]",
|
ArgsUsage: "[<digest>, ...]",
|
||||||
@ -88,17 +88,17 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ingestCommand = cli.Command{
|
ingestCommand = &cli.Command{
|
||||||
Name: "ingest",
|
Name: "ingest",
|
||||||
Usage: "Accept content into the store",
|
Usage: "Accept content into the store",
|
||||||
ArgsUsage: "[flags] <key>",
|
ArgsUsage: "[flags] <key>",
|
||||||
Description: "ingest objects into the local content store",
|
Description: "ingest objects into the local content store",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.Int64Flag{
|
&cli.Int64Flag{
|
||||||
Name: "expected-size",
|
Name: "expected-size",
|
||||||
Usage: "Validate against provided size",
|
Usage: "Validate against provided size",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "expected-digest",
|
Name: "expected-digest",
|
||||||
Usage: "Verify content against expected digest",
|
Usage: "Verify content against expected digest",
|
||||||
},
|
},
|
||||||
@ -130,18 +130,19 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
activeIngestCommand = cli.Command{
|
activeIngestCommand = &cli.Command{
|
||||||
Name: "active",
|
Name: "active",
|
||||||
Usage: "Display active transfers",
|
Usage: "Display active transfers",
|
||||||
ArgsUsage: "[flags] [<regexp>]",
|
ArgsUsage: "[flags] [<regexp>]",
|
||||||
Description: "display the ongoing transfers",
|
Description: "display the ongoing transfers",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "timeout, t",
|
Name: "timeout",
|
||||||
Usage: "Total timeout for fetch",
|
Aliases: []string{"t"},
|
||||||
EnvVar: "CONTAINERD_FETCH_TIMEOUT",
|
Usage: "Total timeout for fetch",
|
||||||
|
EnvVars: []string{"CONTAINERD_FETCH_TIMEOUT"},
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Usage: "Path to content store root",
|
Usage: "Path to content store root",
|
||||||
Value: "/tmp/content", // TODO(stevvooe): for now, just use the PWD/.content
|
Value: "/tmp/content", // TODO(stevvooe): for now, just use the PWD/.content
|
||||||
@ -172,22 +173,23 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
listCommand = cli.Command{
|
listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List all blobs in the store",
|
Usage: "List all blobs in the store",
|
||||||
ArgsUsage: "[flags]",
|
ArgsUsage: "[flags]",
|
||||||
Description: "list blobs in the content store",
|
Description: "list blobs in the content store",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the blob digest",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the blob digest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
quiet = context.Bool("quiet")
|
quiet = context.Bool("quiet")
|
||||||
args = []string(context.Args())
|
args = context.Args().Slice()
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -232,7 +234,7 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
setLabelsCommand = cli.Command{
|
setLabelsCommand = &cli.Command{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Add labels to content",
|
Usage: "Add labels to content",
|
||||||
ArgsUsage: "<digest> [<label>=<value> ...]",
|
ArgsUsage: "<digest> [<label>=<value> ...]",
|
||||||
@ -286,20 +288,20 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
editCommand = cli.Command{
|
editCommand = &cli.Command{
|
||||||
Name: "edit",
|
Name: "edit",
|
||||||
Usage: "Edit a blob and return a new digest",
|
Usage: "Edit a blob and return a new digest",
|
||||||
ArgsUsage: "[flags] <digest>",
|
ArgsUsage: "[flags] <digest>",
|
||||||
Description: "edit a blob and return a new digest",
|
Description: "edit a blob and return a new digest",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "validate",
|
Name: "validate",
|
||||||
Usage: "Validate the result against a format (json, mediatype, etc.)",
|
Usage: "Validate the result against a format (json, mediatype, etc.)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "editor",
|
Name: "editor",
|
||||||
Usage: "Select editor (vim, emacs, etc.)",
|
Usage: "Select editor (vim, emacs, etc.)",
|
||||||
EnvVar: "EDITOR",
|
EnvVars: []string{"EDITOR"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -355,7 +357,7 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCommand = cli.Command{
|
deleteCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
Usage: "Permanently delete one or more blobs",
|
Usage: "Permanently delete one or more blobs",
|
||||||
@ -364,7 +366,7 @@ var (
|
|||||||
blobs are printed to stdout.`,
|
blobs are printed to stdout.`,
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
args = []string(context.Args())
|
args = context.Args().Slice()
|
||||||
exitError error
|
exitError error
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
@ -404,7 +406,7 @@ var (
|
|||||||
// TODO(stevvooe): Create "multi-fetch" mode that just takes a remote
|
// TODO(stevvooe): Create "multi-fetch" mode that just takes a remote
|
||||||
// then receives object/hint lines on stdin, returning content as
|
// then receives object/hint lines on stdin, returning content as
|
||||||
// needed.
|
// needed.
|
||||||
fetchObjectCommand = cli.Command{
|
fetchObjectCommand = &cli.Command{
|
||||||
Name: "fetch-object",
|
Name: "fetch-object",
|
||||||
Usage: "Retrieve objects from a remote",
|
Usage: "Retrieve objects from a remote",
|
||||||
ArgsUsage: "[flags] <remote> <object> [<hint>, ...]",
|
ArgsUsage: "[flags] <remote> <object> [<hint>, ...]",
|
||||||
@ -446,13 +448,13 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchBlobCommand = cli.Command{
|
fetchBlobCommand = &cli.Command{
|
||||||
Name: "fetch-blob",
|
Name: "fetch-blob",
|
||||||
Usage: "Retrieve blobs from a remote",
|
Usage: "Retrieve blobs from a remote",
|
||||||
ArgsUsage: "[flags] <remote> [<digest>, ...]",
|
ArgsUsage: "[flags] <remote> [<digest>, ...]",
|
||||||
Description: `Fetch blobs by digests from a remote.`,
|
Description: `Fetch blobs by digests from a remote.`,
|
||||||
Flags: append(commands.RegistryFlags, []cli.Flag{
|
Flags: append(commands.RegistryFlags, []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "media-type",
|
Name: "media-type",
|
||||||
Usage: "Specify target mediatype for request header",
|
Usage: "Specify target mediatype for request header",
|
||||||
},
|
},
|
||||||
@ -506,7 +508,7 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pushObjectCommand = cli.Command{
|
pushObjectCommand = &cli.Command{
|
||||||
Name: "push-object",
|
Name: "push-object",
|
||||||
Usage: "Push an object to a remote",
|
Usage: "Push an object to a remote",
|
||||||
ArgsUsage: "[flags] <remote> <object> <type>",
|
ArgsUsage: "[flags] <remote> <object> <type>",
|
||||||
|
@ -37,10 +37,10 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fetchCommand = cli.Command{
|
var fetchCommand = &cli.Command{
|
||||||
Name: "fetch",
|
Name: "fetch",
|
||||||
Usage: "Fetch all content for an image into containerd",
|
Usage: "Fetch all content for an image into containerd",
|
||||||
ArgsUsage: "[flags] <remote> <object>",
|
ArgsUsage: "[flags] <remote> <object>",
|
||||||
@ -59,24 +59,24 @@ content and snapshots ready for a direct use via the 'ctr run'.
|
|||||||
|
|
||||||
Most of this is experimental and there are few leaps to make this work.`,
|
Most of this is experimental and there are few leaps to make this work.`,
|
||||||
Flags: append(commands.RegistryFlags, commands.LabelFlag,
|
Flags: append(commands.RegistryFlags, commands.LabelFlag,
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Pull content from a specific platform",
|
Usage: "Pull content from a specific platform",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "Pull content from all platforms",
|
Usage: "Pull content from all platforms",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-metadata",
|
Name: "all-metadata",
|
||||||
Usage: "(Deprecated: use skip-metadata) Pull metadata for all platforms",
|
Usage: "(Deprecated: use skip-metadata) Pull metadata for all platforms",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-metadata",
|
Name: "skip-metadata",
|
||||||
Usage: "Skips metadata for unused platforms (Image may be unable to be pushed without metadata)",
|
Usage: "Skips metadata for unused platforms (Image may be unable to be pushed without metadata)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "metadata-only",
|
Name: "metadata-only",
|
||||||
Usage: "Pull all metadata including manifests and configs",
|
Usage: "Pull all metadata including manifests and configs",
|
||||||
},
|
},
|
||||||
@ -131,7 +131,7 @@ func NewFetchConfig(ctx context.Context, clicontext *cli.Context) (*FetchConfig,
|
|||||||
Labels: clicontext.StringSlice("label"),
|
Labels: clicontext.StringSlice("label"),
|
||||||
TraceHTTP: clicontext.Bool("http-trace"),
|
TraceHTTP: clicontext.Bool("http-trace"),
|
||||||
}
|
}
|
||||||
if !clicontext.GlobalBool("debug") {
|
if !clicontext.Bool("debug") {
|
||||||
config.ProgressOutput = os.Stdout
|
config.ProgressOutput = os.Stdout
|
||||||
}
|
}
|
||||||
if !clicontext.Bool("all-platforms") {
|
if !clicontext.Bool("all-platforms") {
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/core/content"
|
"github.com/containerd/containerd/v2/core/content"
|
||||||
"github.com/containerd/containerd/v2/core/leases"
|
"github.com/containerd/containerd/v2/core/leases"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -34,17 +34,17 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var pruneFlags = []cli.Flag{
|
var pruneFlags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "async",
|
Name: "async",
|
||||||
Usage: "Allow garbage collection to cleanup asynchronously",
|
Usage: "Allow garbage collection to cleanup asynchronously",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "dry",
|
Name: "dry",
|
||||||
Usage: "Just show updates without applying (enables debug logging)",
|
Usage: "Just show updates without applying (enables debug logging)",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pruneCommand = cli.Command{
|
var pruneCommand = &cli.Command{
|
||||||
Name: "prune",
|
Name: "prune",
|
||||||
Usage: "Prunes content from the content store",
|
Usage: "Prunes content from the content store",
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
@ -52,7 +52,7 @@ var pruneCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pruneReferencesCommand = cli.Command{
|
var pruneReferencesCommand = &cli.Command{
|
||||||
Name: "references",
|
Name: "references",
|
||||||
Usage: "Prunes preference labels from the content store (layers only by default)",
|
Usage: "Prunes preference labels from the content store (layers only by default)",
|
||||||
Flags: pruneFlags,
|
Flags: pruneFlags,
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
|
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
@ -31,17 +31,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Command is the parent for all commands under "deprecations"
|
// Command is the parent for all commands under "deprecations"
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "deprecations",
|
Name: "deprecations",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
listCommand,
|
listCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Usage: "Print warnings for deprecations",
|
Usage: "Print warnings for deprecations",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Usage: "output format to use (Examples: 'default', 'json')",
|
Usage: "output format to use (Examples: 'default', 'json')",
|
||||||
},
|
},
|
||||||
|
@ -24,14 +24,14 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/events"
|
"github.com/containerd/containerd/v2/pkg/events"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
// Register grpc event types
|
// Register grpc event types
|
||||||
_ "github.com/containerd/containerd/v2/api/events"
|
_ "github.com/containerd/containerd/v2/api/events"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for displaying containerd events
|
// Command is the cli command for displaying containerd events
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "events",
|
Name: "events",
|
||||||
Aliases: []string{"event"},
|
Aliases: []string{"event"},
|
||||||
Usage: "Display containerd events",
|
Usage: "Display containerd events",
|
||||||
@ -42,7 +42,7 @@ var Command = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
eventsClient := client.EventService()
|
eventsClient := client.EventService()
|
||||||
eventsCh, errCh := eventsClient.Subscribe(ctx, context.Args()...)
|
eventsCh, errCh := eventsClient.Subscribe(ctx, context.Args().Slice()...)
|
||||||
for {
|
for {
|
||||||
var e *events.Envelope
|
var e *events.Envelope
|
||||||
select {
|
select {
|
||||||
|
@ -24,10 +24,10 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/core/images/converter"
|
"github.com/containerd/containerd/v2/core/images/converter"
|
||||||
"github.com/containerd/containerd/v2/core/images/converter/uncompress"
|
"github.com/containerd/containerd/v2/core/images/converter/uncompress"
|
||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var convertCommand = cli.Command{
|
var convertCommand = &cli.Command{
|
||||||
Name: "convert",
|
Name: "convert",
|
||||||
Usage: "Convert an image",
|
Usage: "Convert an image",
|
||||||
ArgsUsage: "[flags] <source_ref> <target_ref>",
|
ArgsUsage: "[flags] <source_ref> <target_ref>",
|
||||||
@ -40,21 +40,21 @@ When '--all-platforms' is given all images in a manifest list must be available.
|
|||||||
`,
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
// generic flags
|
// generic flags
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "uncompress",
|
Name: "uncompress",
|
||||||
Usage: "Convert tar.gz layers to uncompressed tar layers",
|
Usage: "Convert tar.gz layers to uncompressed tar layers",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "oci",
|
Name: "oci",
|
||||||
Usage: "Convert Docker media types to OCI media types",
|
Usage: "Convert Docker media types to OCI media types",
|
||||||
},
|
},
|
||||||
// platform flags
|
// platform flags
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Pull content from a specific platform",
|
Usage: "Pull content from a specific platform",
|
||||||
Value: &cli.StringSlice{},
|
Value: cli.NewStringSlice(),
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "Exports content from all platforms",
|
Usage: "Exports content from all platforms",
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/core/images/archive"
|
"github.com/containerd/containerd/v2/core/images/archive"
|
||||||
@ -32,7 +32,7 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
)
|
)
|
||||||
|
|
||||||
var exportCommand = cli.Command{
|
var exportCommand = &cli.Command{
|
||||||
Name: "export",
|
Name: "export",
|
||||||
Usage: "Export images",
|
Usage: "Export images",
|
||||||
ArgsUsage: "[flags] <out> <image> ...",
|
ArgsUsage: "[flags] <out> <image> ...",
|
||||||
@ -44,24 +44,24 @@ Use '--platform' to define the output platform.
|
|||||||
When '--all-platforms' is given all images in a manifest list must be available.
|
When '--all-platforms' is given all images in a manifest list must be available.
|
||||||
`,
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-manifest-json",
|
Name: "skip-manifest-json",
|
||||||
Usage: "Do not add Docker compatible manifest.json to archive",
|
Usage: "Do not add Docker compatible manifest.json to archive",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-non-distributable",
|
Name: "skip-non-distributable",
|
||||||
Usage: "Do not add non-distributable blobs such as Windows layers to archive",
|
Usage: "Do not add non-distributable blobs such as Windows layers to archive",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Pull content from a specific platform",
|
Usage: "Pull content from a specific platform",
|
||||||
Value: &cli.StringSlice{},
|
Value: cli.NewStringSlice(),
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "Exports content from all platforms",
|
Usage: "Exports content from all platforms",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Usage: "Run export locally rather than through transfer API",
|
Usage: "Run export locally rather than through transfer API",
|
||||||
},
|
},
|
||||||
|
@ -30,11 +30,11 @@ import (
|
|||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for managing images
|
// Command is the cli command for managing images
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "images",
|
Name: "images",
|
||||||
Aliases: []string{"image", "i"},
|
Aliases: []string{"image", "i"},
|
||||||
Usage: "Manage images",
|
Usage: "Manage images",
|
||||||
@ -57,21 +57,22 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List images known to containerd",
|
Usage: "List images known to containerd",
|
||||||
ArgsUsage: "[flags] [<filter>, ...]",
|
ArgsUsage: "[flags] [<filter>, ...]",
|
||||||
Description: "list images registered with containerd",
|
Description: "list images registered with containerd",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the image refs",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the image refs",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
filters = context.Args()
|
filters = context.Args().Slice()
|
||||||
quiet = context.Bool("quiet")
|
quiet = context.Bool("quiet")
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
@ -141,15 +142,16 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var setLabelsCommand = cli.Command{
|
var setLabelsCommand = &cli.Command{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Set and clear labels for an image",
|
Usage: "Set and clear labels for an image",
|
||||||
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
|
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
|
||||||
Description: "set and clear labels for an image",
|
Description: "set and clear labels for an image",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "replace-all, r",
|
Name: "replace-all",
|
||||||
Usage: "Replace all labels",
|
Aliases: []string{"r"},
|
||||||
|
Usage: "Replace all labels",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -200,15 +202,16 @@ var setLabelsCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkCommand = cli.Command{
|
var checkCommand = &cli.Command{
|
||||||
Name: "check",
|
Name: "check",
|
||||||
Usage: "Check existing images to ensure all content is available locally",
|
Usage: "Check existing images to ensure all content is available locally",
|
||||||
ArgsUsage: "[flags] [<filter>, ...]",
|
ArgsUsage: "[flags] [<filter>, ...]",
|
||||||
Description: "check existing images to ensure all content is available locally",
|
Description: "check existing images to ensure all content is available locally",
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the ready image refs (fully downloaded and unpacked)",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the ready image refs (fully downloaded and unpacked)",
|
||||||
},
|
},
|
||||||
}, commands.SnapshotterFlags...),
|
}, commands.SnapshotterFlags...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -224,7 +227,7 @@ var checkCommand = cli.Command{
|
|||||||
|
|
||||||
var contentStore = client.ContentStore()
|
var contentStore = client.ContentStore()
|
||||||
|
|
||||||
args := []string(context.Args())
|
args := context.Args().Slice()
|
||||||
imageList, err := client.ListImages(ctx, args...)
|
imageList, err := client.ListImages(ctx, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed listing images: %w", err)
|
return fmt.Errorf("failed listing images: %w", err)
|
||||||
@ -313,14 +316,14 @@ var checkCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeCommand = cli.Command{
|
var removeCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
Usage: "Remove one or more images by reference",
|
Usage: "Remove one or more images by reference",
|
||||||
ArgsUsage: "[flags] <ref> [<ref>, ...]",
|
ArgsUsage: "[flags] <ref> [<ref>, ...]",
|
||||||
Description: "remove one or more images by reference",
|
Description: "remove one or more images by reference",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Usage: "Synchronously remove image and all associated resources",
|
Usage: "Synchronously remove image and all associated resources",
|
||||||
},
|
},
|
||||||
@ -335,7 +338,7 @@ var removeCommand = cli.Command{
|
|||||||
exitErr error
|
exitErr error
|
||||||
imageStore = client.ImageService()
|
imageStore = client.ImageService()
|
||||||
)
|
)
|
||||||
for i, target := range context.Args() {
|
for i, target := range context.Args().Slice() {
|
||||||
var opts []images.DeleteOpt
|
var opts []images.DeleteOpt
|
||||||
if context.Bool("sync") && i == context.NArg()-1 {
|
if context.Bool("sync") && i == context.NArg()-1 {
|
||||||
opts = append(opts, images.SynchronousDelete())
|
opts = append(opts, images.SynchronousDelete())
|
||||||
@ -359,11 +362,11 @@ var removeCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pruneCommand = cli.Command{
|
var pruneCommand = &cli.Command{
|
||||||
Name: "prune",
|
Name: "prune",
|
||||||
Usage: "Remove unused images",
|
Usage: "Remove unused images",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all", // TODO: add more filters
|
Name: "all", // TODO: add more filters
|
||||||
Usage: "Remove all unused images, not just dangling ones (if all is not specified no images will be pruned)",
|
Usage: "Remove all unused images, not just dangling ones (if all is not specified no images will be pruned)",
|
||||||
},
|
},
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
@ -35,7 +35,7 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
)
|
)
|
||||||
|
|
||||||
var importCommand = cli.Command{
|
var importCommand = &cli.Command{
|
||||||
Name: "import",
|
Name: "import",
|
||||||
Usage: "Import images",
|
Usage: "Import images",
|
||||||
ArgsUsage: "[flags] <in>",
|
ArgsUsage: "[flags] <in>",
|
||||||
@ -57,44 +57,44 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
|
|||||||
"foo/bar:latest" and "foo/bar@sha256:deadbeef" images in the containerd store.
|
"foo/bar:latest" and "foo/bar@sha256:deadbeef" images in the containerd store.
|
||||||
`,
|
`,
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "base-name",
|
Name: "base-name",
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "Base image name for added images, when provided only images with this name prefix are imported",
|
Usage: "Base image name for added images, when provided only images with this name prefix are imported",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "digests",
|
Name: "digests",
|
||||||
Usage: "Whether to create digest images (default: false)",
|
Usage: "Whether to create digest images (default: false)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-digest-for-named",
|
Name: "skip-digest-for-named",
|
||||||
Usage: "Skip applying --digests option to images named in the importing tar (use it in conjunction with --digests)",
|
Usage: "Skip applying --digests option to images named in the importing tar (use it in conjunction with --digests)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "index-name",
|
Name: "index-name",
|
||||||
Usage: "Image name to keep index as, by default index is discarded",
|
Usage: "Image name to keep index as, by default index is discarded",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "Imports content for all platforms, false by default",
|
Usage: "Imports content for all platforms, false by default",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Imports content for specific platform",
|
Usage: "Imports content for specific platform",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "no-unpack",
|
Name: "no-unpack",
|
||||||
Usage: "Skip unpacking the images, cannot be used with --discard-unpacked-layers, false by default",
|
Usage: "Skip unpacking the images, cannot be used with --discard-unpacked-layers, false by default",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Usage: "Run import locally rather than through transfer API",
|
Usage: "Run import locally rather than through transfer API",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "compress-blobs",
|
Name: "compress-blobs",
|
||||||
Usage: "Compress uncompressed blobs when creating manifest (Docker format only)",
|
Usage: "Compress uncompressed blobs when creating manifest (Docker format only)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "discard-unpacked-layers",
|
Name: "discard-unpacked-layers",
|
||||||
Usage: "Allow the garbage collector to clean layers up from the content store after unpacking, cannot be used with --no-unpack, false by default",
|
Usage: "Allow the garbage collector to clean layers up from the content store after unpacking, cannot be used with --no-unpack, false by default",
|
||||||
},
|
},
|
||||||
|
@ -21,17 +21,17 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/pkg/display"
|
"github.com/containerd/containerd/v2/pkg/display"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var inspectCommand = cli.Command{
|
var inspectCommand = &cli.Command{
|
||||||
Name: "inspect",
|
Name: "inspect",
|
||||||
Aliases: []string{"i"},
|
Aliases: []string{"i"},
|
||||||
Usage: "inspect an image",
|
Usage: "inspect an image",
|
||||||
ArgsUsage: "<image> [flags]",
|
ArgsUsage: "<image> [flags]",
|
||||||
Description: `Inspect an image`,
|
Description: `Inspect an image`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "content",
|
Name: "content",
|
||||||
Usage: "Show JSON content",
|
Usage: "Show JSON content",
|
||||||
},
|
},
|
||||||
|
@ -28,10 +28,10 @@ import (
|
|||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var mountCommand = cli.Command{
|
var mountCommand = &cli.Command{
|
||||||
Name: "mount",
|
Name: "mount",
|
||||||
Usage: "Mount an image to a target path",
|
Usage: "Mount an image to a target path",
|
||||||
ArgsUsage: "[flags] <ref> <target>",
|
ArgsUsage: "[flags] <ref> <target>",
|
||||||
@ -40,11 +40,11 @@ var mountCommand = cli.Command{
|
|||||||
When you are done, use the unmount command.
|
When you are done, use the unmount command.
|
||||||
`,
|
`,
|
||||||
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "rw",
|
Name: "rw",
|
||||||
Usage: "Enable write support on the mount",
|
Usage: "Enable write support on the mount",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Mount the image for the specified platform",
|
Usage: "Mount the image for the specified platform",
|
||||||
Value: platforms.DefaultString(),
|
Value: platforms.DefaultString(),
|
||||||
|
@ -36,10 +36,10 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pullCommand = cli.Command{
|
var pullCommand = &cli.Command{
|
||||||
Name: "pull",
|
Name: "pull",
|
||||||
Usage: "Pull an image from a remote",
|
Usage: "Pull an image from a remote",
|
||||||
ArgsUsage: "[flags] <ref>",
|
ArgsUsage: "[flags] <ref>",
|
||||||
@ -53,33 +53,33 @@ command. As part of this process, we do the following:
|
|||||||
3. Register metadata for the image.
|
3. Register metadata for the image.
|
||||||
`,
|
`,
|
||||||
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Pull content from a specific platform",
|
Usage: "Pull content from a specific platform",
|
||||||
Value: &cli.StringSlice{},
|
Value: cli.NewStringSlice(),
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "Pull content and metadata from all platforms",
|
Usage: "Pull content and metadata from all platforms",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all-metadata",
|
Name: "all-metadata",
|
||||||
Usage: "(Deprecated: use skip-metadata) Pull metadata for all platforms",
|
Usage: "(Deprecated: use skip-metadata) Pull metadata for all platforms",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-metadata",
|
Name: "skip-metadata",
|
||||||
Usage: "Skips metadata for unused platforms (Image may be unable to be pushed without metadata)",
|
Usage: "Skips metadata for unused platforms (Image may be unable to be pushed without metadata)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "print-chainid",
|
Name: "print-chainid",
|
||||||
Usage: "Print the resulting image's chain ID",
|
Usage: "Print the resulting image's chain ID",
|
||||||
},
|
},
|
||||||
cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "max-concurrent-downloads",
|
Name: "max-concurrent-downloads",
|
||||||
Usage: "Set the max concurrent downloads for each pull",
|
Usage: "Set the max concurrent downloads for each pull",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Usage: "Fetch content from local client rather than using transfer service",
|
Usage: "Fetch content from local client rather than using transfer service",
|
||||||
},
|
},
|
||||||
|
@ -40,11 +40,11 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pushCommand = cli.Command{
|
var pushCommand = &cli.Command{
|
||||||
Name: "push",
|
Name: "push",
|
||||||
Usage: "Push an image to a remote",
|
Usage: "Push an image to a remote",
|
||||||
ArgsUsage: "[flags] <remote> [<local>]",
|
ArgsUsage: "[flags] <remote> [<local>]",
|
||||||
@ -57,24 +57,24 @@ var pushCommand = cli.Command{
|
|||||||
creating the associated configuration, and creating the manifest
|
creating the associated configuration, and creating the manifest
|
||||||
which references those resources.
|
which references those resources.
|
||||||
`,
|
`,
|
||||||
Flags: append(commands.RegistryFlags, cli.StringFlag{
|
Flags: append(commands.RegistryFlags, &cli.StringFlag{
|
||||||
Name: "manifest",
|
Name: "manifest",
|
||||||
Usage: "Digest of manifest",
|
Usage: "Digest of manifest",
|
||||||
}, cli.StringFlag{
|
}, &cli.StringFlag{
|
||||||
Name: "manifest-type",
|
Name: "manifest-type",
|
||||||
Usage: "Media type of manifest digest",
|
Usage: "Media type of manifest digest",
|
||||||
Value: ocispec.MediaTypeImageManifest,
|
Value: ocispec.MediaTypeImageManifest,
|
||||||
}, cli.StringSliceFlag{
|
}, &cli.StringSliceFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Push content from a specific platform",
|
Usage: "Push content from a specific platform",
|
||||||
Value: &cli.StringSlice{},
|
Value: cli.NewStringSlice(),
|
||||||
}, cli.IntFlag{
|
}, &cli.IntFlag{
|
||||||
Name: "max-concurrent-uploaded-layers",
|
Name: "max-concurrent-uploaded-layers",
|
||||||
Usage: "Set the max concurrent uploaded layers for each push",
|
Usage: "Set the max concurrent uploaded layers for each push",
|
||||||
}, cli.BoolFlag{
|
}, &cli.BoolFlag{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Usage: "Push content from local client rather than using transfer service",
|
Usage: "Push content from local client rather than using transfer service",
|
||||||
}, cli.BoolFlag{
|
}, &cli.BoolFlag{
|
||||||
Name: "allow-non-distributable-blobs",
|
Name: "allow-non-distributable-blobs",
|
||||||
Usage: "Allow pushing blobs that are marked as non-distributable",
|
Usage: "Allow pushing blobs that are marked as non-distributable",
|
||||||
}),
|
}),
|
||||||
@ -82,7 +82,7 @@ var pushCommand = cli.Command{
|
|||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
local = context.Args().Get(1)
|
local = context.Args().Get(1)
|
||||||
debug = context.GlobalBool("debug")
|
debug = context.Bool("debug")
|
||||||
desc ocispec.Descriptor
|
desc ocispec.Descriptor
|
||||||
)
|
)
|
||||||
if ref == "" {
|
if ref == "" {
|
||||||
|
@ -19,7 +19,7 @@ package images
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/core/transfer/image"
|
"github.com/containerd/containerd/v2/core/transfer/image"
|
||||||
@ -27,21 +27,21 @@ import (
|
|||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tagCommand = cli.Command{
|
var tagCommand = &cli.Command{
|
||||||
Name: "tag",
|
Name: "tag",
|
||||||
Usage: "Tag an image",
|
Usage: "Tag an image",
|
||||||
ArgsUsage: "[flags] <source_ref> <target_ref> [<target_ref>, ...]",
|
ArgsUsage: "[flags] <source_ref> <target_ref> [<target_ref>, ...]",
|
||||||
Description: `Tag an image for use in containerd.`,
|
Description: `Tag an image for use in containerd.`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "force",
|
Name: "force",
|
||||||
Usage: "Force target_ref to be created, regardless if it already exists",
|
Usage: "Force target_ref to be created, regardless if it already exists",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Usage: "Run tag locally rather than through transfer API",
|
Usage: "Run tag locally rather than through transfer API",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "skip-reference-check",
|
Name: "skip-reference-check",
|
||||||
Usage: "Skip the strict check for reference names",
|
Usage: "Skip the strict check for reference names",
|
||||||
},
|
},
|
||||||
@ -64,7 +64,7 @@ var tagCommand = cli.Command{
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if !context.Bool("local") {
|
if !context.Bool("local") {
|
||||||
for _, targetRef := range context.Args()[1:] {
|
for _, targetRef := range context.Args().Slice()[1:] {
|
||||||
if !context.Bool("skip-reference-check") {
|
if !context.Bool("skip-reference-check") {
|
||||||
if _, err := reference.ParseAnyReference(targetRef); err != nil {
|
if _, err := reference.ParseAnyReference(targetRef); err != nil {
|
||||||
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err)
|
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err)
|
||||||
@ -91,7 +91,7 @@ var tagCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Support multiple references for one command run
|
// Support multiple references for one command run
|
||||||
for _, targetRef := range context.Args()[1:] {
|
for _, targetRef := range context.Args().Slice()[1:] {
|
||||||
if !context.Bool("skip-reference-check") {
|
if !context.Bool("skip-reference-check") {
|
||||||
if _, err := reference.ParseAnyReference(targetRef); err != nil {
|
if _, err := reference.ParseAnyReference(targetRef); err != nil {
|
||||||
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err)
|
return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err)
|
||||||
|
@ -23,16 +23,16 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/core/leases"
|
"github.com/containerd/containerd/v2/core/leases"
|
||||||
"github.com/containerd/containerd/v2/core/mount"
|
"github.com/containerd/containerd/v2/core/mount"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var unmountCommand = cli.Command{
|
var unmountCommand = &cli.Command{
|
||||||
Name: "unmount",
|
Name: "unmount",
|
||||||
Usage: "Unmount the image from the target",
|
Usage: "Unmount the image from the target",
|
||||||
ArgsUsage: "[flags] <target>",
|
ArgsUsage: "[flags] <target>",
|
||||||
Description: "Unmount the image rootfs from the specified target.",
|
Description: "Unmount the image rootfs from the specified target.",
|
||||||
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
Flags: append(append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "rm",
|
Name: "rm",
|
||||||
Usage: "Remove the snapshot after a successful unmount",
|
Usage: "Remove the snapshot after a successful unmount",
|
||||||
},
|
},
|
||||||
|
@ -27,10 +27,10 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/progress"
|
"github.com/containerd/containerd/v2/pkg/progress"
|
||||||
|
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var usageCommand = cli.Command{
|
var usageCommand = &cli.Command{
|
||||||
Name: "usage",
|
Name: "usage",
|
||||||
Usage: "Display usage of snapshots for a given image ref",
|
Usage: "Display usage of snapshots for a given image ref",
|
||||||
ArgsUsage: "[flags] <ref>",
|
ArgsUsage: "[flags] <ref>",
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
|
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
ptypes "github.com/containerd/containerd/v2/protobuf/types"
|
ptypes "github.com/containerd/containerd/v2/protobuf/types"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
@ -28,7 +28,7 @@ type Info struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command is a cli command to output the containerd server info
|
// Command is a cli command to output the containerd server info
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "info",
|
Name: "info",
|
||||||
Usage: "Print the server info",
|
Usage: "Print the server info",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
@ -19,25 +19,27 @@ package install
|
|||||||
import (
|
import (
|
||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command to install binary packages
|
// Command to install binary packages
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "install",
|
Name: "install",
|
||||||
Usage: "Install a new package",
|
Usage: "Install a new package",
|
||||||
ArgsUsage: "<ref>",
|
ArgsUsage: "<ref>",
|
||||||
Description: "install a new package",
|
Description: "install a new package",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "libs,l",
|
Name: "libs",
|
||||||
Usage: "Install libs from the image",
|
Aliases: []string{"l"},
|
||||||
|
Usage: "Install libs from the image",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "replace,r",
|
Name: "replace",
|
||||||
Usage: "Replace any binaries or libs in the opt directory",
|
Aliases: []string{"r"},
|
||||||
|
Usage: "Replace any binaries or libs in the opt directory",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "path",
|
Name: "path",
|
||||||
Usage: "Set an optional install path other than the managed opt directory",
|
Usage: "Set an optional install path other than the managed opt directory",
|
||||||
},
|
},
|
||||||
|
@ -26,11 +26,11 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/core/leases"
|
"github.com/containerd/containerd/v2/core/leases"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for managing content
|
// Command is the cli command for managing content
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "leases",
|
Name: "leases",
|
||||||
Usage: "Manage leases",
|
Usage: "Manage leases",
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
@ -40,7 +40,7 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
|
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
@ -48,14 +48,15 @@ var listCommand = cli.Command{
|
|||||||
ArgsUsage: "[flags] <filter>",
|
ArgsUsage: "[flags] <filter>",
|
||||||
Description: "list active leases by containerd",
|
Description: "list active leases by containerd",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the blob digest",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the blob digest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
filters = context.Args()
|
filters = context.Args().Slice()
|
||||||
quiet = context.Bool("quiet")
|
quiet = context.Bool("quiet")
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
@ -99,24 +100,25 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var createCommand = cli.Command{
|
var createCommand = &cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Usage: "Create lease",
|
Usage: "Create lease",
|
||||||
ArgsUsage: "[flags] <label>=<value> ...",
|
ArgsUsage: "[flags] <label>=<value> ...",
|
||||||
Description: "create a new lease",
|
Description: "create a new lease",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "id",
|
Name: "id",
|
||||||
Usage: "Set the id for the lease, will be generated by default",
|
Usage: "Set the id for the lease, will be generated by default",
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "expires, x",
|
Name: "expires",
|
||||||
Usage: "Expiration of lease (0 value will not expire)",
|
Aliases: []string{"x"},
|
||||||
Value: 24 * time.Hour,
|
Usage: "Expiration of lease (0 value will not expire)",
|
||||||
|
Value: 24 * time.Hour,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var labelstr = context.Args()
|
var labelstr = context.Args().Slice()
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -152,20 +154,20 @@ var createCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var deleteCommand = cli.Command{
|
var deleteCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
Usage: "Delete a lease",
|
Usage: "Delete a lease",
|
||||||
ArgsUsage: "[flags] <lease id> ...",
|
ArgsUsage: "[flags] <lease id> ...",
|
||||||
Description: "delete a lease",
|
Description: "delete a lease",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Usage: "Synchronously remove leases and all unreferenced resources",
|
Usage: "Synchronously remove leases and all unreferenced resources",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var lids = context.Args()
|
var lids = context.Args().Slice()
|
||||||
if len(lids) == 0 {
|
if len(lids) == 0 {
|
||||||
return cli.ShowSubcommandHelp(context)
|
return cli.ShowSubcommandHelp(context)
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,11 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for managing namespaces
|
// Command is the cli command for managing namespaces
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "namespaces",
|
Name: "namespaces",
|
||||||
Aliases: []string{"namespace", "ns"},
|
Aliases: []string{"namespace", "ns"},
|
||||||
Usage: "Manage namespaces",
|
Usage: "Manage namespaces",
|
||||||
@ -43,7 +43,7 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var createCommand = cli.Command{
|
var createCommand = &cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Usage: "Create a new namespace",
|
Usage: "Create a new namespace",
|
||||||
@ -64,7 +64,7 @@ var createCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var setLabelsCommand = cli.Command{
|
var setLabelsCommand = &cli.Command{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Set and clear labels for a namespace",
|
Usage: "Set and clear labels for a namespace",
|
||||||
ArgsUsage: "<name> [<key>=<value>, ...]",
|
ArgsUsage: "<name> [<key>=<value>, ...]",
|
||||||
@ -89,16 +89,17 @@ var setLabelsCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List namespaces",
|
Usage: "List namespaces",
|
||||||
ArgsUsage: "[flags]",
|
ArgsUsage: "[flags]",
|
||||||
Description: "list namespaces",
|
Description: "list namespaces",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the namespace name",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the namespace name",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -141,16 +142,17 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeCommand = cli.Command{
|
var removeCommand = &cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
Usage: "Remove one or more namespaces",
|
Usage: "Remove one or more namespaces",
|
||||||
ArgsUsage: "<name> [<name>, ...]",
|
ArgsUsage: "<name> [<name>, ...]",
|
||||||
Description: "remove one or more namespaces. for now, the namespace must be empty",
|
Description: "remove one or more namespaces. for now, the namespace must be empty",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "cgroup,c",
|
Name: "cgroup",
|
||||||
Usage: "Delete the namespace's cgroup",
|
Aliases: []string{"c"},
|
||||||
|
Usage: "Delete the namespace's cgroup",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -163,7 +165,7 @@ var removeCommand = cli.Command{
|
|||||||
|
|
||||||
opts := deleteOpts(context)
|
opts := deleteOpts(context)
|
||||||
namespaces := client.NamespaceService()
|
namespaces := client.NamespaceService()
|
||||||
for _, target := range context.Args() {
|
for _, target := range context.Args().Slice() {
|
||||||
if err := namespaces.Delete(ctx, target, opts...); err != nil {
|
if err := namespaces.Delete(ctx, target, opts...); err != nil {
|
||||||
if !errdefs.IsNotFound(err) {
|
if !errdefs.IsNotFound(err) {
|
||||||
if exitErr == nil {
|
if exitErr == nil {
|
||||||
|
@ -19,7 +19,7 @@ package namespaces
|
|||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/v2/core/runtime/opts"
|
"github.com/containerd/containerd/v2/core/runtime/opts"
|
||||||
"github.com/containerd/containerd/v2/pkg/namespaces"
|
"github.com/containerd/containerd/v2/pkg/namespaces"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func deleteOpts(context *cli.Context) []namespaces.DeleteOpts {
|
func deleteOpts(context *cli.Context) []namespaces.DeleteOpts {
|
||||||
|
@ -20,7 +20,7 @@ package namespaces
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/v2/pkg/namespaces"
|
"github.com/containerd/containerd/v2/pkg/namespaces"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func deleteOpts(context *cli.Context) []namespaces.DeleteOpts {
|
func deleteOpts(context *cli.Context) []namespaces.DeleteOpts {
|
||||||
|
@ -19,7 +19,7 @@ package oci
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/core/containers"
|
"github.com/containerd/containerd/v2/core/containers"
|
||||||
@ -28,19 +28,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Command is the parent for all OCI related tools under 'oci'
|
// Command is the parent for all OCI related tools under 'oci'
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "oci",
|
Name: "oci",
|
||||||
Usage: "OCI tools",
|
Usage: "OCI tools",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
defaultSpecCommand,
|
defaultSpecCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultSpecCommand = cli.Command{
|
var defaultSpecCommand = &cli.Command{
|
||||||
Name: "spec",
|
Name: "spec",
|
||||||
Usage: "See the output of the default OCI spec",
|
Usage: "See the output of the default OCI spec",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Platform of the spec to print (Examples: 'linux/arm64', 'windows/amd64')",
|
Usage: "Platform of the spec to print (Examples: 'linux/arm64', 'windows/amd64')",
|
||||||
},
|
},
|
||||||
|
@ -29,33 +29,35 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
pluginutils "github.com/containerd/plugin"
|
pluginutils "github.com/containerd/plugin"
|
||||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is a cli command that outputs plugin information
|
// Command is a cli command that outputs plugin information
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "plugins",
|
Name: "plugins",
|
||||||
Aliases: []string{"plugin"},
|
Aliases: []string{"plugin"},
|
||||||
Usage: "Provides information about containerd plugins",
|
Usage: "Provides information about containerd plugins",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
listCommand,
|
listCommand,
|
||||||
inspectRuntimeCommand,
|
inspectRuntimeCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "Lists containerd plugins",
|
Usage: "Lists containerd plugins",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet,q",
|
Name: "quiet",
|
||||||
Usage: "Print only the plugin ids",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the plugin ids",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "detailed,d",
|
Name: "detailed",
|
||||||
Usage: "Print detailed information about each plugin",
|
Aliases: []string{"d"},
|
||||||
|
Usage: "Print detailed information about each plugin",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -69,7 +71,7 @@ var listCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
ps := client.IntrospectionService()
|
ps := client.IntrospectionService()
|
||||||
response, err := ps.Plugins(ctx, context.Args())
|
response, err := ps.Plugins(ctx, context.Args().Slice())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -165,7 +167,7 @@ func prettyPlatforms(pspb []*types.Platform) string {
|
|||||||
return strings.Join(ps, ",")
|
return strings.Join(ps, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
var inspectRuntimeCommand = cli.Command{
|
var inspectRuntimeCommand = &cli.Command{
|
||||||
Name: "inspect-runtime",
|
Name: "inspect-runtime",
|
||||||
Usage: "Display runtime info",
|
Usage: "Display runtime info",
|
||||||
ArgsUsage: "[flags]",
|
ArgsUsage: "[flags]",
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/defaults"
|
"github.com/containerd/containerd/v2/defaults"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pprofDialer struct {
|
type pprofDialer struct {
|
||||||
@ -33,17 +33,18 @@ type pprofDialer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command is the cli command for providing golang pprof outputs for containerd
|
// Command is the cli command for providing golang pprof outputs for containerd
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "pprof",
|
Name: "pprof",
|
||||||
Usage: "Provide golang pprof outputs for containerd",
|
Usage: "Provide golang pprof outputs for containerd",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "debug-socket, d",
|
Name: "debug-socket",
|
||||||
Usage: "Socket path for containerd's debug server",
|
Aliases: []string{"d"},
|
||||||
Value: defaults.DefaultDebugAddress,
|
Usage: "Socket path for containerd's debug server",
|
||||||
|
Value: defaults.DefaultDebugAddress,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
pprofBlockCommand,
|
pprofBlockCommand,
|
||||||
pprofGoroutinesCommand,
|
pprofGoroutinesCommand,
|
||||||
pprofHeapCommand,
|
pprofHeapCommand,
|
||||||
@ -53,11 +54,11 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofGoroutinesCommand = cli.Command{
|
var pprofGoroutinesCommand = &cli.Command{
|
||||||
Name: "goroutines",
|
Name: "goroutines",
|
||||||
Usage: "Dump goroutine stack dump",
|
Usage: "Dump goroutine stack dump",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 2,
|
Value: 2,
|
||||||
@ -77,11 +78,11 @@ var pprofGoroutinesCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofHeapCommand = cli.Command{
|
var pprofHeapCommand = &cli.Command{
|
||||||
Name: "heap",
|
Name: "heap",
|
||||||
Usage: "Dump heap profile",
|
Usage: "Dump heap profile",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -101,16 +102,17 @@ var pprofHeapCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofProfileCommand = cli.Command{
|
var pprofProfileCommand = &cli.Command{
|
||||||
Name: "profile",
|
Name: "profile",
|
||||||
Usage: "CPU profile",
|
Usage: "CPU profile",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "seconds,s",
|
Name: "seconds",
|
||||||
Usage: "Duration for collection (seconds)",
|
Aliases: []string{"s"},
|
||||||
Value: 30 * time.Second,
|
Usage: "Duration for collection (seconds)",
|
||||||
|
Value: 30 * time.Second,
|
||||||
},
|
},
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -131,16 +133,17 @@ var pprofProfileCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofTraceCommand = cli.Command{
|
var pprofTraceCommand = &cli.Command{
|
||||||
Name: "trace",
|
Name: "trace",
|
||||||
Usage: "Collect execution trace",
|
Usage: "Collect execution trace",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.DurationFlag{
|
&cli.DurationFlag{
|
||||||
Name: "seconds,s",
|
Name: "seconds",
|
||||||
Usage: "Trace time (seconds)",
|
Aliases: []string{"s"},
|
||||||
Value: 5 * time.Second,
|
Usage: "Trace time (seconds)",
|
||||||
|
Value: 5 * time.Second,
|
||||||
},
|
},
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -162,11 +165,11 @@ var pprofTraceCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofBlockCommand = cli.Command{
|
var pprofBlockCommand = &cli.Command{
|
||||||
Name: "block",
|
Name: "block",
|
||||||
Usage: "Goroutine blocking profile",
|
Usage: "Goroutine blocking profile",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -186,11 +189,11 @@ var pprofBlockCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofThreadcreateCommand = cli.Command{
|
var pprofThreadcreateCommand = &cli.Command{
|
||||||
Name: "threadcreate",
|
Name: "threadcreate",
|
||||||
Usage: "Goroutine thread creating profile",
|
Usage: "Goroutine thread creating profile",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.UintFlag{
|
&cli.UintFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "Debug pprof args",
|
Usage: "Debug pprof args",
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -211,7 +214,7 @@ var pprofThreadcreateCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getPProfClient(context *cli.Context) *http.Client {
|
func getPProfClient(context *cli.Context) *http.Client {
|
||||||
dialer := getPProfDialer(context.GlobalString("debug-socket"))
|
dialer := getPProfDialer(context.String("debug-socket"))
|
||||||
|
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
Dial: dialer.pprofDial,
|
Dial: dialer.pprofDial,
|
||||||
|
@ -36,7 +36,7 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/core/remotes/docker/config"
|
"github.com/containerd/containerd/v2/core/remotes/docker/config"
|
||||||
"github.com/containerd/containerd/v2/core/transfer/registry"
|
"github.com/containerd/containerd/v2/core/transfer/registry"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PushTracker returns a new InMemoryTracker which tracks the ref status
|
// PushTracker returns a new InMemoryTracker which tracks the ref status
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
gocni "github.com/containerd/go-cni"
|
gocni "github.com/containerd/go-cni"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
@ -89,41 +89,41 @@ func parseMountFlag(m string) (specs.Mount, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command runs a container
|
// Command runs a container
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Usage: "Run a container",
|
Usage: "Run a container",
|
||||||
ArgsUsage: "[flags] Image|RootFS ID [COMMAND] [ARG...]",
|
ArgsUsage: "[flags] Image|RootFS ID [COMMAND] [ARG...]",
|
||||||
SkipArgReorder: true,
|
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "rm",
|
Name: "rm",
|
||||||
Usage: "Remove the container after running, cannot be used with --detach",
|
Usage: "Remove the container after running, cannot be used with --detach",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "null-io",
|
Name: "null-io",
|
||||||
Usage: "Send all IO to /dev/null",
|
Usage: "Send all IO to /dev/null",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "log-uri",
|
Name: "log-uri",
|
||||||
Usage: "Log uri",
|
Usage: "Log uri",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "detach,d",
|
Name: "detach",
|
||||||
Usage: "Detach from the task after it has started execution, cannot be used with --rm",
|
Aliases: []string{"d"},
|
||||||
|
Usage: "Detach from the task after it has started execution, cannot be used with --rm",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "fifo-dir",
|
Name: "fifo-dir",
|
||||||
Usage: "Directory used for storing IO FIFOs",
|
Usage: "Directory used for storing IO FIFOs",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cgroup",
|
Name: "cgroup",
|
||||||
Usage: "Cgroup path (To disable use of cgroup, set to \"\" explicitly)",
|
Usage: "Cgroup path (To disable use of cgroup, set to \"\" explicitly)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "platform",
|
Name: "platform",
|
||||||
Usage: "Run image for specific platform",
|
Usage: "Run image for specific platform",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "cni",
|
Name: "cni",
|
||||||
Usage: "Enable cni networking for the container",
|
Usage: "Enable cni networking for the container",
|
||||||
},
|
},
|
||||||
@ -259,7 +259,7 @@ var Command = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return cli.NewExitError("", int(code))
|
return cli.Exit("", int(code))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -39,43 +39,43 @@ import (
|
|||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/intel/goresctrl/pkg/blockio"
|
"github.com/intel/goresctrl/pkg/blockio"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"tags.cncf.io/container-device-interface/pkg/cdi"
|
"tags.cncf.io/container-device-interface/pkg/cdi"
|
||||||
"tags.cncf.io/container-device-interface/pkg/parser"
|
"tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
var platformRunFlags = []cli.Flag{
|
var platformRunFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "uidmap",
|
Name: "uidmap",
|
||||||
Usage: "Run inside a user namespace with the specified UID mapping range; specified with the format `container-uid:host-uid:length`",
|
Usage: "Run inside a user namespace with the specified UID mapping range; specified with the format `container-uid:host-uid:length`",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "gidmap",
|
Name: "gidmap",
|
||||||
Usage: "Run inside a user namespace with the specified GID mapping range; specified with the format `container-gid:host-gid:length`",
|
Usage: "Run inside a user namespace with the specified GID mapping range; specified with the format `container-gid:host-gid:length`",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "remap-labels",
|
Name: "remap-labels",
|
||||||
Usage: "Provide the user namespace ID remapping to the snapshotter via label options; requires snapshotter support",
|
Usage: "Provide the user namespace ID remapping to the snapshotter via label options; requires snapshotter support",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "privileged-without-host-devices",
|
Name: "privileged-without-host-devices",
|
||||||
Usage: "Don't pass all host devices to privileged container",
|
Usage: "Don't pass all host devices to privileged container",
|
||||||
},
|
},
|
||||||
cli.Float64Flag{
|
&cli.Float64Flag{
|
||||||
Name: "cpus",
|
Name: "cpus",
|
||||||
Usage: "Set the CFS cpu quota",
|
Usage: "Set the CFS cpu quota",
|
||||||
Value: 0.0,
|
Value: 0.0,
|
||||||
},
|
},
|
||||||
cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "cpu-shares",
|
Name: "cpu-shares",
|
||||||
Usage: "Set the cpu shares",
|
Usage: "Set the cpu shares",
|
||||||
Value: 1024,
|
Value: 1024,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cpuset-cpus",
|
Name: "cpuset-cpus",
|
||||||
Usage: "Set the CPUs the container will run in (e.g., 1-2,4)",
|
Usage: "Set the CPUs the container will run in (e.g., 1-2,4)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cpuset-mems",
|
Name: "cpuset-mems",
|
||||||
Usage: "Set the memory nodes the container will run in (e.g., 1-2,4)",
|
Usage: "Set the memory nodes the container will run in (e.g., 1-2,4)",
|
||||||
},
|
},
|
||||||
@ -110,7 +110,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
// for container's id is Args[1]
|
// for container's id is Args[1]
|
||||||
args = context.Args()[2:]
|
args = context.Args().Slice()[2:]
|
||||||
)
|
)
|
||||||
opts = append(opts, oci.WithDefaultSpec(), oci.WithDefaultUnixDevices)
|
opts = append(opts, oci.WithDefaultSpec(), oci.WithDefaultUnixDevices)
|
||||||
if ef := context.String("env-file"); ef != "" {
|
if ef := context.String("env-file"); ef != "" {
|
||||||
|
@ -30,11 +30,11 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/oci"
|
"github.com/containerd/containerd/v2/pkg/oci"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var platformRunFlags = []cli.Flag{
|
var platformRunFlags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "isolated",
|
Name: "isolated",
|
||||||
Usage: "Run the container with vm isolation",
|
Usage: "Run the container with vm isolation",
|
||||||
},
|
},
|
||||||
@ -62,7 +62,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
} else {
|
} else {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
args = context.Args()[2:]
|
args = context.Args().Slice()[2:]
|
||||||
)
|
)
|
||||||
|
|
||||||
id = context.Args().Get(1)
|
id = context.Args().Get(1)
|
||||||
@ -176,7 +176,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
var runtimeOpts interface{}
|
var runtimeOpts interface{}
|
||||||
if runtime == "io.containerd.runhcs.v1" {
|
if runtime == "io.containerd.runhcs.v1" {
|
||||||
runtimeOpts = &options.Options{
|
runtimeOpts = &options.Options{
|
||||||
Debug: context.GlobalBool("debug"),
|
Debug: context.Bool("debug"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cOpts = append(cOpts, containerd.WithRuntime(runtime, runtimeOpts))
|
cOpts = append(cOpts, containerd.WithRuntime(runtime, runtimeOpts))
|
||||||
|
@ -27,11 +27,11 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/defaults"
|
"github.com/containerd/containerd/v2/defaults"
|
||||||
"github.com/containerd/containerd/v2/pkg/oci"
|
"github.com/containerd/containerd/v2/pkg/oci"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is a set of subcommands to manage runtimes with sandbox support
|
// Command is a set of subcommands to manage runtimes with sandbox support
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "sandboxes",
|
Name: "sandboxes",
|
||||||
Aliases: []string{"sandbox", "sb", "s"},
|
Aliases: []string{"sandbox", "sb", "s"},
|
||||||
Usage: "Manage sandboxes",
|
Usage: "Manage sandboxes",
|
||||||
@ -42,13 +42,13 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var runCommand = cli.Command{
|
var runCommand = &cli.Command{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Aliases: []string{"create", "c", "r"},
|
Aliases: []string{"create", "c", "r"},
|
||||||
Usage: "Run a new sandbox",
|
Usage: "Run a new sandbox",
|
||||||
ArgsUsage: "[flags] <pod-config.json> <sandbox-id>",
|
ArgsUsage: "[flags] <pod-config.json> <sandbox-id>",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "runtime",
|
Name: "runtime",
|
||||||
Usage: "Runtime name",
|
Usage: "Runtime name",
|
||||||
Value: defaults.DefaultRuntime,
|
Value: defaults.DefaultRuntime,
|
||||||
@ -97,12 +97,12 @@ var runCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List sandboxes",
|
Usage: "List sandboxes",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "filters",
|
Name: "filters",
|
||||||
Usage: "The list of filters to apply when querying sandboxes from the store",
|
Usage: "The list of filters to apply when querying sandboxes from the store",
|
||||||
},
|
},
|
||||||
@ -143,15 +143,16 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeCommand = cli.Command{
|
var removeCommand = &cli.Command{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Aliases: []string{"rm"},
|
Aliases: []string{"rm"},
|
||||||
ArgsUsage: "<id> [<id>, ...]",
|
ArgsUsage: "<id> [<id>, ...]",
|
||||||
Usage: "Remove sandboxes",
|
Usage: "Remove sandboxes",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "force, f",
|
Name: "force",
|
||||||
Usage: "Ignore shutdown errors when removing sandbox",
|
Aliases: []string{"f"},
|
||||||
|
Usage: "Ignore shutdown errors when removing sandbox",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -163,7 +164,7 @@ var removeCommand = cli.Command{
|
|||||||
|
|
||||||
force := context.Bool("force")
|
force := context.Bool("force")
|
||||||
|
|
||||||
for _, id := range context.Args() {
|
for _, id := range context.Args().Slice() {
|
||||||
sandbox, err := client.LoadSandbox(ctx, id)
|
sandbox, err := client.LoadSandbox(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithError(err).Errorf("failed to load sandbox %s", id)
|
log.G(ctx).WithError(err).Errorf("failed to load sandbox %s", id)
|
||||||
|
@ -37,39 +37,40 @@ import (
|
|||||||
"github.com/containerd/ttrpc"
|
"github.com/containerd/ttrpc"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fifoFlags = []cli.Flag{
|
var fifoFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "stdin",
|
Name: "stdin",
|
||||||
Usage: "Specify the path to the stdin fifo",
|
Usage: "Specify the path to the stdin fifo",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "stdout",
|
Name: "stdout",
|
||||||
Usage: "Specify the path to the stdout fifo",
|
Usage: "Specify the path to the stdout fifo",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "stderr",
|
Name: "stderr",
|
||||||
Usage: "Specify the path to the stderr fifo",
|
Usage: "Specify the path to the stderr fifo",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "tty,t",
|
Name: "tty",
|
||||||
Usage: "Enable tty support",
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Enable tty support",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command is the cli command for interacting with a task
|
// Command is the cli command for interacting with a task
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "shim",
|
Name: "shim",
|
||||||
Usage: "Interact with a shim directly",
|
Usage: "Interact with a shim directly",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "id",
|
Name: "id",
|
||||||
Usage: "Container id",
|
Usage: "Container id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
execCommand,
|
execCommand,
|
||||||
startCommand,
|
startCommand,
|
||||||
@ -77,7 +78,7 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var startCommand = cli.Command{
|
var startCommand = &cli.Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "Start a container with a task",
|
Usage: "Start a container with a task",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -92,7 +93,7 @@ var startCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var deleteCommand = cli.Command{
|
var deleteCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "Delete a container with a task",
|
Usage: "Delete a container with a task",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -111,7 +112,7 @@ var deleteCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateCommand = cli.Command{
|
var stateCommand = &cli.Command{
|
||||||
Name: "state",
|
Name: "state",
|
||||||
Usage: "Get the state of all the processes of the task",
|
Usage: "Get the state of all the processes of the task",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -120,7 +121,7 @@ var stateCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r, err := service.State(gocontext.Background(), &task.StateRequest{
|
r, err := service.State(gocontext.Background(), &task.StateRequest{
|
||||||
ID: context.GlobalString("id"),
|
ID: context.String("id"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -130,24 +131,26 @@ var stateCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var execCommand = cli.Command{
|
var execCommand = &cli.Command{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Usage: "Exec a new process in the task's container",
|
Usage: "Exec a new process in the task's container",
|
||||||
Flags: append(fifoFlags,
|
Flags: append(fifoFlags,
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "attach,a",
|
Name: "attach",
|
||||||
Usage: "Stay attached to the container and open the fifos",
|
Aliases: []string{"a"},
|
||||||
|
Usage: "Stay attached to the container and open the fifos",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "env,e",
|
Name: "env",
|
||||||
Usage: "Add environment vars",
|
Aliases: []string{"e"},
|
||||||
Value: &cli.StringSlice{},
|
Usage: "Add environment vars",
|
||||||
|
Value: cli.NewStringSlice(),
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cwd",
|
Name: "cwd",
|
||||||
Usage: "Current working directory",
|
Usage: "Current working directory",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "spec",
|
Name: "spec",
|
||||||
Usage: "Runtime spec",
|
Usage: "Runtime spec",
|
||||||
},
|
},
|
||||||
@ -230,18 +233,18 @@ var execCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTaskService(context *cli.Context) (task.TaskService, error) {
|
func getTaskService(context *cli.Context) (task.TaskService, error) {
|
||||||
id := context.GlobalString("id")
|
id := context.String("id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return nil, fmt.Errorf("container id must be specified")
|
return nil, fmt.Errorf("container id must be specified")
|
||||||
}
|
}
|
||||||
ns := context.GlobalString("namespace")
|
ns := context.String("namespace")
|
||||||
|
|
||||||
// /containerd-shim/ns/id/shim.sock is the old way to generate shim socket,
|
// /containerd-shim/ns/id/shim.sock is the old way to generate shim socket,
|
||||||
// compatible it
|
// compatible it
|
||||||
s1 := filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock")
|
s1 := filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock")
|
||||||
// this should not error, ctr always get a default ns
|
// this should not error, ctr always get a default ns
|
||||||
ctx := namespaces.WithNamespace(gocontext.Background(), ns)
|
ctx := namespaces.WithNamespace(gocontext.Background(), ns)
|
||||||
s2, _ := shim.SocketAddress(ctx, context.GlobalString("address"), id)
|
s2, _ := shim.SocketAddress(ctx, context.String("address"), id)
|
||||||
s2 = strings.TrimPrefix(s2, "unix://")
|
s2 = strings.TrimPrefix(s2, "unix://")
|
||||||
|
|
||||||
for _, socket := range []string{s2, "\x00" + s1} {
|
for _, socket := range []string{s2, "\x00" + s1} {
|
||||||
|
@ -38,11 +38,11 @@ import (
|
|||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is the cli command for managing snapshots
|
// Command is the cli command for managing snapshots
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "snapshots",
|
Name: "snapshots",
|
||||||
Aliases: []string{"snapshot"},
|
Aliases: []string{"snapshot"},
|
||||||
Usage: "Manage snapshots",
|
Usage: "Manage snapshots",
|
||||||
@ -63,7 +63,7 @@ var Command = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Usage: "List snapshots",
|
Usage: "List snapshots",
|
||||||
@ -74,7 +74,7 @@ var listCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var (
|
var (
|
||||||
snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter = client.SnapshotService(context.String("snapshotter"))
|
||||||
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
||||||
)
|
)
|
||||||
fmt.Fprintln(tw, "KEY\tPARENT\tKIND\t")
|
fmt.Fprintln(tw, "KEY\tPARENT\tKIND\t")
|
||||||
@ -92,21 +92,21 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffCommand = cli.Command{
|
var diffCommand = &cli.Command{
|
||||||
Name: "diff",
|
Name: "diff",
|
||||||
Usage: "Get the diff of two snapshots. the default second snapshot is the first snapshot's parent.",
|
Usage: "Get the diff of two snapshots. the default second snapshot is the first snapshot's parent.",
|
||||||
ArgsUsage: "[flags] <idA> [<idB>]",
|
ArgsUsage: "[flags] <idA> [<idB>]",
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "media-type",
|
Name: "media-type",
|
||||||
Usage: "Media type to use for creating diff",
|
Usage: "Media type to use for creating diff",
|
||||||
Value: ocispec.MediaTypeImageLayerGzip,
|
Value: ocispec.MediaTypeImageLayerGzip,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "ref",
|
Name: "ref",
|
||||||
Usage: "Content upload reference to use",
|
Usage: "Content upload reference to use",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "keep",
|
Name: "keep",
|
||||||
Usage: "Keep diff content. up to creator to delete it.",
|
Usage: "Keep diff content. up to creator to delete it.",
|
||||||
},
|
},
|
||||||
@ -133,7 +133,7 @@ var diffCommand = cli.Command{
|
|||||||
|
|
||||||
var desc ocispec.Descriptor
|
var desc ocispec.Descriptor
|
||||||
labels := commands.LabelArgs(context.StringSlice("label"))
|
labels := commands.LabelArgs(context.StringSlice("label"))
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
|
|
||||||
if context.Bool("keep") {
|
if context.Bool("keep") {
|
||||||
labels["containerd.io/gc.root"] = time.Now().UTC().Format(time.RFC3339)
|
labels["containerd.io/gc.root"] = time.Now().UTC().Format(time.RFC3339)
|
||||||
@ -194,12 +194,12 @@ func withMounts(ctx gocontext.Context, id string, sn snapshots.Snapshotter, f fu
|
|||||||
return f(mounts)
|
return f(mounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
var usageCommand = cli.Command{
|
var usageCommand = &cli.Command{
|
||||||
Name: "usage",
|
Name: "usage",
|
||||||
Usage: "Usage snapshots",
|
Usage: "Usage snapshots",
|
||||||
ArgsUsage: "[flags] [<key>, ...]",
|
ArgsUsage: "[flags] [<key>, ...]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "b",
|
Name: "b",
|
||||||
Usage: "Display size in bytes",
|
Usage: "Display size in bytes",
|
||||||
},
|
},
|
||||||
@ -221,7 +221,7 @@ var usageCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var (
|
var (
|
||||||
snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter = client.SnapshotService(context.String("snapshotter"))
|
||||||
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
||||||
)
|
)
|
||||||
fmt.Fprintln(tw, "KEY\tSIZE\tINODES\t")
|
fmt.Fprintln(tw, "KEY\tSIZE\tINODES\t")
|
||||||
@ -237,7 +237,7 @@ var usageCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, id := range context.Args() {
|
for _, id := range context.Args().Slice() {
|
||||||
usage, err := snapshotter.Usage(ctx, id)
|
usage, err := snapshotter.Usage(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -250,7 +250,7 @@ var usageCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeCommand = cli.Command{
|
var removeCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
ArgsUsage: "<key> [<key>, ...]",
|
ArgsUsage: "<key> [<key>, ...]",
|
||||||
@ -261,8 +261,8 @@ var removeCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
for _, key := range context.Args() {
|
for _, key := range context.Args().Slice() {
|
||||||
err = snapshotter.Remove(ctx, key)
|
err = snapshotter.Remove(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to remove %q: %w", key, err)
|
return fmt.Errorf("failed to remove %q: %w", key, err)
|
||||||
@ -273,16 +273,17 @@ var removeCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var prepareCommand = cli.Command{
|
var prepareCommand = &cli.Command{
|
||||||
Name: "prepare",
|
Name: "prepare",
|
||||||
Usage: "Prepare a snapshot from a committed snapshot",
|
Usage: "Prepare a snapshot from a committed snapshot",
|
||||||
ArgsUsage: "[flags] <key> [<parent>]",
|
ArgsUsage: "[flags] <key> [<parent>]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "target, t",
|
Name: "target",
|
||||||
Usage: "Mount target path, will print mount, if provided",
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Mount target path, will print mount, if provided",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "mounts",
|
Name: "mounts",
|
||||||
Usage: "Print out snapshot mounts as JSON",
|
Usage: "Print out snapshot mounts as JSON",
|
||||||
},
|
},
|
||||||
@ -302,7 +303,7 @@ var prepareCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
||||||
}
|
}
|
||||||
@ -324,16 +325,17 @@ var prepareCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewCommand = cli.Command{
|
var viewCommand = &cli.Command{
|
||||||
Name: "view",
|
Name: "view",
|
||||||
Usage: "Create a read-only snapshot from a committed snapshot",
|
Usage: "Create a read-only snapshot from a committed snapshot",
|
||||||
ArgsUsage: "[flags] <key> [<parent>]",
|
ArgsUsage: "[flags] <key> [<parent>]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "target, t",
|
Name: "target",
|
||||||
Usage: "Mount target path, will print mount, if provided",
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Mount target path, will print mount, if provided",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "mounts",
|
Name: "mounts",
|
||||||
Usage: "Print out snapshot mounts as JSON",
|
Usage: "Print out snapshot mounts as JSON",
|
||||||
},
|
},
|
||||||
@ -353,7 +355,7 @@ var viewCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
mounts, err := snapshotter.View(ctx, key, parent)
|
mounts, err := snapshotter.View(ctx, key, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -371,7 +373,7 @@ var viewCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var mountCommand = cli.Command{
|
var mountCommand = &cli.Command{
|
||||||
Name: "mounts",
|
Name: "mounts",
|
||||||
Aliases: []string{"m", "mount"},
|
Aliases: []string{"m", "mount"},
|
||||||
Usage: "Mount gets mount commands for the snapshots",
|
Usage: "Mount gets mount commands for the snapshots",
|
||||||
@ -389,7 +391,7 @@ var mountCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
mounts, err := snapshotter.Mounts(ctx, key)
|
mounts, err := snapshotter.Mounts(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -401,7 +403,7 @@ var mountCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var commitCommand = cli.Command{
|
var commitCommand = &cli.Command{
|
||||||
Name: "commit",
|
Name: "commit",
|
||||||
Usage: "Commit an active snapshot into the provided name",
|
Usage: "Commit an active snapshot into the provided name",
|
||||||
ArgsUsage: "<key> <active>",
|
ArgsUsage: "<key> <active>",
|
||||||
@ -418,7 +420,7 @@ var commitCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
||||||
}
|
}
|
||||||
@ -426,7 +428,7 @@ var commitCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var treeCommand = cli.Command{
|
var treeCommand = &cli.Command{
|
||||||
Name: "tree",
|
Name: "tree",
|
||||||
Usage: "Display tree view of snapshot branches",
|
Usage: "Display tree view of snapshot branches",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -436,7 +438,7 @@ var treeCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var (
|
var (
|
||||||
snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter = client.SnapshotService(context.String("snapshotter"))
|
||||||
tree = newSnapshotTree()
|
tree = newSnapshotTree()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -454,7 +456,7 @@ var treeCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var infoCommand = cli.Command{
|
var infoCommand = &cli.Command{
|
||||||
Name: "info",
|
Name: "info",
|
||||||
Usage: "Get info about a snapshot",
|
Usage: "Get info about a snapshot",
|
||||||
ArgsUsage: "<key>",
|
ArgsUsage: "<key>",
|
||||||
@ -469,7 +471,7 @@ var infoCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
info, err := snapshotter.Stat(ctx, key)
|
info, err := snapshotter.Stat(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -481,7 +483,7 @@ var infoCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var setLabelCommand = cli.Command{
|
var setLabelCommand = &cli.Command{
|
||||||
Name: "label",
|
Name: "label",
|
||||||
Usage: "Add labels to content",
|
Usage: "Add labels to content",
|
||||||
ArgsUsage: "<name> [<label>=<value> ...]",
|
ArgsUsage: "<name> [<label>=<value> ...]",
|
||||||
@ -494,7 +496,7 @@ var setLabelCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
|
snapshotter := client.SnapshotService(context.String("snapshotter"))
|
||||||
|
|
||||||
info := snapshots.Info{
|
info := snapshots.Info{
|
||||||
Name: key,
|
Name: key,
|
||||||
@ -530,7 +532,7 @@ var setLabelCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var unpackCommand = cli.Command{
|
var unpackCommand = &cli.Command{
|
||||||
Name: "unpack",
|
Name: "unpack",
|
||||||
Usage: "Unpack applies layers from a manifest to a snapshot",
|
Usage: "Unpack applies layers from a manifest to a snapshot",
|
||||||
ArgsUsage: "[flags] <digest>",
|
ArgsUsage: "[flags] <digest>",
|
||||||
|
@ -21,10 +21,10 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var attachCommand = cli.Command{
|
var attachCommand = &cli.Command{
|
||||||
Name: "attach",
|
Name: "attach",
|
||||||
Usage: "Attach to the IO of a running container",
|
Usage: "Attach to the IO of a running container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
@ -79,7 +79,7 @@ var attachCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return cli.NewExitError("", int(code))
|
return cli.Exit("", int(code))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -23,23 +23,23 @@ import (
|
|||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkpointCommand = cli.Command{
|
var checkpointCommand = &cli.Command{
|
||||||
Name: "checkpoint",
|
Name: "checkpoint",
|
||||||
Usage: "Checkpoint a container",
|
Usage: "Checkpoint a container",
|
||||||
ArgsUsage: "[flags] CONTAINER",
|
ArgsUsage: "[flags] CONTAINER",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "exit",
|
Name: "exit",
|
||||||
Usage: "Stop the container after the checkpoint",
|
Usage: "Stop the container after the checkpoint",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "image-path",
|
Name: "image-path",
|
||||||
Usage: "Path to criu image files",
|
Usage: "Path to criu image files",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "work-path",
|
Name: "work-path",
|
||||||
Usage: "Path to criu work files and logs",
|
Usage: "Path to criu work files and logs",
|
||||||
},
|
},
|
||||||
|
@ -23,20 +23,21 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteCommand = cli.Command{
|
var deleteCommand = &cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "Delete one or more tasks",
|
Usage: "Delete one or more tasks",
|
||||||
ArgsUsage: "CONTAINER [CONTAINER, ...]",
|
ArgsUsage: "CONTAINER [CONTAINER, ...]",
|
||||||
Aliases: []string{"del", "remove", "rm"},
|
Aliases: []string{"del", "remove", "rm"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "force, f",
|
Name: "force",
|
||||||
Usage: "Force delete task process",
|
Aliases: []string{"f"},
|
||||||
|
Usage: "Force delete task process",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "exec-id",
|
Name: "exec-id",
|
||||||
Usage: "Process ID to kill",
|
Usage: "Process ID to kill",
|
||||||
},
|
},
|
||||||
@ -70,10 +71,10 @@ var deleteCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ec := status.ExitCode(); ec != 0 {
|
if ec := status.ExitCode(); ec != 0 {
|
||||||
return cli.NewExitError("", int(ec))
|
return cli.Exit("", int(ec))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, target := range context.Args() {
|
for _, target := range context.Args().Slice() {
|
||||||
task, err := loadTask(ctx, client, target)
|
task, err := loadTask(ctx, client, target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if exitErr == nil {
|
if exitErr == nil {
|
||||||
|
@ -28,41 +28,42 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/containerd/v2/pkg/oci"
|
"github.com/containerd/containerd/v2/pkg/oci"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var execCommand = cli.Command{
|
var execCommand = &cli.Command{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Usage: "Execute additional processes in an existing container",
|
Usage: "Execute additional processes in an existing container",
|
||||||
ArgsUsage: "[flags] CONTAINER CMD [ARG...]",
|
ArgsUsage: "[flags] CONTAINER CMD [ARG...]",
|
||||||
SkipArgReorder: true,
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "cwd",
|
Name: "cwd",
|
||||||
Usage: "Working directory of the new process",
|
Usage: "Working directory of the new process",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "tty,t",
|
Name: "tty",
|
||||||
Usage: "Allocate a TTY for the container",
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Allocate a TTY for the container",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "detach,d",
|
Name: "detach",
|
||||||
Usage: "Detach from the task after it has started execution",
|
Aliases: []string{"d"},
|
||||||
|
Usage: "Detach from the task after it has started execution",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "exec-id",
|
Name: "exec-id",
|
||||||
Required: true,
|
Required: true,
|
||||||
Usage: "Exec specific id for the process",
|
Usage: "Exec specific id for the process",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "fifo-dir",
|
Name: "fifo-dir",
|
||||||
Usage: "Directory used for storing IO FIFOs",
|
Usage: "Directory used for storing IO FIFOs",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "log-uri",
|
Name: "log-uri",
|
||||||
Usage: "Log uri for custom shim logging",
|
Usage: "Log uri for custom shim logging",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "user",
|
Name: "user",
|
||||||
Usage: "User id or name",
|
Usage: "User id or name",
|
||||||
},
|
},
|
||||||
@ -186,7 +187,7 @@ var execCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return cli.NewExitError("", int(code))
|
return cli.Exit("", int(code))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/moby/sys/signal"
|
"github.com/moby/sys/signal"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultSignal = "SIGTERM"
|
const defaultSignal = "SIGTERM"
|
||||||
@ -61,23 +61,25 @@ func RemoveCniNetworkIfExist(ctx context.Context, container containerd.Container
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var killCommand = cli.Command{
|
var killCommand = &cli.Command{
|
||||||
Name: "kill",
|
Name: "kill",
|
||||||
Usage: "Signal a container (default: SIGTERM)",
|
Usage: "Signal a container (default: SIGTERM)",
|
||||||
ArgsUsage: "[flags] CONTAINER",
|
ArgsUsage: "[flags] CONTAINER",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "signal, s",
|
Name: "signal",
|
||||||
Value: "",
|
Aliases: []string{"s"},
|
||||||
Usage: "Signal to send to the container",
|
Value: "",
|
||||||
|
Usage: "Signal to send to the container",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "exec-id",
|
Name: "exec-id",
|
||||||
Usage: "Process ID to kill",
|
Usage: "Process ID to kill",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "all, a",
|
Name: "all",
|
||||||
Usage: "Send signal to all processes inside the container",
|
Aliases: []string{"a"},
|
||||||
|
Usage: "Send signal to all processes inside the container",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
@ -23,18 +23,19 @@ import (
|
|||||||
|
|
||||||
tasks "github.com/containerd/containerd/v2/api/services/tasks/v1"
|
tasks "github.com/containerd/containerd/v2/api/services/tasks/v1"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = &cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Usage: "List tasks",
|
Usage: "List tasks",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
ArgsUsage: "[flags]",
|
ArgsUsage: "[flags]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet",
|
||||||
Usage: "Print only the task id",
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Print only the task id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
|
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -37,13 +37,13 @@ const (
|
|||||||
formatJSON = "json"
|
formatJSON = "json"
|
||||||
)
|
)
|
||||||
|
|
||||||
var metricsCommand = cli.Command{
|
var metricsCommand = &cli.Command{
|
||||||
Name: "metrics",
|
Name: "metrics",
|
||||||
Usage: "Get a single data point of metrics for a task with the built-in Linux runtime",
|
Usage: "Get a single data point of metrics for a task with the built-in Linux runtime",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Aliases: []string{"metric"},
|
Aliases: []string{"metric"},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: formatFlag,
|
Name: formatFlag,
|
||||||
Usage: `"table" or "json"`,
|
Usage: `"table" or "json"`,
|
||||||
Value: formatTable,
|
Value: formatTable,
|
||||||
|
@ -18,10 +18,10 @@ package tasks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pauseCommand = cli.Command{
|
var pauseCommand = &cli.Command{
|
||||||
Name: "pause",
|
Name: "pause",
|
||||||
Usage: "Pause an existing container",
|
Usage: "Pause an existing container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
|
@ -24,10 +24,10 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var psCommand = cli.Command{
|
var psCommand = &cli.Command{
|
||||||
Name: "ps",
|
Name: "ps",
|
||||||
Usage: "List processes for container",
|
Usage: "List processes for container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
|
@ -18,10 +18,10 @@ package tasks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var resumeCommand = cli.Command{
|
var resumeCommand = &cli.Command{
|
||||||
Name: "resume",
|
Name: "resume",
|
||||||
Usage: "Resume a paused container",
|
Usage: "Resume a paused container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
|
@ -25,33 +25,34 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var startCommand = cli.Command{
|
var startCommand = &cli.Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "Start a container that has been created",
|
Usage: "Start a container that has been created",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Flags: append(platformStartFlags, []cli.Flag{
|
Flags: append(platformStartFlags, []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "null-io",
|
Name: "null-io",
|
||||||
Usage: "Send all IO to /dev/null",
|
Usage: "Send all IO to /dev/null",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "log-uri",
|
Name: "log-uri",
|
||||||
Usage: "Log uri",
|
Usage: "Log uri",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "fifo-dir",
|
Name: "fifo-dir",
|
||||||
Usage: "Directory used for storing IO FIFOs",
|
Usage: "Directory used for storing IO FIFOs",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "pid-file",
|
Name: "pid-file",
|
||||||
Usage: "File path to write the task's pid",
|
Usage: "File path to write the task's pid",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "detach,d",
|
Name: "detach",
|
||||||
Usage: "Detach from the task after it has started execution",
|
Aliases: []string{"d"},
|
||||||
|
Usage: "Detach from the task after it has started execution",
|
||||||
},
|
},
|
||||||
}...),
|
}...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -137,7 +138,7 @@ var startCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
return cli.NewExitError("", int(code))
|
return cli.Exit("", int(code))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,7 @@ package tasks
|
|||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type resizer interface {
|
type resizer interface {
|
||||||
@ -27,11 +27,11 @@ type resizer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command is the cli command for managing tasks
|
// Command is the cli command for managing tasks
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "tasks",
|
Name: "tasks",
|
||||||
Usage: "Manage tasks",
|
Usage: "Manage tasks",
|
||||||
Aliases: []string{"t", "task"},
|
Aliases: []string{"t", "task"},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
attachCommand,
|
attachCommand,
|
||||||
checkpointCommand,
|
checkpointCommand,
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
|
@ -29,12 +29,12 @@ import (
|
|||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var platformStartFlags = []cli.Flag{
|
var platformStartFlags = []cli.Flag{
|
||||||
cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "no-pivot",
|
Name: "no-pivot",
|
||||||
Usage: "Disable use of pivot-root (linux only)",
|
Usage: "Disable use of pivot-root (linux only)",
|
||||||
},
|
},
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
containerd "github.com/containerd/containerd/v2/client"
|
containerd "github.com/containerd/containerd/v2/client"
|
||||||
"github.com/containerd/containerd/v2/pkg/cio"
|
"github.com/containerd/containerd/v2/pkg/cio"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var platformStartFlags = []cli.Flag{}
|
var platformStartFlags = []cli.Flag{}
|
||||||
|
@ -22,11 +22,11 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
"github.com/containerd/containerd/v2/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/v2/version"
|
"github.com/containerd/containerd/v2/version"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Command is a cli command to output the client and containerd server version
|
// Command is a cli command to output the client and containerd server version
|
||||||
var Command = cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
Usage: "Print the client and server versions",
|
Usage: "Print the client and server versions",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
@ -24,10 +24,10 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/cmd/ctr/app"
|
"github.com/containerd/containerd/v2/cmd/ctr/app"
|
||||||
"github.com/containerd/containerd/v2/internal/hasher"
|
"github.com/containerd/containerd/v2/internal/hasher"
|
||||||
"github.com/containerd/containerd/v2/pkg/seed" //nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
|
"github.com/containerd/containerd/v2/pkg/seed" //nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pluginCmds = []cli.Command{}
|
var pluginCmds = []*cli.Command{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
//nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
|
//nolint:staticcheck // Global math/rand seed is deprecated, but still used by external dependencies
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/v2/cmd/containerd/command"
|
"github.com/containerd/containerd/v2/cmd/containerd/command"
|
||||||
"github.com/containerd/containerd/v2/cmd/ctr/app"
|
"github.com/containerd/containerd/v2/cmd/ctr/app"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
3
go.mod
3
go.mod
@ -54,7 +54,7 @@ require (
|
|||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/tchap/go-patricia/v2 v2.3.1
|
github.com/tchap/go-patricia/v2 v2.3.1
|
||||||
github.com/urfave/cli v1.22.14
|
github.com/urfave/cli/v2 v2.27.1
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2
|
github.com/vishvananda/netlink v1.2.1-beta.2
|
||||||
go.etcd.io/bbolt v1.3.8
|
go.etcd.io/bbolt v1.3.8
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0
|
||||||
@ -113,6 +113,7 @@ require (
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
||||||
github.com/vishvananda/netns v0.0.4 // indirect
|
github.com/vishvananda/netns v0.0.4 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.23.1 // indirect
|
go.opentelemetry.io/otel/metric v1.23.1 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
||||||
|
7
go.sum
7
go.sum
@ -11,7 +11,6 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h
|
|||||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
|
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
|
||||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
|
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||||
github.com/Microsoft/hcsshim v0.12.0-rc.3 h1:5GNGrobGs/sN/0nFO21W9k4lFn+iXXZAE8fCZbmdRak=
|
github.com/Microsoft/hcsshim v0.12.0-rc.3 h1:5GNGrobGs/sN/0nFO21W9k4lFn+iXXZAE8fCZbmdRak=
|
||||||
@ -329,8 +328,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
|||||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
||||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||||
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
|
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||||
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
|
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
@ -343,6 +342,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
|
|||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
10
vendor/github.com/urfave/cli/.gitignore
generated
vendored
10
vendor/github.com/urfave/cli/.gitignore
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
*.coverprofile
|
|
||||||
coverage.txt
|
|
||||||
node_modules/
|
|
||||||
vendor
|
|
||||||
.idea
|
|
||||||
/.local/
|
|
||||||
/internal/
|
|
||||||
/site/
|
|
||||||
package.json
|
|
||||||
package-lock.json
|
|
51
vendor/github.com/urfave/cli/README.md
generated
vendored
51
vendor/github.com/urfave/cli/README.md
generated
vendored
@ -1,51 +0,0 @@
|
|||||||
cli
|
|
||||||
===
|
|
||||||
|
|
||||||
[](https://github.com/urfave/cli/actions/workflows/cli.yml)
|
|
||||||
[](https://pkg.go.dev/github.com/urfave/cli/)
|
|
||||||
[](https://goreportcard.com/report/urfave/cli)
|
|
||||||
[](https://codecov.io/gh/urfave/cli)
|
|
||||||
|
|
||||||
cli is a simple, fast, and fun package for building command line apps in Go. The
|
|
||||||
goal is to enable developers to write fast and distributable command line
|
|
||||||
applications in an expressive way.
|
|
||||||
|
|
||||||
## Usage Documentation
|
|
||||||
|
|
||||||
Usage documentation for `v1` is available [at the docs
|
|
||||||
site](https://cli.urfave.org/v1/getting-started/) or in-tree at
|
|
||||||
[./docs/v1/manual.md](./docs/v1/manual.md)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Make sure you have a working Go environment. Go version 1.18+ is supported.
|
|
||||||
|
|
||||||
### Supported platforms
|
|
||||||
|
|
||||||
cli is tested against multiple versions of Go on Linux, and against the latest released
|
|
||||||
version of Go on OS X and Windows. For full details, see
|
|
||||||
[./.github/workflows/cli.yml](./.github/workflows/cli.yml).
|
|
||||||
|
|
||||||
### Build tags
|
|
||||||
|
|
||||||
You can use the following build tags:
|
|
||||||
|
|
||||||
#### `urfave_cli_no_docs`
|
|
||||||
|
|
||||||
When set, this removes `ToMarkdown` and `ToMan` methods, so your application
|
|
||||||
won't be able to call those. This reduces the resulting binary size by about
|
|
||||||
300-400 KB (measured using Go 1.18.1 on Linux/amd64), due to less dependencies.
|
|
||||||
|
|
||||||
### Using `v1` releases
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/urfave/cli
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
...
|
|
||||||
import (
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
|
||||||
...
|
|
||||||
```
|
|
531
vendor/github.com/urfave/cli/app.go
generated
vendored
531
vendor/github.com/urfave/cli/app.go
generated
vendored
@ -1,531 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md"
|
|
||||||
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
|
|
||||||
// unused variable. commented for now. will remove in future if agreed upon by everyone
|
|
||||||
//runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL)
|
|
||||||
|
|
||||||
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
|
|
||||||
|
|
||||||
errInvalidActionType = NewExitError("ERROR invalid Action type. "+
|
|
||||||
fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+
|
|
||||||
fmt.Sprintf("See %s", appActionDeprecationURL), 2)
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// Description of the program argument format.
|
|
||||||
ArgsUsage string
|
|
||||||
// Version of the program
|
|
||||||
Version string
|
|
||||||
// Description of the program
|
|
||||||
Description 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
|
|
||||||
HideHelp bool
|
|
||||||
// Boolean to hide built-in version flag and the VERSION section of help
|
|
||||||
HideVersion bool
|
|
||||||
// Populate on app startup, only gettable through method Categories()
|
|
||||||
categories CommandCategories
|
|
||||||
// An action to execute when the bash-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
|
|
||||||
// Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}`
|
|
||||||
// *Note*: support for the deprecated `Action` signature will be removed in a future version
|
|
||||||
Action interface{}
|
|
||||||
|
|
||||||
// Execute this function if the proper command cannot be found
|
|
||||||
CommandNotFound CommandNotFoundFunc
|
|
||||||
// Execute this function if an usage error occurs
|
|
||||||
OnUsageError OnUsageErrorFunc
|
|
||||||
// Compilation date
|
|
||||||
Compiled time.Time
|
|
||||||
// List of all authors who contributed
|
|
||||||
Authors []Author
|
|
||||||
// Copyright of the binary if any
|
|
||||||
Copyright string
|
|
||||||
// Name of Author (Note: Use App.Authors, this is deprecated)
|
|
||||||
Author string
|
|
||||||
// Email of Author (Note: Use App.Authors, this is deprecated)
|
|
||||||
Email string
|
|
||||||
// Writer writer to write output to
|
|
||||||
Writer io.Writer
|
|
||||||
// ErrWriter writes error output
|
|
||||||
ErrWriter io.Writer
|
|
||||||
// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to
|
|
||||||
// function as a default, so this is optional.
|
|
||||||
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
|
|
||||||
// Boolean to enable short-option handling so user can combine several
|
|
||||||
// single-character bool arguements into one
|
|
||||||
// i.e. foobar -o -v -> foobar -ov
|
|
||||||
UseShortOptionHandling bool
|
|
||||||
|
|
||||||
didSetup bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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]),
|
|
||||||
HelpName: filepath.Base(os.Args[0]),
|
|
||||||
Usage: "A new cli application",
|
|
||||||
UsageText: "",
|
|
||||||
BashComplete: DefaultAppComplete,
|
|
||||||
Action: helpCommand.Action,
|
|
||||||
Compiled: compileTime(),
|
|
||||||
Writer: os.Stdout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.Author != "" || a.Email != "" {
|
|
||||||
a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
|
|
||||||
}
|
|
||||||
|
|
||||||
var newCmds []Command
|
|
||||||
for _, c := range a.Commands {
|
|
||||||
if c.HelpName == "" {
|
|
||||||
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
|
|
||||||
}
|
|
||||||
newCmds = append(newCmds, c)
|
|
||||||
}
|
|
||||||
a.Commands = newCmds
|
|
||||||
|
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
|
||||||
a.Commands = append(a.Commands, helpCommand)
|
|
||||||
if (HelpFlag != BoolFlag{}) {
|
|
||||||
a.appendFlag(HelpFlag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Version == "" {
|
|
||||||
a.HideVersion = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if !a.HideVersion {
|
|
||||||
a.appendFlag(VersionFlag)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.categories = CommandCategories{}
|
|
||||||
for _, command := range a.Commands {
|
|
||||||
a.categories = a.categories.AddCommand(command.Category, command)
|
|
||||||
}
|
|
||||||
sort.Sort(a.categories)
|
|
||||||
|
|
||||||
if a.Metadata == nil {
|
|
||||||
a.Metadata = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Writer == nil {
|
|
||||||
a.Writer = os.Stdout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
|
||||||
return flagSet(a.Name, a.Flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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)
|
|
||||||
|
|
||||||
set, err := a.newFlagSet()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parseIter(set, a, arguments[1:], shellComplete)
|
|
||||||
nerr := normalizeFlags(a.Flags, set)
|
|
||||||
context := NewContext(a, set, nil)
|
|
||||||
if nerr != nil {
|
|
||||||
_, _ = fmt.Fprintln(a.Writer, nerr)
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
return nerr
|
|
||||||
}
|
|
||||||
context.shellComplete = shellComplete
|
|
||||||
|
|
||||||
if checkCompletions(context) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if a.OnUsageError != nil {
|
|
||||||
err := a.OnUsageError(context, err, false)
|
|
||||||
a.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !a.HideHelp && checkHelp(context) {
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !a.HideVersion && checkVersion(context) {
|
|
||||||
ShowVersion(context)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cerr := checkRequiredFlags(a.Flags, context)
|
|
||||||
if cerr != nil {
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.After != nil && !context.shellComplete {
|
|
||||||
defer func() {
|
|
||||||
if afterErr := a.After(context); afterErr != nil {
|
|
||||||
if err != nil {
|
|
||||||
err = NewMultiError(err, afterErr)
|
|
||||||
} else {
|
|
||||||
err = afterErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Before != nil && !context.shellComplete {
|
|
||||||
beforeErr := a.Before(context)
|
|
||||||
if beforeErr != nil {
|
|
||||||
a.handleExitCoder(context, beforeErr)
|
|
||||||
err = beforeErr
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := context.Args()
|
|
||||||
if args.Present() {
|
|
||||||
name := args.First()
|
|
||||||
c := a.Command(name)
|
|
||||||
if c != nil {
|
|
||||||
return c.Run(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Action == nil {
|
|
||||||
a.Action = helpCommand.Action
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run default Action
|
|
||||||
err = HandleAction(a.Action, context)
|
|
||||||
|
|
||||||
a.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 eror
|
|
||||||
// code in the cli.ExitCoder
|
|
||||||
func (a *App) RunAndExitOnError() {
|
|
||||||
if err := a.Run(os.Args); err != nil {
|
|
||||||
_, _ = fmt.Fprintln(a.errWriter(), err)
|
|
||||||
OsExiter(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to
|
|
||||||
// generate command-specific flags
|
|
||||||
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|
||||||
// append help to commands
|
|
||||||
if len(a.Commands) > 0 {
|
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
|
||||||
a.Commands = append(a.Commands, helpCommand)
|
|
||||||
if (HelpFlag != BoolFlag{}) {
|
|
||||||
a.appendFlag(HelpFlag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newCmds := []Command{}
|
|
||||||
for _, c := range a.Commands {
|
|
||||||
if c.HelpName == "" {
|
|
||||||
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
|
|
||||||
}
|
|
||||||
newCmds = append(newCmds, c)
|
|
||||||
}
|
|
||||||
a.Commands = newCmds
|
|
||||||
|
|
||||||
set, err := a.newFlagSet()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete)
|
|
||||||
nerr := normalizeFlags(a.Flags, set)
|
|
||||||
context := NewContext(a, set, ctx)
|
|
||||||
|
|
||||||
if nerr != nil {
|
|
||||||
_, _ = fmt.Fprintln(a.Writer, nerr)
|
|
||||||
_, _ = fmt.Fprintln(a.Writer)
|
|
||||||
if len(a.Commands) > 0 {
|
|
||||||
_ = ShowSubcommandHelp(context)
|
|
||||||
} else {
|
|
||||||
_ = ShowCommandHelp(ctx, context.Args().First())
|
|
||||||
}
|
|
||||||
return nerr
|
|
||||||
}
|
|
||||||
|
|
||||||
if checkCompletions(context) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if a.OnUsageError != nil {
|
|
||||||
err = a.OnUsageError(context, err, true)
|
|
||||||
a.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
|
||||||
_ = ShowSubcommandHelp(context)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(a.Commands) > 0 {
|
|
||||||
if checkSubcommandHelp(context) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if checkCommandHelp(ctx, context.Args().First()) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cerr := checkRequiredFlags(a.Flags, context)
|
|
||||||
if cerr != nil {
|
|
||||||
_ = ShowSubcommandHelp(context)
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.After != nil && !context.shellComplete {
|
|
||||||
defer func() {
|
|
||||||
afterErr := a.After(context)
|
|
||||||
if afterErr != nil {
|
|
||||||
a.handleExitCoder(context, err)
|
|
||||||
if err != nil {
|
|
||||||
err = NewMultiError(err, afterErr)
|
|
||||||
} else {
|
|
||||||
err = afterErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Before != nil && !context.shellComplete {
|
|
||||||
beforeErr := a.Before(context)
|
|
||||||
if beforeErr != nil {
|
|
||||||
a.handleExitCoder(context, beforeErr)
|
|
||||||
err = beforeErr
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := context.Args()
|
|
||||||
if args.Present() {
|
|
||||||
name := args.First()
|
|
||||||
c := a.Command(name)
|
|
||||||
if c != nil {
|
|
||||||
return c.Run(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run default Action
|
|
||||||
err = HandleAction(a.Action, context)
|
|
||||||
|
|
||||||
a.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command returns the named command on App. Returns nil if the command does not exist
|
|
||||||
func (a *App) Command(name string) *Command {
|
|
||||||
for _, c := range a.Commands {
|
|
||||||
if c.HasName(name) {
|
|
||||||
return &c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Categories returns a slice containing all the categories with the commands they contain
|
|
||||||
func (a *App) Categories() CommandCategories {
|
|
||||||
return a.categories
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisibleCategories returns a slice of categories and commands that are
|
|
||||||
// Hidden=false
|
|
||||||
func (a *App) VisibleCategories() []*CommandCategory {
|
|
||||||
ret := []*CommandCategory{}
|
|
||||||
for _, category := range a.categories {
|
|
||||||
if visible := func() *CommandCategory {
|
|
||||||
for _, command := range category.Commands {
|
|
||||||
if !command.Hidden {
|
|
||||||
return category
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
|
||||||
func (a *App) VisibleFlags() []Flag {
|
|
||||||
return visibleFlags(a.Flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) hasFlag(flag Flag) bool {
|
|
||||||
for _, f := range a.Flags {
|
|
||||||
if flag == f {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) errWriter() io.Writer {
|
|
||||||
// When the app ErrWriter is nil use the package level one.
|
|
||||||
if a.ErrWriter == nil {
|
|
||||||
return ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) appendFlag(flag Flag) {
|
|
||||||
if !a.hasFlag(flag) {
|
|
||||||
a.Flags = append(a.Flags, flag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) handleExitCoder(context *Context, err error) {
|
|
||||||
if a.ExitErrHandler != nil {
|
|
||||||
a.ExitErrHandler(context, err)
|
|
||||||
} else {
|
|
||||||
HandleExitCoder(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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{}, context *Context) (err error) {
|
|
||||||
switch a := action.(type) {
|
|
||||||
case ActionFunc:
|
|
||||||
return a(context)
|
|
||||||
case func(*Context) error:
|
|
||||||
return a(context)
|
|
||||||
case func(*Context): // deprecated function signature
|
|
||||||
a(context)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return errInvalidActionType
|
|
||||||
}
|
|
44
vendor/github.com/urfave/cli/category.go
generated
vendored
44
vendor/github.com/urfave/cli/category.go
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
// CommandCategories is a slice of *CommandCategory.
|
|
||||||
type CommandCategories []*CommandCategory
|
|
||||||
|
|
||||||
// CommandCategory is a category containing commands.
|
|
||||||
type CommandCategory struct {
|
|
||||||
Name string
|
|
||||||
Commands Commands
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c CommandCategories) Less(i, j int) bool {
|
|
||||||
return lexicographicLess(c[i].Name, c[j].Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c CommandCategories) Len() int {
|
|
||||||
return len(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c CommandCategories) Swap(i, j int) {
|
|
||||||
c[i], c[j] = c[j], c[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddCommand adds a command to a category.
|
|
||||||
func (c CommandCategories) AddCommand(category string, command Command) CommandCategories {
|
|
||||||
for _, commandCategory := range c {
|
|
||||||
if commandCategory.Name == category {
|
|
||||||
commandCategory.Commands = append(commandCategory.Commands, command)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return append(c, &CommandCategory{Name: category, Commands: []Command{command}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
|
||||||
func (c *CommandCategory) VisibleCommands() []Command {
|
|
||||||
ret := []Command{}
|
|
||||||
for _, command := range c.Commands {
|
|
||||||
if !command.Hidden {
|
|
||||||
ret = append(ret, command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
22
vendor/github.com/urfave/cli/cli.go
generated
vendored
22
vendor/github.com/urfave/cli/cli.go
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
// Package cli provides a minimal framework for creating and organizing command line
|
|
||||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
|
||||||
// cli application can be written as follows:
|
|
||||||
// func main() {
|
|
||||||
// cli.NewApp().Run(os.Args)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Of course this application does not do much, so let's make this an actual application:
|
|
||||||
// func main() {
|
|
||||||
// app := cli.NewApp()
|
|
||||||
// app.Name = "greet"
|
|
||||||
// app.Usage = "say a greeting"
|
|
||||||
// app.Action = func(c *cli.Context) error {
|
|
||||||
// println("Greetings")
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// app.Run(os.Args)
|
|
||||||
// }
|
|
||||||
package cli
|
|
||||||
|
|
||||||
//go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go
|
|
386
vendor/github.com/urfave/cli/command.go
generated
vendored
386
vendor/github.com/urfave/cli/command.go
generated
vendored
@ -1,386 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Command is a subcommand for a cli.App.
|
|
||||||
type Command struct {
|
|
||||||
// The name of the command
|
|
||||||
Name string
|
|
||||||
// short name of the command. Typically one character (deprecated, use `Aliases`)
|
|
||||||
ShortName string
|
|
||||||
// A list of aliases for the command
|
|
||||||
Aliases []string
|
|
||||||
// A short description of the usage of this command
|
|
||||||
Usage string
|
|
||||||
// Custom text to show on USAGE section of help
|
|
||||||
UsageText string
|
|
||||||
// A longer explanation of how the command works
|
|
||||||
Description string
|
|
||||||
// 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 interface{}
|
|
||||||
// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
|
|
||||||
// of deprecation period has passed, maybe?
|
|
||||||
|
|
||||||
// Execute this function if a usage error occurs.
|
|
||||||
OnUsageError OnUsageErrorFunc
|
|
||||||
// List of child commands
|
|
||||||
Subcommands Commands
|
|
||||||
// List of flags to parse
|
|
||||||
Flags []Flag
|
|
||||||
// Treat all flags as normal arguments if true
|
|
||||||
SkipFlagParsing bool
|
|
||||||
// Skip argument reordering which attempts to move flags before arguments,
|
|
||||||
// but only works if all flags appear after all arguments. This behavior was
|
|
||||||
// removed n version 2 since it only works under specific conditions so we
|
|
||||||
// backport here by exposing it as an option for compatibility.
|
|
||||||
SkipArgReorder bool
|
|
||||||
// Boolean to hide built-in help command
|
|
||||||
HideHelp bool
|
|
||||||
// Boolean to hide this command from help or completion
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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, " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commands is a slice of Command
|
|
||||||
type Commands []Command
|
|
||||||
|
|
||||||
// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags
|
|
||||||
func (c Command) Run(ctx *Context) (err error) {
|
|
||||||
if !c.SkipFlagParsing {
|
|
||||||
if len(c.Subcommands) > 0 {
|
|
||||||
return c.startApp(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.HideHelp && (HelpFlag != BoolFlag{}) {
|
|
||||||
// append help to flags
|
|
||||||
c.Flags = append(
|
|
||||||
c.Flags,
|
|
||||||
HelpFlag,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.App.UseShortOptionHandling {
|
|
||||||
c.UseShortOptionHandling = true
|
|
||||||
}
|
|
||||||
|
|
||||||
set, err := c.parseFlags(ctx.Args().Tail(), ctx.shellComplete)
|
|
||||||
|
|
||||||
context := NewContext(ctx.App, set, ctx)
|
|
||||||
context.Command = c
|
|
||||||
if checkCommandCompletions(context, c.Name) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if c.OnUsageError != nil {
|
|
||||||
err := c.OnUsageError(context, err, false)
|
|
||||||
context.App.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, _ = fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
|
|
||||||
_, _ = fmt.Fprintln(context.App.Writer)
|
|
||||||
_ = ShowCommandHelp(context, c.Name)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if checkCommandHelp(context, c.Name) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cerr := checkRequiredFlags(c.Flags, context)
|
|
||||||
if cerr != nil {
|
|
||||||
_ = ShowCommandHelp(context, c.Name)
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.After != nil {
|
|
||||||
defer func() {
|
|
||||||
afterErr := c.After(context)
|
|
||||||
if afterErr != nil {
|
|
||||||
context.App.handleExitCoder(context, err)
|
|
||||||
if err != nil {
|
|
||||||
err = NewMultiError(err, afterErr)
|
|
||||||
} else {
|
|
||||||
err = afterErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Before != nil {
|
|
||||||
err = c.Before(context)
|
|
||||||
if err != nil {
|
|
||||||
context.App.handleExitCoder(context, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Action == nil {
|
|
||||||
c.Action = helpSubcommand.Action
|
|
||||||
}
|
|
||||||
|
|
||||||
err = HandleAction(c.Action, context)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
context.App.handleExitCoder(context, err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) {
|
|
||||||
if c.SkipFlagParsing {
|
|
||||||
set, err := c.newFlagSet()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return set, set.Parse(append([]string{"--"}, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.SkipArgReorder {
|
|
||||||
args = reorderArgs(c.Flags, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
set, err := c.newFlagSet()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parseIter(set, c, args, shellComplete)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = normalizeFlags(c.Flags, set)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return set, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Command) newFlagSet() (*flag.FlagSet, error) {
|
|
||||||
return flagSet(c.Name, c.Flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Command) useShortOptionHandling() bool {
|
|
||||||
return c.UseShortOptionHandling
|
|
||||||
}
|
|
||||||
|
|
||||||
// reorderArgs moves all flags (via reorderedArgs) before the rest of
|
|
||||||
// the arguments (remainingArgs) as this is what flag expects.
|
|
||||||
func reorderArgs(commandFlags []Flag, args []string) []string {
|
|
||||||
var remainingArgs, reorderedArgs []string
|
|
||||||
|
|
||||||
nextIndexMayContainValue := false
|
|
||||||
for i, arg := range args {
|
|
||||||
|
|
||||||
// if we're expecting an option-value, check if this arg is a value, in
|
|
||||||
// which case it should be re-ordered next to its associated flag
|
|
||||||
if nextIndexMayContainValue && !argIsFlag(commandFlags, arg) {
|
|
||||||
nextIndexMayContainValue = false
|
|
||||||
reorderedArgs = append(reorderedArgs, arg)
|
|
||||||
} else if arg == "--" {
|
|
||||||
// don't reorder any args after the -- delimiter As described in the POSIX spec:
|
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02
|
|
||||||
// > Guideline 10:
|
|
||||||
// > The first -- argument that is not an option-argument should be accepted
|
|
||||||
// > as a delimiter indicating the end of options. Any following arguments
|
|
||||||
// > should be treated as operands, even if they begin with the '-' character.
|
|
||||||
|
|
||||||
// make sure the "--" delimiter itself is at the start
|
|
||||||
remainingArgs = append([]string{"--"}, remainingArgs...)
|
|
||||||
remainingArgs = append(remainingArgs, args[i+1:]...)
|
|
||||||
break
|
|
||||||
// checks if this is an arg that should be re-ordered
|
|
||||||
} else if argIsFlag(commandFlags, arg) {
|
|
||||||
// we have determined that this is a flag that we should re-order
|
|
||||||
reorderedArgs = append(reorderedArgs, arg)
|
|
||||||
// if this arg does not contain a "=", then the next index may contain the value for this flag
|
|
||||||
nextIndexMayContainValue = !strings.Contains(arg, "=")
|
|
||||||
|
|
||||||
// simply append any remaining args
|
|
||||||
} else {
|
|
||||||
remainingArgs = append(remainingArgs, arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(reorderedArgs, remainingArgs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// argIsFlag checks if an arg is one of our command flags
|
|
||||||
func argIsFlag(commandFlags []Flag, arg string) bool {
|
|
||||||
if arg == "-" || arg == "--" {
|
|
||||||
// `-` is never a flag
|
|
||||||
// `--` is an option-value when following a flag, and a delimiter indicating the end of options in other cases.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// flags always start with a -
|
|
||||||
if !strings.HasPrefix(arg, "-") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// this line turns `--flag` into `flag`
|
|
||||||
if strings.HasPrefix(arg, "--") {
|
|
||||||
arg = strings.Replace(arg, "-", "", 2)
|
|
||||||
}
|
|
||||||
// this line turns `-flag` into `flag`
|
|
||||||
if strings.HasPrefix(arg, "-") {
|
|
||||||
arg = strings.Replace(arg, "-", "", 1)
|
|
||||||
}
|
|
||||||
// this line turns `flag=value` into `flag`
|
|
||||||
arg = strings.Split(arg, "=")[0]
|
|
||||||
// look through all the flags, to see if the `arg` is one of our flags
|
|
||||||
for _, flag := range commandFlags {
|
|
||||||
for _, key := range strings.Split(flag.GetName(), ",") {
|
|
||||||
key := strings.TrimSpace(key)
|
|
||||||
if key == arg {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// return false if this arg was not one of our flags
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Names returns the names including short names and aliases.
|
|
||||||
func (c Command) Names() []string {
|
|
||||||
names := []string{c.Name}
|
|
||||||
|
|
||||||
if c.ShortName != "" {
|
|
||||||
names = append(names, c.ShortName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(names, c.Aliases...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasName returns true if Command.Name or Command.ShortName matches given name
|
|
||||||
func (c Command) HasName(name string) bool {
|
|
||||||
for _, n := range c.Names() {
|
|
||||||
if n == name {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Command) startApp(ctx *Context) error {
|
|
||||||
app := NewApp()
|
|
||||||
app.Metadata = ctx.App.Metadata
|
|
||||||
app.ExitErrHandler = ctx.App.ExitErrHandler
|
|
||||||
// set the name and usage
|
|
||||||
app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
|
|
||||||
if c.HelpName == "" {
|
|
||||||
app.HelpName = c.HelpName
|
|
||||||
} else {
|
|
||||||
app.HelpName = app.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Usage = c.Usage
|
|
||||||
app.Description = c.Description
|
|
||||||
app.ArgsUsage = c.ArgsUsage
|
|
||||||
|
|
||||||
// set CommandNotFound
|
|
||||||
app.CommandNotFound = ctx.App.CommandNotFound
|
|
||||||
app.CustomAppHelpTemplate = c.CustomHelpTemplate
|
|
||||||
|
|
||||||
// set the flags and commands
|
|
||||||
app.Commands = c.Subcommands
|
|
||||||
app.Flags = c.Flags
|
|
||||||
app.HideHelp = c.HideHelp
|
|
||||||
|
|
||||||
app.Version = ctx.App.Version
|
|
||||||
app.HideVersion = ctx.App.HideVersion
|
|
||||||
app.Compiled = ctx.App.Compiled
|
|
||||||
app.Author = ctx.App.Author
|
|
||||||
app.Email = ctx.App.Email
|
|
||||||
app.Writer = ctx.App.Writer
|
|
||||||
app.ErrWriter = ctx.App.ErrWriter
|
|
||||||
app.UseShortOptionHandling = ctx.App.UseShortOptionHandling
|
|
||||||
|
|
||||||
app.categories = CommandCategories{}
|
|
||||||
for _, command := range c.Subcommands {
|
|
||||||
app.categories = app.categories.AddCommand(command.Category, command)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(app.categories)
|
|
||||||
|
|
||||||
// bash completion
|
|
||||||
app.EnableBashCompletion = ctx.App.EnableBashCompletion
|
|
||||||
if c.BashComplete != nil {
|
|
||||||
app.BashComplete = c.BashComplete
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the actions
|
|
||||||
app.Before = c.Before
|
|
||||||
app.After = c.After
|
|
||||||
if c.Action != nil {
|
|
||||||
app.Action = c.Action
|
|
||||||
} else {
|
|
||||||
app.Action = helpSubcommand.Action
|
|
||||||
}
|
|
||||||
app.OnUsageError = c.OnUsageError
|
|
||||||
|
|
||||||
for index, cc := range app.Commands {
|
|
||||||
app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.RunAsSubcommand(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
|
||||||
func (c Command) VisibleFlags() []Flag {
|
|
||||||
return visibleFlags(c.Flags)
|
|
||||||
}
|
|
348
vendor/github.com/urfave/cli/context.go
generated
vendored
348
vendor/github.com/urfave/cli/context.go
generated
vendored
@ -1,348 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Context is a type that is passed through to
|
|
||||||
// each Handler action in a cli application. Context
|
|
||||||
// can be used to retrieve context-specific Args and
|
|
||||||
// parsed command-line options.
|
|
||||||
type Context struct {
|
|
||||||
App *App
|
|
||||||
Command Command
|
|
||||||
shellComplete bool
|
|
||||||
flagSet *flag.FlagSet
|
|
||||||
setFlags map[string]bool
|
|
||||||
parentContext *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewContext creates a new context. For use in when invoking an App or Command action.
|
|
||||||
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
|
||||||
c := &Context{App: app, flagSet: set, parentContext: parentCtx}
|
|
||||||
|
|
||||||
if parentCtx != nil {
|
|
||||||
c.shellComplete = parentCtx.shellComplete
|
|
||||||
}
|
|
||||||
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// NumFlags returns the number of flags set
|
|
||||||
func (c *Context) NumFlags() int {
|
|
||||||
return c.flagSet.NFlag()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets a context flag to a value.
|
|
||||||
func (c *Context) Set(name, value string) error {
|
|
||||||
c.setFlags = nil
|
|
||||||
return c.flagSet.Set(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalSet sets a context flag to a value on the global flagset
|
|
||||||
func (c *Context) GlobalSet(name, value string) error {
|
|
||||||
globalContext(c).setFlags = nil
|
|
||||||
return globalContext(c).flagSet.Set(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSet determines if the flag was actually set
|
|
||||||
func (c *Context) IsSet(name string) bool {
|
|
||||||
if c.setFlags == nil {
|
|
||||||
c.setFlags = make(map[string]bool)
|
|
||||||
|
|
||||||
c.flagSet.Visit(func(f *flag.Flag) {
|
|
||||||
c.setFlags[f.Name] = true
|
|
||||||
})
|
|
||||||
|
|
||||||
c.flagSet.VisitAll(func(f *flag.Flag) {
|
|
||||||
if _, ok := c.setFlags[f.Name]; ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.setFlags[f.Name] = false
|
|
||||||
})
|
|
||||||
|
|
||||||
// XXX hack to support IsSet for flags with EnvVar
|
|
||||||
//
|
|
||||||
// There isn't an easy way to do this with the current implementation since
|
|
||||||
// whether a flag was set via an environment variable is very difficult to
|
|
||||||
// determine here. Instead, we intend to introduce a backwards incompatible
|
|
||||||
// change in version 2 to add `IsSet` to the Flag interface to push the
|
|
||||||
// responsibility closer to where the information required to determine
|
|
||||||
// whether a flag is set by non-standard means such as environment
|
|
||||||
// variables is available.
|
|
||||||
//
|
|
||||||
// See https://github.com/urfave/cli/issues/294 for additional discussion
|
|
||||||
flags := c.Command.Flags
|
|
||||||
if c.Command.Name == "" { // cannot == Command{} since it contains slice types
|
|
||||||
if c.App != nil {
|
|
||||||
flags = c.App.Flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, f := range flags {
|
|
||||||
eachName(f.GetName(), func(name string) {
|
|
||||||
if isSet, ok := c.setFlags[name]; isSet || !ok {
|
|
||||||
// Check if a flag is set
|
|
||||||
if isSet {
|
|
||||||
// If the flag is set, also set its other aliases
|
|
||||||
eachName(f.GetName(), func(name string) {
|
|
||||||
c.setFlags[name] = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val := reflect.ValueOf(f)
|
|
||||||
if val.Kind() == reflect.Ptr {
|
|
||||||
val = val.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
filePathValue := val.FieldByName("FilePath")
|
|
||||||
if filePathValue.IsValid() {
|
|
||||||
eachName(filePathValue.String(), func(filePath string) {
|
|
||||||
if _, err := os.Stat(filePath); err == nil {
|
|
||||||
c.setFlags[name] = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarValue := val.FieldByName("EnvVar")
|
|
||||||
if envVarValue.IsValid() {
|
|
||||||
eachName(envVarValue.String(), func(envVar string) {
|
|
||||||
envVar = strings.TrimSpace(envVar)
|
|
||||||
if _, ok := syscall.Getenv(envVar); ok {
|
|
||||||
c.setFlags[name] = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.setFlags[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalIsSet determines if the global flag was actually set
|
|
||||||
func (c *Context) GlobalIsSet(name string) bool {
|
|
||||||
ctx := c
|
|
||||||
if ctx.parentContext != nil {
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
|
|
||||||
for ; ctx != nil; ctx = ctx.parentContext {
|
|
||||||
if ctx.IsSet(name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// FlagNames returns a slice of flag names used in this context.
|
|
||||||
func (c *Context) FlagNames() (names []string) {
|
|
||||||
for _, f := range c.Command.Flags {
|
|
||||||
name := strings.Split(f.GetName(), ",")[0]
|
|
||||||
if name == "help" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalFlagNames returns a slice of global flag names used by the app.
|
|
||||||
func (c *Context) GlobalFlagNames() (names []string) {
|
|
||||||
for _, f := range c.App.Flags {
|
|
||||||
name := strings.Split(f.GetName(), ",")[0]
|
|
||||||
if name == "help" || name == "version" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parent returns the parent context, if any
|
|
||||||
func (c *Context) Parent() *Context {
|
|
||||||
return c.parentContext
|
|
||||||
}
|
|
||||||
|
|
||||||
// value returns the value of the flag coressponding to `name`
|
|
||||||
func (c *Context) value(name string) interface{} {
|
|
||||||
return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args contains apps console arguments
|
|
||||||
type Args []string
|
|
||||||
|
|
||||||
// Args returns the command line arguments associated with the context.
|
|
||||||
func (c *Context) Args() Args {
|
|
||||||
args := Args(c.flagSet.Args())
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
// NArg returns the number of the command line arguments.
|
|
||||||
func (c *Context) NArg() int {
|
|
||||||
return len(c.Args())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the nth argument, or else a blank string
|
|
||||||
func (a Args) Get(n int) string {
|
|
||||||
if len(a) > n {
|
|
||||||
return a[n]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// First returns the first argument, or else a blank string
|
|
||||||
func (a Args) First() string {
|
|
||||||
return a.Get(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tail returns the rest of the arguments (not the first one)
|
|
||||||
// or else an empty string slice
|
|
||||||
func (a Args) Tail() []string {
|
|
||||||
if len(a) >= 2 {
|
|
||||||
return []string(a)[1:]
|
|
||||||
}
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Present checks if there are any arguments present
|
|
||||||
func (a Args) Present() bool {
|
|
||||||
return len(a) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps arguments at the given indexes
|
|
||||||
func (a Args) Swap(from, to int) error {
|
|
||||||
if from >= len(a) || to >= len(a) {
|
|
||||||
return errors.New("index out of range")
|
|
||||||
}
|
|
||||||
a[from], a[to] = a[to], a[from]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func globalContext(ctx *Context) *Context {
|
|
||||||
if ctx == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
if ctx.parentContext == nil {
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
|
|
||||||
if ctx.parentContext != nil {
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
for ; ctx != nil; ctx = ctx.parentContext {
|
|
||||||
if f := ctx.flagSet.Lookup(name); f != nil {
|
|
||||||
return ctx.flagSet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
|
||||||
switch ff.Value.(type) {
|
|
||||||
case *StringSlice:
|
|
||||||
default:
|
|
||||||
_ = set.Set(name, ff.Value.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
|
||||||
visited := make(map[string]bool)
|
|
||||||
set.Visit(func(f *flag.Flag) {
|
|
||||||
visited[f.Name] = true
|
|
||||||
})
|
|
||||||
for _, f := range flags {
|
|
||||||
parts := strings.Split(f.GetName(), ",")
|
|
||||||
if len(parts) == 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var ff *flag.Flag
|
|
||||||
for _, name := range parts {
|
|
||||||
name = strings.Trim(name, " ")
|
|
||||||
if visited[name] {
|
|
||||||
if ff != nil {
|
|
||||||
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
|
||||||
}
|
|
||||||
ff = set.Lookup(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ff == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, name := range parts {
|
|
||||||
name = strings.Trim(name, " ")
|
|
||||||
if !visited[name] {
|
|
||||||
copyFlag(name, ff, set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type requiredFlagsErr interface {
|
|
||||||
error
|
|
||||||
getMissingFlags() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type errRequiredFlags struct {
|
|
||||||
missingFlags []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *errRequiredFlags) Error() string {
|
|
||||||
numberOfMissingFlags := len(e.missingFlags)
|
|
||||||
if numberOfMissingFlags == 1 {
|
|
||||||
return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
|
|
||||||
}
|
|
||||||
joinedMissingFlags := strings.Join(e.missingFlags, ", ")
|
|
||||||
return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *errRequiredFlags) getMissingFlags() []string {
|
|
||||||
return e.missingFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr {
|
|
||||||
var missingFlags []string
|
|
||||||
for _, f := range flags {
|
|
||||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
|
||||||
var flagPresent bool
|
|
||||||
var flagName string
|
|
||||||
for _, key := range strings.Split(f.GetName(), ",") {
|
|
||||||
key = strings.TrimSpace(key)
|
|
||||||
if len(key) > 1 {
|
|
||||||
flagName = key
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.IsSet(key) {
|
|
||||||
flagPresent = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !flagPresent && flagName != "" {
|
|
||||||
missingFlags = append(missingFlags, flagName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(missingFlags) != 0 {
|
|
||||||
return &errRequiredFlags{missingFlags: missingFlags}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
115
vendor/github.com/urfave/cli/errors.go
generated
vendored
115
vendor/github.com/urfave/cli/errors.go
generated
vendored
@ -1,115 +0,0 @@
|
|||||||
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 struct {
|
|
||||||
Errors []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMultiError creates a new MultiError. Pass in one or more errors.
|
|
||||||
func NewMultiError(err ...error) MultiError {
|
|
||||||
return MultiError{Errors: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error implements the error interface.
|
|
||||||
func (m MultiError) Error() string {
|
|
||||||
errs := make([]string, len(m.Errors))
|
|
||||||
for i, err := range m.Errors {
|
|
||||||
errs[i] = err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(errs, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExitError fulfills both the builtin `error` interface and `ExitCoder`
|
|
||||||
type ExitError struct {
|
|
||||||
exitCode int
|
|
||||||
message interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewExitError makes a new *ExitError
|
|
||||||
func NewExitError(message interface{}, exitCode int) *ExitError {
|
|
||||||
return &ExitError{
|
|
||||||
exitCode: exitCode,
|
|
||||||
message: message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string message, fulfilling the interface required by
|
|
||||||
// `error`
|
|
||||||
func (ee *ExitError) Error() string {
|
|
||||||
return fmt.Sprintf("%v", ee.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExitCode returns the exit code, fulfilling the interface required by
|
|
||||||
// `ExitCoder`
|
|
||||||
func (ee *ExitError) ExitCode() int {
|
|
||||||
return ee.exitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
|
|
||||||
// so prints the error to stderr (if it is non-empty) and calls OsExiter with the
|
|
||||||
// given exit code. If the given error is a MultiError, then this func is
|
|
||||||
// called on all members of the Errors slice and calls OsExiter with the last exit code.
|
|
||||||
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 {
|
|
||||||
fmt.Fprintln(ErrWriter, merr)
|
|
||||||
if exitErr, ok := merr.(ExitCoder); ok {
|
|
||||||
code = exitErr.ExitCode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code
|
|
||||||
}
|
|
348
vendor/github.com/urfave/cli/flag.go
generated
vendored
348
vendor/github.com/urfave/cli/flag.go
generated
vendored
@ -1,348 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultPlaceholder = "value"
|
|
||||||
|
|
||||||
// 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, v",
|
|
||||||
Usage: "print the version",
|
|
||||||
}
|
|
||||||
|
|
||||||
// HelpFlag prints the help for all commands and subcommands
|
|
||||||
// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
|
|
||||||
// unless HideHelp is set to true)
|
|
||||||
var HelpFlag Flag = BoolFlag{
|
|
||||||
Name: "help, h",
|
|
||||||
Usage: "show help",
|
|
||||||
}
|
|
||||||
|
|
||||||
// FlagStringer converts a flag definition to a string. This is used by help
|
|
||||||
// to display a flag.
|
|
||||||
var FlagStringer FlagStringFunc = stringifyFlag
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
return lexicographicLess(f[i].GetName(), f[j].GetName())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f FlagsByName) Swap(i, j int) {
|
|
||||||
f[i], f[j] = f[j], f[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
GetName() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// errorableFlag is an interface that allows us to return errors during apply
|
|
||||||
// it allows flags defined in this library to return errors in a fashion backwards compatible
|
|
||||||
// TODO remove in v2 and modify the existing Flag interface to return errors
|
|
||||||
type errorableFlag interface {
|
|
||||||
Flag
|
|
||||||
|
|
||||||
ApplyWithError(*flag.FlagSet) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
|
||||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
|
||||||
|
|
||||||
for _, f := range flags {
|
|
||||||
//TODO remove in v2 when errorableFlag is removed
|
|
||||||
if ef, ok := f.(errorableFlag); ok {
|
|
||||||
if err := ef.ApplyWithError(set); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
f.Apply(set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set.SetOutput(ioutil.Discard)
|
|
||||||
return set, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func eachName(longName string, fn func(string)) {
|
|
||||||
parts := strings.Split(longName, ",")
|
|
||||||
for _, name := range parts {
|
|
||||||
name = strings.Trim(name, " ")
|
|
||||||
fn(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func visibleFlags(fl []Flag) []Flag {
|
|
||||||
var visible []Flag
|
|
||||||
for _, f := range fl {
|
|
||||||
field := flagValue(f).FieldByName("Hidden")
|
|
||||||
if !field.IsValid() || !field.Bool() {
|
|
||||||
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(fullName, placeholder string) string {
|
|
||||||
var prefixed string
|
|
||||||
parts := strings.Split(fullName, ",")
|
|
||||||
for i, name := range parts {
|
|
||||||
name = strings.Trim(name, " ")
|
|
||||||
prefixed += prefixFor(name) + name
|
|
||||||
if placeholder != "" {
|
|
||||||
prefixed += " " + placeholder
|
|
||||||
}
|
|
||||||
if i < len(parts)-1 {
|
|
||||||
prefixed += ", "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return prefixed
|
|
||||||
}
|
|
||||||
|
|
||||||
func withEnvHint(envVar, str string) string {
|
|
||||||
envText := ""
|
|
||||||
if envVar != "" {
|
|
||||||
prefix := "$"
|
|
||||||
suffix := ""
|
|
||||||
sep := ", $"
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
prefix = "%"
|
|
||||||
suffix = "%"
|
|
||||||
sep = "%, %"
|
|
||||||
}
|
|
||||||
envText = " [" + prefix + strings.Join(strings.Split(envVar, ","), sep) + suffix + "]"
|
|
||||||
}
|
|
||||||
return str + envText
|
|
||||||
}
|
|
||||||
|
|
||||||
func withFileHint(filePath, str string) string {
|
|
||||||
fileText := ""
|
|
||||||
if filePath != "" {
|
|
||||||
fileText = fmt.Sprintf(" [%s]", filePath)
|
|
||||||
}
|
|
||||||
return str + fileText
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagValue(f Flag) reflect.Value {
|
|
||||||
fv := reflect.ValueOf(f)
|
|
||||||
for fv.Kind() == reflect.Ptr {
|
|
||||||
fv = reflect.Indirect(fv)
|
|
||||||
}
|
|
||||||
return fv
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifyFlag(f Flag) string {
|
|
||||||
fv := flagValue(f)
|
|
||||||
|
|
||||||
switch f.(type) {
|
|
||||||
case IntSliceFlag:
|
|
||||||
return FlagFileHinter(
|
|
||||||
fv.FieldByName("FilePath").String(),
|
|
||||||
FlagEnvHinter(
|
|
||||||
fv.FieldByName("EnvVar").String(),
|
|
||||||
stringifyIntSliceFlag(f.(IntSliceFlag)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
case Int64SliceFlag:
|
|
||||||
return FlagFileHinter(
|
|
||||||
fv.FieldByName("FilePath").String(),
|
|
||||||
FlagEnvHinter(
|
|
||||||
fv.FieldByName("EnvVar").String(),
|
|
||||||
stringifyInt64SliceFlag(f.(Int64SliceFlag)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
case StringSliceFlag:
|
|
||||||
return FlagFileHinter(
|
|
||||||
fv.FieldByName("FilePath").String(),
|
|
||||||
FlagEnvHinter(
|
|
||||||
fv.FieldByName("EnvVar").String(),
|
|
||||||
stringifyStringSliceFlag(f.(StringSliceFlag)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String())
|
|
||||||
|
|
||||||
needsPlaceholder := false
|
|
||||||
defaultValueString := ""
|
|
||||||
|
|
||||||
if val := fv.FieldByName("Value"); val.IsValid() {
|
|
||||||
needsPlaceholder = true
|
|
||||||
defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
|
|
||||||
|
|
||||||
if val.Kind() == reflect.String && val.String() != "" {
|
|
||||||
defaultValueString = fmt.Sprintf(" (default: %q)", val.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if defaultValueString == " (default: )" {
|
|
||||||
defaultValueString = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if needsPlaceholder && placeholder == "" {
|
|
||||||
placeholder = defaultPlaceholder
|
|
||||||
}
|
|
||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
|
||||||
|
|
||||||
return FlagFileHinter(
|
|
||||||
fv.FieldByName("FilePath").String(),
|
|
||||||
FlagEnvHinter(
|
|
||||||
fv.FieldByName("EnvVar").String(),
|
|
||||||
FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder)+"\t"+usageWithDefault,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifyIntSliceFlag(f IntSliceFlag) 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 stringifySliceFlag(f.Usage, f.Name, defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifyInt64SliceFlag(f Int64SliceFlag) 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 stringifySliceFlag(f.Usage, f.Name, defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifyStringSliceFlag(f StringSliceFlag) 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 stringifySliceFlag(f.Usage, f.Name, defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringifySliceFlag(usage, name string, defaultVals []string) string {
|
|
||||||
placeholder, usage := unquoteUsage(usage)
|
|
||||||
if placeholder == "" {
|
|
||||||
placeholder = defaultPlaceholder
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultVal := ""
|
|
||||||
if len(defaultVals) > 0 {
|
|
||||||
defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", "))
|
|
||||||
}
|
|
||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(usage + defaultVal)
|
|
||||||
return FlagNamePrefixer(name, placeholder) + "\t" + usageWithDefault
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagFromFileEnv(filePath, envName string) (val string, ok bool) {
|
|
||||||
for _, envVar := range strings.Split(envName, ",") {
|
|
||||||
envVar = strings.TrimSpace(envVar)
|
|
||||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
|
||||||
return envVal, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, fileVar := range strings.Split(filePath, ",") {
|
|
||||||
if fileVar != "" {
|
|
||||||
if data, err := ioutil.ReadFile(fileVar); err == nil {
|
|
||||||
return string(data), true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", false
|
|
||||||
}
|
|
109
vendor/github.com/urfave/cli/flag_bool.go
generated
vendored
109
vendor/github.com/urfave/cli/flag_bool.go
generated
vendored
@ -1,109 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BoolFlag is a flag with type bool
|
|
||||||
type BoolFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Destination *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f BoolFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f BoolFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f BoolFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f BoolFlag) TakesValue() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f BoolFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f BoolFlag) GetValue() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool looks up the value of a local BoolFlag, returns
|
|
||||||
// false if not found
|
|
||||||
func (c *Context) Bool(name string) bool {
|
|
||||||
return lookupBool(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalBool looks up the value of a global BoolFlag, returns
|
|
||||||
// false if not found
|
|
||||||
func (c *Context) GlobalBool(name string) bool {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupBool(name, fs)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f BoolFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
val := false
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
if envVal == "" {
|
|
||||||
val = false
|
|
||||||
} else {
|
|
||||||
envValBool, err := strconv.ParseBool(envVal)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
val = envValBool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.BoolVar(f.Destination, name, val, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Bool(name, val, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := strconv.ParseBool(f.Value.String())
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
110
vendor/github.com/urfave/cli/flag_bool_t.go
generated
vendored
110
vendor/github.com/urfave/cli/flag_bool_t.go
generated
vendored
@ -1,110 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BoolTFlag is a flag with type bool that is true by default
|
|
||||||
type BoolTFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Destination *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f BoolTFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f BoolTFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f BoolTFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f BoolTFlag) TakesValue() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f BoolTFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f BoolTFlag) GetValue() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolT looks up the value of a local BoolTFlag, returns
|
|
||||||
// false if not found
|
|
||||||
func (c *Context) BoolT(name string) bool {
|
|
||||||
return lookupBoolT(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalBoolT looks up the value of a global BoolTFlag, returns
|
|
||||||
// false if not found
|
|
||||||
func (c *Context) GlobalBoolT(name string) bool {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupBoolT(name, fs)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f BoolTFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
val := true
|
|
||||||
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
if envVal == "" {
|
|
||||||
val = false
|
|
||||||
} else {
|
|
||||||
envValBool, err := strconv.ParseBool(envVal)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
val = envValBool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.BoolVar(f.Destination, name, val, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Bool(name, val, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupBoolT(name string, set *flag.FlagSet) bool {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := strconv.ParseBool(f.Value.String())
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
106
vendor/github.com/urfave/cli/flag_duration.go
generated
vendored
106
vendor/github.com/urfave/cli/flag_duration.go
generated
vendored
@ -1,106 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
|
|
||||||
type DurationFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value time.Duration
|
|
||||||
Destination *time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f DurationFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f DurationFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f DurationFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f DurationFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f DurationFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f DurationFlag) GetValue() string {
|
|
||||||
return f.Value.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Duration looks up the value of a local DurationFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Duration(name string) time.Duration {
|
|
||||||
return lookupDuration(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalDuration looks up the value of a global DurationFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalDuration(name string) time.Duration {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupDuration(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f DurationFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValDuration, err := time.ParseDuration(envVal)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Value = envValDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.DurationVar(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Duration(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := time.ParseDuration(f.Value.String())
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
106
vendor/github.com/urfave/cli/flag_float64.go
generated
vendored
106
vendor/github.com/urfave/cli/flag_float64.go
generated
vendored
@ -1,106 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Float64Flag is a flag with type float64
|
|
||||||
type Float64Flag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value float64
|
|
||||||
Destination *float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f Float64Flag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f Float64Flag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f Float64Flag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f Float64Flag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f Float64Flag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f Float64Flag) GetValue() string {
|
|
||||||
return fmt.Sprintf("%f", f.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 looks up the value of a local Float64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Float64(name string) float64 {
|
|
||||||
return lookupFloat64(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalFloat64 looks up the value of a global Float64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalFloat64(name string) float64 {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupFloat64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f Float64Flag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValFloat, err := strconv.ParseFloat(envVal, 10)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Value = envValFloat
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.Float64Var(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Float64(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
110
vendor/github.com/urfave/cli/flag_generic.go
generated
vendored
110
vendor/github.com/urfave/cli/flag_generic.go
generated
vendored
@ -1,110 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Generic is a generic parseable type identified by a specific flag
|
|
||||||
type Generic interface {
|
|
||||||
Set(value string) error
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenericFlag is a flag with type Generic
|
|
||||||
type GenericFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
TakesFile bool
|
|
||||||
Value Generic
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f GenericFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f GenericFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f GenericFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f GenericFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f GenericFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f GenericFlag) GetValue() string {
|
|
||||||
if f.Value != nil {
|
|
||||||
return f.Value.String()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply takes the flagset and calls Set on the generic flag with the value
|
|
||||||
// provided by the user for parsing by the flag
|
|
||||||
// Ignores parsing errors
|
|
||||||
func (f GenericFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError takes the flagset and calls Set on the generic flag with the value
|
|
||||||
// provided by the user for parsing by the flag
|
|
||||||
func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
val := f.Value
|
|
||||||
if fileEnvVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
if err := val.Set(fileEnvVal); err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as value for flag %s: %s", fileEnvVal, f.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
set.Var(f.Value, name, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic looks up the value of a local GenericFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) Generic(name string) interface{} {
|
|
||||||
return lookupGeneric(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalGeneric looks up the value of a global GenericFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) GlobalGeneric(name string) interface{} {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupGeneric(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := f.Value, error(nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
105
vendor/github.com/urfave/cli/flag_int.go
generated
vendored
105
vendor/github.com/urfave/cli/flag_int.go
generated
vendored
@ -1,105 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IntFlag is a flag with type int
|
|
||||||
type IntFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value int
|
|
||||||
Destination *int
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f IntFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f IntFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f IntFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f IntFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f IntFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f IntFlag) GetValue() string {
|
|
||||||
return fmt.Sprintf("%d", f.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f IntFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f IntFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValInt, err := strconv.ParseInt(envVal, 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
f.Value = int(envValInt)
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.IntVar(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Int(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int looks up the value of a local IntFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Int(name string) int {
|
|
||||||
return lookupInt(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalInt looks up the value of a global IntFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalInt(name string) int {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
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
|
|
||||||
}
|
|
106
vendor/github.com/urfave/cli/flag_int64.go
generated
vendored
106
vendor/github.com/urfave/cli/flag_int64.go
generated
vendored
@ -1,106 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Int64Flag is a flag with type int64
|
|
||||||
type Int64Flag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value int64
|
|
||||||
Destination *int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f Int64Flag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f Int64Flag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f Int64Flag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f Int64Flag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f Int64Flag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f Int64Flag) GetValue() string {
|
|
||||||
return fmt.Sprintf("%d", f.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f Int64Flag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValInt, err := strconv.ParseInt(envVal, 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Value = envValInt
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.Int64Var(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Int64(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 looks up the value of a local Int64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Int64(name string) int64 {
|
|
||||||
return lookupInt64(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalInt64 looks up the value of a global Int64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalInt64(name string) int64 {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
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
|
|
||||||
}
|
|
199
vendor/github.com/urfave/cli/flag_int64_slice.go
generated
vendored
199
vendor/github.com/urfave/cli/flag_int64_slice.go
generated
vendored
@ -1,199 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter
|
|
||||||
type Int64Slice []int64
|
|
||||||
|
|
||||||
// Set parses the value into an integer and appends it to the list of values
|
|
||||||
func (f *Int64Slice) Set(value string) error {
|
|
||||||
tmp, err := strconv.ParseInt(value, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*f = append(*f, tmp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
|
||||||
func (f *Int64Slice) String() string {
|
|
||||||
slice := make([]string, len(*f))
|
|
||||||
for i, v := range *f {
|
|
||||||
slice[i] = strconv.FormatInt(v, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(slice, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns the slice of ints set by this flag
|
|
||||||
func (f *Int64Slice) Value() []int64 {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the slice of ints set by this flag
|
|
||||||
func (f *Int64Slice) Get() interface{} {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64SliceFlag is a flag with type *Int64Slice
|
|
||||||
type Int64SliceFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value *Int64Slice
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f Int64SliceFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f Int64SliceFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f Int64SliceFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f Int64SliceFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f Int64SliceFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f Int64SliceFlag) GetValue() string {
|
|
||||||
if f.Value != nil {
|
|
||||||
return f.Value.String()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
newVal := &Int64Slice{}
|
|
||||||
for _, s := range strings.Split(envVal, ",") {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
if err := newVal.Set(s); err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = newVal
|
|
||||||
} else {
|
|
||||||
*f.Value = *newVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = &Int64Slice{}
|
|
||||||
}
|
|
||||||
set.Var(f.Value, name, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) Int64Slice(name string) []int64 {
|
|
||||||
return lookupInt64Slice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) GlobalInt64Slice(name string) []int64 {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupInt64Slice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
value, ok := f.Value.(*Int64Slice)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract the slice from asserted value
|
|
||||||
parsed := value.Value()
|
|
||||||
|
|
||||||
// extract default value from the flag
|
|
||||||
var defaultVal []int64
|
|
||||||
for _, v := range strings.Split(f.DefValue, ",") {
|
|
||||||
if v != "" {
|
|
||||||
int64Value, err := strconv.ParseInt(v, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defaultVal = append(defaultVal, int64Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if the current value is not equal to the default value
|
|
||||||
// remove the default values from the flag
|
|
||||||
if !isInt64SliceEqual(parsed, defaultVal) {
|
|
||||||
for _, v := range defaultVal {
|
|
||||||
parsed = removeFromInt64Slice(parsed, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeFromInt64Slice(slice []int64, val int64) []int64 {
|
|
||||||
for i, v := range slice {
|
|
||||||
if v == val {
|
|
||||||
ret := append([]int64{}, slice[:i]...)
|
|
||||||
ret = append(ret, slice[i+1:]...)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
func isInt64SliceEqual(newValue, defaultValue []int64) bool {
|
|
||||||
// If one is nil, the other must also be nil.
|
|
||||||
if (newValue == nil) != (defaultValue == nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(newValue) != len(defaultValue) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range newValue {
|
|
||||||
if v != defaultValue[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
198
vendor/github.com/urfave/cli/flag_int_slice.go
generated
vendored
198
vendor/github.com/urfave/cli/flag_int_slice.go
generated
vendored
@ -1,198 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter
|
|
||||||
type IntSlice []int
|
|
||||||
|
|
||||||
// Set parses the value into an integer and appends it to the list of values
|
|
||||||
func (f *IntSlice) Set(value string) error {
|
|
||||||
tmp, err := strconv.Atoi(value)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*f = append(*f, tmp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
|
||||||
func (f *IntSlice) String() string {
|
|
||||||
slice := make([]string, len(*f))
|
|
||||||
for i, v := range *f {
|
|
||||||
slice[i] = strconv.Itoa(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(slice, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns the slice of ints set by this flag
|
|
||||||
func (f *IntSlice) Value() []int {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the slice of ints set by this flag
|
|
||||||
func (f *IntSlice) Get() interface{} {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSliceFlag is a flag with type *IntSlice
|
|
||||||
type IntSliceFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value *IntSlice
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f IntSliceFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f IntSliceFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f IntSliceFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f IntSliceFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f IntSliceFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f IntSliceFlag) GetValue() string {
|
|
||||||
if f.Value != nil {
|
|
||||||
return f.Value.String()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f IntSliceFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
newVal := &IntSlice{}
|
|
||||||
for _, s := range strings.Split(envVal, ",") {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
if err := newVal.Set(s); err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = newVal
|
|
||||||
} else {
|
|
||||||
*f.Value = *newVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = &IntSlice{}
|
|
||||||
}
|
|
||||||
set.Var(f.Value, name, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) IntSlice(name string) []int {
|
|
||||||
return lookupIntSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalIntSlice looks up the value of a global IntSliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) GlobalIntSlice(name string) []int {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupIntSlice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
value, ok := f.Value.(*IntSlice)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// extract the slice from asserted value
|
|
||||||
slice := value.Value()
|
|
||||||
|
|
||||||
// extract default value from the flag
|
|
||||||
var defaultVal []int
|
|
||||||
for _, v := range strings.Split(f.DefValue, ",") {
|
|
||||||
if v != "" {
|
|
||||||
intValue, err := strconv.Atoi(v)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defaultVal = append(defaultVal, intValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if the current value is not equal to the default value
|
|
||||||
// remove the default values from the flag
|
|
||||||
if !isIntSliceEqual(slice, defaultVal) {
|
|
||||||
for _, v := range defaultVal {
|
|
||||||
slice = removeFromIntSlice(slice, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeFromIntSlice(slice []int, val int) []int {
|
|
||||||
for i, v := range slice {
|
|
||||||
if v == val {
|
|
||||||
ret := append([]int{}, slice[:i]...)
|
|
||||||
ret = append(ret, slice[i+1:]...)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
func isIntSliceEqual(newValue, defaultValue []int) bool {
|
|
||||||
// If one is nil, the other must also be nil.
|
|
||||||
if (newValue == nil) != (defaultValue == nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(newValue) != len(defaultValue) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range newValue {
|
|
||||||
if v != defaultValue[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
98
vendor/github.com/urfave/cli/flag_string.go
generated
vendored
98
vendor/github.com/urfave/cli/flag_string.go
generated
vendored
@ -1,98 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import "flag"
|
|
||||||
|
|
||||||
// StringFlag is a flag with type string
|
|
||||||
type StringFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
TakesFile bool
|
|
||||||
Value string
|
|
||||||
Destination *string
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f StringFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f StringFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f StringFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f StringFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f StringFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
f.Value = envVal
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.String(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String looks up the value of a local StringFlag, returns
|
|
||||||
// "" if not found
|
|
||||||
func (c *Context) String(name string) string {
|
|
||||||
return lookupString(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalString looks up the value of a global StringFlag, returns
|
|
||||||
// "" if not found
|
|
||||||
func (c *Context) GlobalString(name string) string {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupString(name, fs)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupString(name string, set *flag.FlagSet) string {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
parsed, err := f.Value.String(), error(nil)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
184
vendor/github.com/urfave/cli/flag_string_slice.go
generated
vendored
184
vendor/github.com/urfave/cli/flag_string_slice.go
generated
vendored
@ -1,184 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter
|
|
||||||
type StringSlice []string
|
|
||||||
|
|
||||||
// Set appends the string value to the list of values
|
|
||||||
func (f *StringSlice) Set(value string) error {
|
|
||||||
*f = append(*f, value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
|
||||||
func (f *StringSlice) String() string {
|
|
||||||
return strings.Join(*f, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns the slice of strings set by this flag
|
|
||||||
func (f *StringSlice) Value() []string {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the slice of strings set by this flag
|
|
||||||
func (f *StringSlice) Get() interface{} {
|
|
||||||
return *f
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSliceFlag is a flag with type *StringSlice
|
|
||||||
type StringSliceFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
TakesFile bool
|
|
||||||
Value *StringSlice
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f StringSliceFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f StringSliceFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f StringSliceFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f StringSliceFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f StringSliceFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f StringSliceFlag) GetValue() string {
|
|
||||||
if f.Value != nil {
|
|
||||||
return f.Value.String()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f StringSliceFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
newVal := &StringSlice{}
|
|
||||||
for _, s := range strings.Split(envVal, ",") {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
if err := newVal.Set(s); err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = newVal
|
|
||||||
} else {
|
|
||||||
*f.Value = *newVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Value == nil {
|
|
||||||
f.Value = &StringSlice{}
|
|
||||||
}
|
|
||||||
set.Var(f.Value, name, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) StringSlice(name string) []string {
|
|
||||||
return lookupStringSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalStringSlice looks up the value of a global StringSliceFlag, returns
|
|
||||||
// nil if not found
|
|
||||||
func (c *Context) GlobalStringSlice(name string) []string {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupStringSlice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
|
||||||
value, ok := f.Value.(*StringSlice)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// extract the slice from asserted value
|
|
||||||
slice := value.Value()
|
|
||||||
|
|
||||||
// extract default value from the flag
|
|
||||||
var defaultVal []string
|
|
||||||
for _, v := range strings.Split(f.DefValue, ",") {
|
|
||||||
defaultVal = append(defaultVal, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the current value is not equal to the default value
|
|
||||||
// remove the default values from the flag
|
|
||||||
if !isStringSliceEqual(slice, defaultVal) {
|
|
||||||
for _, v := range defaultVal {
|
|
||||||
slice = removeFromStringSlice(slice, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeFromStringSlice(slice []string, val string) []string {
|
|
||||||
for i, v := range slice {
|
|
||||||
if v == val {
|
|
||||||
ret := append([]string{}, slice[:i]...)
|
|
||||||
ret = append(ret, slice[i+1:]...)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
func isStringSliceEqual(newValue, defaultValue []string) bool {
|
|
||||||
// If one is nil, the other must also be nil.
|
|
||||||
if (newValue == nil) != (defaultValue == nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(newValue) != len(defaultValue) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range newValue {
|
|
||||||
if v != defaultValue[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
106
vendor/github.com/urfave/cli/flag_uint.go
generated
vendored
106
vendor/github.com/urfave/cli/flag_uint.go
generated
vendored
@ -1,106 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UintFlag is a flag with type uint
|
|
||||||
type UintFlag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value uint
|
|
||||||
Destination *uint
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f UintFlag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f UintFlag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f UintFlag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f UintFlag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f UintFlag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f UintFlag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f UintFlag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValInt, err := strconv.ParseUint(envVal, 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Value = uint(envValInt)
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.UintVar(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Uint(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f UintFlag) GetValue() string {
|
|
||||||
return fmt.Sprintf("%d", f.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint looks up the value of a local UintFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Uint(name string) uint {
|
|
||||||
return lookupUint(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalUint looks up the value of a global UintFlag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalUint(name string) uint {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
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
|
|
||||||
}
|
|
106
vendor/github.com/urfave/cli/flag_uint64.go
generated
vendored
106
vendor/github.com/urfave/cli/flag_uint64.go
generated
vendored
@ -1,106 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Uint64Flag is a flag with type uint64
|
|
||||||
type Uint64Flag struct {
|
|
||||||
Name string
|
|
||||||
Usage string
|
|
||||||
EnvVar string
|
|
||||||
FilePath string
|
|
||||||
Required bool
|
|
||||||
Hidden bool
|
|
||||||
Value uint64
|
|
||||||
Destination *uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
|
||||||
// (for usage defaults)
|
|
||||||
func (f Uint64Flag) String() string {
|
|
||||||
return FlagStringer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
|
||||||
func (f Uint64Flag) GetName() string {
|
|
||||||
return f.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
|
||||||
func (f Uint64Flag) IsRequired() bool {
|
|
||||||
return f.Required
|
|
||||||
}
|
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
|
||||||
func (f Uint64Flag) TakesValue() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsage returns the usage string for the flag
|
|
||||||
func (f Uint64Flag) GetUsage() string {
|
|
||||||
return f.Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue returns the flags value as string representation and an empty
|
|
||||||
// string if the flag takes no value at all.
|
|
||||||
func (f Uint64Flag) GetValue() string {
|
|
||||||
return fmt.Sprintf("%d", f.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
|
||||||
// Ignores errors
|
|
||||||
func (f Uint64Flag) Apply(set *flag.FlagSet) {
|
|
||||||
_ = f.ApplyWithError(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyWithError populates the flag given the flag set and environment
|
|
||||||
func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error {
|
|
||||||
if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
|
|
||||||
envValInt, err := strconv.ParseUint(envVal, 0, 64)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Value = envValInt
|
|
||||||
}
|
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
|
||||||
if f.Destination != nil {
|
|
||||||
set.Uint64Var(f.Destination, name, f.Value, f.Usage)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
set.Uint64(name, f.Value, f.Usage)
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) Uint64(name string) uint64 {
|
|
||||||
return lookupUint64(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalUint64 looks up the value of a global Uint64Flag, returns
|
|
||||||
// 0 if not found
|
|
||||||
func (c *Context) GlobalUint64(name string) uint64 {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
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
|
|
||||||
}
|
|
363
vendor/github.com/urfave/cli/help.go
generated
vendored
363
vendor/github.com/urfave/cli/help.go
generated
vendored
@ -1,363 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"text/tabwriter"
|
|
||||||
"text/template"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
var helpCommand = Command{
|
|
||||||
Name: "help",
|
|
||||||
Aliases: []string{"h"},
|
|
||||||
Usage: "Shows a list of commands or help for one command",
|
|
||||||
ArgsUsage: "[command]",
|
|
||||||
Action: func(c *Context) error {
|
|
||||||
args := c.Args()
|
|
||||||
if args.Present() {
|
|
||||||
return ShowCommandHelp(c, args.First())
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = ShowAppHelp(c)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var helpSubcommand = Command{
|
|
||||||
Name: "help",
|
|
||||||
Aliases: []string{"h"},
|
|
||||||
Usage: "Shows a list of commands or help for one command",
|
|
||||||
ArgsUsage: "[command]",
|
|
||||||
Action: func(c *Context) error {
|
|
||||||
args := c.Args()
|
|
||||||
if args.Present() {
|
|
||||||
return ShowCommandHelp(c, args.First())
|
|
||||||
}
|
|
||||||
|
|
||||||
return ShowSubcommandHelp(c)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
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(c *Context) error {
|
|
||||||
template := c.App.CustomAppHelpTemplate
|
|
||||||
if template == "" {
|
|
||||||
template = AppHelpTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.App.ExtraInfo == nil {
|
|
||||||
HelpPrinter(c.App.Writer, template, c.App)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
customAppData := func() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"ExtraInfo": c.App.ExtraInfo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HelpPrinterCustom(c.App.Writer, template, c.App, customAppData())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
|
||||||
func DefaultAppComplete(c *Context) {
|
|
||||||
DefaultCompleteWithFlags(nil)(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func printCommandSuggestions(commands []Command, writer io.Writer) {
|
|
||||||
for _, command := range commands {
|
|
||||||
if command.Hidden {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" {
|
|
||||||
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 strings.Split(flag.GetName(), ",") {
|
|
||||||
name = strings.TrimSpace(name)
|
|
||||||
// this will get total count utf8 letters in flag name
|
|
||||||
count := utf8.RuneCountInString(name)
|
|
||||||
if count > 2 {
|
|
||||||
count = 2 // resuse 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(flag.GetName()) {
|
|
||||||
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
|
||||||
_, _ = fmt.Fprintln(writer, flagCompletion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultCompleteWithFlags(cmd *Command) func(c *Context) {
|
|
||||||
return func(c *Context) {
|
|
||||||
if len(os.Args) > 2 {
|
|
||||||
lastArg := os.Args[len(os.Args)-2]
|
|
||||||
if strings.HasPrefix(lastArg, "-") {
|
|
||||||
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
|
|
||||||
if cmd != nil {
|
|
||||||
printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cmd != nil {
|
|
||||||
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
|
|
||||||
} else {
|
|
||||||
printCommandSuggestions(c.App.Commands, c.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 {
|
|
||||||
// show the subcommand help for a command with subcommands
|
|
||||||
if command == "" {
|
|
||||||
HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range ctx.App.Commands {
|
|
||||||
if c.HasName(command) {
|
|
||||||
templ := c.CustomHelpTemplate
|
|
||||||
if templ == "" {
|
|
||||||
templ = CommandHelpTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
HelpPrinter(ctx.App.Writer, templ, c)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.App.CommandNotFound == nil {
|
|
||||||
return NewExitError(fmt.Sprintf("No help topic for '%v'", command), 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.App.CommandNotFound(ctx, command)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowSubcommandHelp prints help for the given subcommand
|
|
||||||
func ShowSubcommandHelp(c *Context) error {
|
|
||||||
return ShowCommandHelp(c, c.Command.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowVersion prints the version number of the App
|
|
||||||
func ShowVersion(c *Context) {
|
|
||||||
VersionPrinter(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func printVersion(c *Context) {
|
|
||||||
_, _ = fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowCompletions prints the lists of commands within a given context
|
|
||||||
func ShowCompletions(c *Context) {
|
|
||||||
a := c.App
|
|
||||||
if a != nil && a.BashComplete != nil {
|
|
||||||
a.BashComplete(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowCommandCompletions prints the custom completions for a given command
|
|
||||||
func ShowCommandCompletions(ctx *Context, command string) {
|
|
||||||
c := ctx.App.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{}) {
|
|
||||||
funcMap := template.FuncMap{
|
|
||||||
"join": strings.Join,
|
|
||||||
}
|
|
||||||
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))
|
|
||||||
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(c *Context) bool {
|
|
||||||
found := false
|
|
||||||
if VersionFlag.GetName() != "" {
|
|
||||||
eachName(VersionFlag.GetName(), func(name string) {
|
|
||||||
if c.GlobalBool(name) || c.Bool(name) {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkHelp(c *Context) bool {
|
|
||||||
found := false
|
|
||||||
if HelpFlag.GetName() != "" {
|
|
||||||
eachName(HelpFlag.GetName(), func(name string) {
|
|
||||||
if c.GlobalBool(name) || c.Bool(name) {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkCommandHelp(c *Context, name string) bool {
|
|
||||||
if c.Bool("h") || c.Bool("help") {
|
|
||||||
_ = ShowCommandHelp(c, name)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSubcommandHelp(c *Context) bool {
|
|
||||||
if c.Bool("h") || c.Bool("help") {
|
|
||||||
_ = ShowSubcommandHelp(c)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
|
|
||||||
if !a.EnableBashCompletion {
|
|
||||||
return false, arguments
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := len(arguments) - 1
|
|
||||||
lastArg := arguments[pos]
|
|
||||||
|
|
||||||
if lastArg != "--"+BashCompletionFlag.GetName() {
|
|
||||||
return false, arguments
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, arguments[:pos]
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkCompletions(c *Context) bool {
|
|
||||||
if !c.shellComplete {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if args := c.Args(); args.Present() {
|
|
||||||
name := args.First()
|
|
||||||
if cmd := c.App.Command(name); cmd != nil {
|
|
||||||
// let the command handle the completion
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowCompletions(c)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkCommandCompletions(c *Context, name string) bool {
|
|
||||||
if !c.shellComplete {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowCommandCompletions(c, name)
|
|
||||||
return true
|
|
||||||
}
|
|
121
vendor/github.com/urfave/cli/template.go
generated
vendored
121
vendor/github.com/urfave/cli/template.go
generated
vendored
@ -1,121 +0,0 @@
|
|||||||
package cli
|
|
||||||
|
|
||||||
// AppHelpTemplate is the text template for the Default help topic.
|
|
||||||
// cli.go uses text/template to render templates. You can
|
|
||||||
// render custom help text by setting this variable.
|
|
||||||
var AppHelpTemplate = `NAME:
|
|
||||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
|
||||||
|
|
||||||
USAGE:
|
|
||||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
|
||||||
|
|
||||||
VERSION:
|
|
||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
|
||||||
|
|
||||||
DESCRIPTION:
|
|
||||||
{{.Description}}{{end}}{{if len .Authors}}
|
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
|
||||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
|
||||||
|
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
|
||||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
|
||||||
{{end}}{{$option}}{{end}}{{end}}{{if .Copyright}}
|
|
||||||
|
|
||||||
COPYRIGHT:
|
|
||||||
{{.Copyright}}{{end}}
|
|
||||||
`
|
|
||||||
|
|
||||||
// CommandHelpTemplate is the text template for the command help topic.
|
|
||||||
// cli.go uses text/template to render templates. You can
|
|
||||||
// render custom help text by setting this variable.
|
|
||||||
var CommandHelpTemplate = `NAME:
|
|
||||||
{{.HelpName}} - {{.Usage}}
|
|
||||||
|
|
||||||
USAGE:
|
|
||||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
|
||||||
|
|
||||||
CATEGORY:
|
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
|
||||||
|
|
||||||
DESCRIPTION:
|
|
||||||
{{.Description}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
{{range .VisibleFlags}}{{.}}
|
|
||||||
{{end}}{{end}}
|
|
||||||
`
|
|
||||||
|
|
||||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
|
||||||
// cli.go uses text/template to render templates. You can
|
|
||||||
// render custom help text by setting this variable.
|
|
||||||
var SubcommandHelpTemplate = `NAME:
|
|
||||||
{{.HelpName}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}}
|
|
||||||
|
|
||||||
USAGE:
|
|
||||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
|
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
|
||||||
|
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
{{range .VisibleFlags}}{{.}}
|
|
||||||
{{end}}{{end}}
|
|
||||||
`
|
|
||||||
|
|
||||||
var MarkdownDocTemplate = `% {{ .App.Name }}(8) {{ .App.Description }}
|
|
||||||
|
|
||||||
% {{ .App.Author }}
|
|
||||||
|
|
||||||
# NAME
|
|
||||||
|
|
||||||
{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }}
|
|
||||||
|
|
||||||
# SYNOPSIS
|
|
||||||
|
|
||||||
{{ .App.Name }}
|
|
||||||
{{ if .SynopsisArgs }}
|
|
||||||
` + "```" + `
|
|
||||||
{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + `
|
|
||||||
{{ end }}{{ if .App.UsageText }}
|
|
||||||
# DESCRIPTION
|
|
||||||
|
|
||||||
{{ .App.UsageText }}
|
|
||||||
{{ end }}
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
` + "```" + `
|
|
||||||
{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
|
||||||
` + "```" + `
|
|
||||||
{{ if .GlobalArgs }}
|
|
||||||
# GLOBAL OPTIONS
|
|
||||||
{{ range $v := .GlobalArgs }}
|
|
||||||
{{ $v }}{{ end }}
|
|
||||||
{{ end }}{{ if .Commands }}
|
|
||||||
# COMMANDS
|
|
||||||
{{ range $v := .Commands }}
|
|
||||||
{{ $v }}{{ end }}{{ end }}`
|
|
||||||
|
|
||||||
var FishCompletionTemplate = `# {{ .App.Name }} fish shell completion
|
|
||||||
|
|
||||||
function __fish_{{ .App.Name }}_no_subcommand --description 'Test if there has been any subcommand yet'
|
|
||||||
for i in (commandline -opc)
|
|
||||||
if contains -- $i{{ range $v := .AllCommands }} {{ $v }}{{ end }}
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
{{ range $v := .Completions }}{{ $v }}
|
|
||||||
{{ end }}`
|
|
0
vendor/github.com/urfave/cli/.flake8 → vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
0
vendor/github.com/urfave/cli/.flake8 → vendor/github.com/urfave/cli/v2/.flake8
generated
vendored
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
|
@ -55,11 +55,12 @@ further defined and clarified by project maintainers.
|
|||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
reported by contacting Dan Buch at dan@meatballhat.com. All complaints will be
|
reported by contacting urfave-governance@googlegroups.com, a members-only group
|
||||||
reviewed and investigated and will result in a response that is deemed necessary
|
that is world-postable. All complaints will be reviewed and investigated and
|
||||||
and appropriate to the circumstances. The project team is obligated to maintain
|
will result in a response that is deemed necessary and appropriate to the
|
||||||
confidentiality with regard to the reporter of an incident. Further details of
|
circumstances. The project team is obligated to maintain confidentiality with
|
||||||
specific enforcement policies may be posted separately.
|
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
|
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
|
faith may face temporary or permanent repercussions as determined by other
|
2
vendor/github.com/urfave/cli/LICENSE → vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
2
vendor/github.com/urfave/cli/LICENSE → vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Jeremy Saenz & Contributors
|
Copyright (c) 2022 urfave/cli maintainers
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
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)
|
540
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
Normal file
540
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
Normal file
@ -0,0 +1,540 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var newCommands []*Command
|
||||||
|
|
||||||
|
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)
|
||||||
|
newCommands = append(newCommands, c)
|
||||||
|
}
|
||||||
|
a.Commands = newCommands
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user