diff --git a/cmd/goss/goss.go b/cmd/goss/goss.go index 0c6a061a..a90da7b8 100644 --- a/cmd/goss/goss.go +++ b/cmd/goss/goss.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "log" "os" @@ -15,35 +16,35 @@ import ( "github.com/goss-org/goss/util" "github.com/fatih/color" - "github.com/urfave/cli" + "github.com/urfave/cli/v3" ) // converts a cli context into a goss Config -func newRuntimeConfigFromCLI(c *cli.Context) *util.Config { +func newRuntimeConfigFromCLI(c *cli.Command) *util.Config { cfg := &util.Config{ AllowInsecure: c.Bool("insecure"), AnnounceToCLI: true, Cache: c.Duration("cache"), Debug: c.Bool("debug"), - LogLevel: c.GlobalString("log-level"), + LogLevel: c.String("log-level"), Endpoint: c.String("endpoint"), FormatOptions: c.StringSlice("format-options"), - IgnoreList: c.GlobalStringSlice("exclude-attr"), + IgnoreList: c.StringSlice("exclude-attr"), ListenAddress: c.String("listen-addr"), MaxConcurrent: c.Int("max-concurrent"), NoFollowRedirects: c.Bool("no-follow-redirects"), OutputFormat: c.String("format"), - PackageManager: c.GlobalString("package"), + PackageManager: c.String("package"), Password: c.String("password"), Proxy: c.String("proxy"), RetryTimeout: c.Duration("retry-timeout"), Server: c.String("server"), Sleep: c.Duration("sleep"), - Spec: c.GlobalString("gossfile"), + Spec: c.String("gossfile"), Timeout: c.Duration("timeout"), Username: c.String("username"), - Vars: c.GlobalString("vars"), - VarsInline: c.GlobalString("vars-inline"), + Vars: c.String("vars"), + VarsInline: c.String("vars-inline"), } if c.Bool("no-color") { @@ -57,348 +58,366 @@ func newRuntimeConfigFromCLI(c *cli.Context) *util.Config { return cfg } -func timeoutFlag(value time.Duration) cli.DurationFlag { - return cli.DurationFlag{ +func timeoutFlag(value time.Duration) *cli.DurationFlag { + return &cli.DurationFlag{ Name: "timeout", Value: value, } } func main() { - app := cli.NewApp() - app.EnableBashCompletion = true - app.Version = util.Version - app.Name = "goss" - app.Usage = "Quick and Easy server validation" - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "log-level, loglevel, L, l", - Value: "INFO", - Usage: "Goss log verbosity level", - EnvVar: "GOSS_LOGLEVEL", - }, - cli.StringFlag{ - Name: "gossfile, g", - Value: "./goss.yaml", - Usage: "Goss file to read from / write to", - EnvVar: "GOSS_FILE", - }, - cli.StringFlag{ - Name: "vars", - Usage: "json/yaml file containing variables for template", - EnvVar: "GOSS_VARS", - }, - cli.StringFlag{ - Name: "vars-inline", - Usage: "json/yaml string containing variables for template (overwrites vars)", - EnvVar: "GOSS_VARS_INLINE", - }, - cli.StringFlag{ - Name: "package", - Usage: fmt.Sprintf("Package type to use [%s]", strings.Join(system.SupportedPackageManagers(), ", ")), - }, - } - app.Commands = []cli.Command{ - { - Name: "validate", - Aliases: []string{"v"}, - Usage: "Validate system", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "format, f", - Value: "rspecish", - Usage: fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()), - EnvVar: "GOSS_FMT", - }, - cli.StringSliceFlag{ - Name: "format-options, o", - Usage: fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()), - EnvVar: "GOSS_FMT_OPTIONS", - }, - cli.BoolFlag{ - Name: "color", - Usage: "Force color on", - EnvVar: "GOSS_COLOR", - }, - cli.BoolFlag{ - Name: "no-color", - Usage: "Force color off", - EnvVar: "GOSS_NOCOLOR", - }, - cli.DurationFlag{ - Name: "sleep,s", - Usage: "Time to sleep between retries, only active when -r is set", - Value: 1 * time.Second, - EnvVar: "GOSS_SLEEP", - }, - cli.DurationFlag{ - Name: "retry-timeout,r", - Usage: "Retry on failure so long as elapsed + sleep time is less than this", - Value: 0, - EnvVar: "GOSS_RETRY_TIMEOUT", - }, - cli.IntFlag{ - Name: "max-concurrent", - Usage: "Max number of tests to run concurrently", - Value: 50, - EnvVar: "GOSS_MAX_CONCURRENT", - }, + app := &cli.Command{ + EnableShellCompletion: true, + Version: util.Version, + Name: "goss", + Usage: "Quick and Easy server validation", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "log-level", + Aliases: []string{"loglevel", "L", "l"}, + Value: "INFO", + Usage: "Goss log verbosity level", + Sources: cli.EnvVars("GOSS_LOGLEVEL"), }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - code, err := goss.Validate(newRuntimeConfigFromCLI(c)) - if err != nil { - color.Red(fmt.Sprintf("Error: %v\n", err)) - } - os.Exit(code) - - return nil + &cli.StringFlag{ + Name: "gossfile", + Aliases: []string{"g"}, + Value: "./goss.yaml", + Usage: "Goss file to read from / write to", + Sources: cli.EnvVars("GOSS_FILE"), }, - }, - { - Name: "serve", - Aliases: []string{"s"}, - Usage: "Serve a health endpoint", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "format, f", - Value: "rspecish", - Usage: fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()), - EnvVar: "GOSS_FMT", - }, - cli.StringSliceFlag{ - Name: "format-options, o", - Usage: fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()), - EnvVar: "GOSS_FMT_OPTIONS", - }, - cli.DurationFlag{ - Name: "cache, c", - Usage: "Time to cache the results", - Value: 5 * time.Second, - EnvVar: "GOSS_CACHE", - }, - cli.StringFlag{ - Name: "listen-addr, l", - Value: ":8080", - Usage: "Address to listen on [ip]:port", - EnvVar: "GOSS_LISTEN", - }, - cli.StringFlag{ - Name: "endpoint, e", - Value: "/healthz", - Usage: "Endpoint to expose", - EnvVar: "GOSS_ENDPOINT", - }, - cli.IntFlag{ - Name: "max-concurrent", - Usage: "Max number of tests to run concurrently", - Value: 50, - EnvVar: "GOSS_MAX_CONCURRENT", - }, + &cli.StringFlag{ + Name: "vars", + Usage: "json/yaml file containing variables for template", + Sources: cli.EnvVars("GOSS_VARS"), + }, + &cli.StringFlag{ + Name: "vars-inline", + Usage: "json/yaml string containing variables for template (overwrites vars)", + Sources: cli.EnvVars("GOSS_VARS_INLINE"), }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.Serve(newRuntimeConfigFromCLI(c)) + &cli.StringFlag{ + Name: "package", + Usage: fmt.Sprintf("Package type to use [%s]", strings.Join(system.SupportedPackageManagers(), ", ")), }, }, - { - Name: "render", - Aliases: []string{"r"}, - Usage: "render gossfile after imports", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "debug, d", - Usage: "Print debugging info when rendering", + Commands: []*cli.Command{ + { + Name: "validate", + Aliases: []string{"v"}, + Usage: "Validate system", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "format", + Aliases: []string{"f"}, + Value: "rspecish", + Usage: fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()), + Sources: cli.EnvVars("GOSS_FMT"), + }, + &cli.StringSliceFlag{ + Name: "format-options", + Aliases: []string{"o"}, + Usage: fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()), + Sources: cli.EnvVars("GOSS_FMT_OPTIONS"), + }, + &cli.BoolFlag{ + Name: "color", + Usage: "Force color on", + Sources: cli.EnvVars("GOSS_COLOR"), + }, + &cli.BoolFlag{ + Name: "no-color", + Usage: "Force color off", + Sources: cli.EnvVars("GOSS_NOCOLOR"), + }, + &cli.DurationFlag{ + Name: "sleep", + Aliases: []string{"s"}, + Usage: "Time to sleep between retries, only active when -r is set", + Value: 1 * time.Second, + Sources: cli.EnvVars("GOSS_SLEEP"), + }, + &cli.DurationFlag{ + Name: "retry-timeout", + Aliases: []string{"r"}, + Usage: "Retry on failure so long as elapsed + sleep time is less than this", + Value: 0, + Sources: cli.EnvVars("GOSS_RETRY_TIMEOUT"), + }, + &cli.IntFlag{ + Name: "max-concurrent", + Usage: "Max number of tests to run concurrently", + Value: 50, + Sources: cli.EnvVars("GOSS_MAX_CONCURRENT"), + }, }, - }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - j, err := goss.RenderJSON(newRuntimeConfigFromCLI(c)) - if err != nil { - return err - } - - fmt.Print(j) + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + code, err := goss.Validate(newRuntimeConfigFromCLI(c)) + if err != nil { + color.Red(fmt.Sprintf("Error: %v\n", err)) + } + os.Exit(code) - return nil - }, - }, - { - Name: "autoadd", - Aliases: []string{"aa"}, - Usage: "automatically add all matching resource to the test suite", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AutoAddResources(c.GlobalString("gossfile"), c.Args(), newRuntimeConfigFromCLI(c)) - }, - }, - { - Name: "add", - Aliases: []string{"a"}, - Usage: "add a resource to the test suite", - Flags: []cli.Flag{ - cli.StringSliceFlag{ - Name: "exclude-attr", - Usage: "Exclude the following attributes when adding a new resource", + return nil }, }, - Subcommands: []cli.Command{ - { - Name: resource.PackageResourceKey, - Usage: "add new package", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.PackageResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: "serve", + Aliases: []string{"s"}, + Usage: "Serve a health endpoint", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "format", + Aliases: []string{"f"}, + Value: "rspecish", + Usage: fmt.Sprintf("Format to output in, valid options: %s", outputs.Outputers()), + Sources: cli.EnvVars("GOSS_FMT"), }, - }, - { - Name: resource.FileResourceKey, - Usage: "add new file", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.FileResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + &cli.StringSliceFlag{ + Name: "format-options", + Aliases: []string{"o"}, + Usage: fmt.Sprintf("Extra options passed to the formatter, valid options: %s", outputs.FormatOptions()), + Sources: cli.EnvVars("GOSS_FMT_OPTIONS"), }, - }, - { - Name: resource.AddrResourceKey, - Usage: "add new remote address:port - ex: google.com:80", - Flags: []cli.Flag{ - timeoutFlag(500 * time.Millisecond), + &cli.DurationFlag{ + Name: "cache", + Aliases: []string{"c"}, + Usage: "Time to cache the results", + Value: 5 * time.Second, + Sources: cli.EnvVars("GOSS_CACHE"), }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.AddResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + &cli.StringFlag{ + Name: "listen-addr", + Aliases: []string{"l"}, + Value: ":8080", + Usage: "Address to listen on [ip]:port", + Sources: cli.EnvVars("GOSS_LISTEN"), }, - }, - { - Name: resource.PortResourceKey, - Usage: "add new listening [protocol]:port - ex: 80 or udp:123", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.PortResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + &cli.StringFlag{ + Name: "endpoint", + Aliases: []string{"e"}, + Value: "/healthz", + Usage: "Endpoint to expose", + Sources: cli.EnvVars("GOSS_ENDPOINT"), }, - }, - { - Name: resource.ServiceResourceKey, - Usage: "add new service", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.ServiceResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + &cli.IntFlag{ + Name: "max-concurrent", + Usage: "Max number of tests to run concurrently", + Value: 50, + Sources: cli.EnvVars("GOSS_MAX_CONCURRENT"), }, }, - { - Name: resource.UserResourceKey, - Usage: "add new user", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.UserResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.Serve(newRuntimeConfigFromCLI(c)) + }, + }, + { + Name: "render", + Aliases: []string{"r"}, + Usage: "render gossfile after imports", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "debug", + Aliases: []string{"d"}, + Usage: "Print debugging info when rendering", }, }, - { - Name: resource.GroupResourceKey, - Usage: "add new group", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.GroupResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + j, err := goss.RenderJSON(newRuntimeConfigFromCLI(c)) + if err != nil { + return err + } + + fmt.Print(j) + + return nil + }, + }, + { + Name: "autoadd", + Aliases: []string{"aa"}, + Usage: "automatically add all matching resource to the test suite", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AutoAddResources(c.String("gossfile"), c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, + }, + { + Name: "add", + Aliases: []string{"a"}, + Usage: "add a resource to the test suite", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "exclude-attr", + Usage: "Exclude the following attributes when adding a new resource", }, }, - { - Name: resource.CommandResourceKey, - Usage: "add new command", - Flags: []cli.Flag{ - timeoutFlag(10 * time.Second), + Commands: []*cli.Command{ + { + Name: resource.PackageResourceKey, + Usage: "add new package", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.PackageResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.CommandResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.FileResourceKey, + Usage: "add new file", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.FileResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: resource.DNSResourceKey, - Usage: "add new dns", - Flags: []cli.Flag{ - timeoutFlag(500 * time.Millisecond), - cli.StringFlag{ - Name: "server", - Usage: "The IP address of a DNS server to query", + { + Name: resource.AddrResourceKey, + Usage: "add new remote address:port - ex: google.com:80", + Flags: []cli.Flag{ + timeoutFlag(500 * time.Millisecond), + }, + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.AddResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) }, }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.DNSResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.PortResourceKey, + Usage: "add new listening [protocol]:port - ex: 80 or udp:123", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.PortResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: resource.ProcessResourceKey, - Usage: "add new process name", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.ProcessResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.ServiceResourceKey, + Usage: "add new service", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.ServiceResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: resource.HTTPResourceKey, - Usage: "add new http", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "insecure, k", + { + Name: resource.UserResourceKey, + Usage: "add new user", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.UserResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) }, - cli.BoolFlag{ - Name: "no-follow-redirects, r", + }, + { + Name: resource.GroupResourceKey, + Usage: "add new group", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.GroupResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) }, - timeoutFlag(5 * time.Second), - cli.StringFlag{ - Name: "username, u", - Usage: "Username for basic auth", + }, + { + Name: resource.CommandResourceKey, + Usage: "add new command", + Flags: []cli.Flag{ + timeoutFlag(10 * time.Second), }, - cli.StringFlag{ - Name: "password, p", - Usage: "Password for basic auth", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.CommandResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) }, - cli.StringFlag{ - Name: "proxy, x", - Usage: "Proxy server to use. e.g. http://10.0.0.2:8080", + }, + { + Name: resource.DNSResourceKey, + Usage: "add new dns", + Flags: []cli.Flag{ + timeoutFlag(500 * time.Millisecond), + &cli.StringFlag{ + Name: "server", + Usage: "The IP address of a DNS server to query", + }, + }, + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.DNSResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) }, }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.HTTPResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.ProcessResourceKey, + Usage: "add new process name", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.ProcessResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: "goss", - Usage: "add new goss file, it will be imported from this one", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.GossFileResourceName, c.Args(), newRuntimeConfigFromCLI(c)) - + { + Name: resource.HTTPResourceKey, + Usage: "add new http", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "insecure", + Aliases: []string{"k"}, + }, + &cli.BoolFlag{ + Name: "no-follow-redirects", + Aliases: []string{"r"}, + }, + timeoutFlag(5 * time.Second), + &cli.StringFlag{ + Name: "username", + Aliases: []string{"u"}, + Usage: "Username for basic auth", + }, + &cli.StringFlag{ + Name: "password", + Aliases: []string{"p"}, + Usage: "Password for basic auth", + }, + &cli.StringFlag{ + Name: "proxy", + Aliases: []string{"x"}, + Usage: "Proxy server to use. e.g. http://10.0.0.2:8080", + }, + }, + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.HTTPResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: resource.KernelParamResourceKey, - Usage: "add new goss kernel param", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.KernelParamResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: "goss", + Usage: "add new goss file, it will be imported from this one", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.GossFileResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + + }, }, - }, - { - Name: resource.MountResourceKey, - Usage: "add new mount", - Flags: []cli.Flag{ - timeoutFlag(1000 * time.Millisecond), + { + Name: resource.KernelParamResourceKey, + Usage: "add new goss kernel param", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.KernelParamResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.MountResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.MountResourceKey, + Usage: "add new mount", + Flags: []cli.Flag{ + timeoutFlag(1000 * time.Millisecond), + }, + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.MountResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, - }, - { - Name: resource.InterfaceResourceKey, - Usage: "add new interface", - Action: func(c *cli.Context) error { - fatalAlphaIfNeeded(c) - return goss.AddResources(c.GlobalString("gossfile"), resource.InterfaceResourceName, c.Args(), newRuntimeConfigFromCLI(c)) + { + Name: resource.InterfaceResourceKey, + Usage: "add new interface", + Action: func(ctx context.Context, c *cli.Command) error { + fatalAlphaIfNeeded(c) + return goss.AddResources(c.String("gossfile"), resource.InterfaceResourceName, c.Args().Slice(), newRuntimeConfigFromCLI(c)) + }, }, }, }, @@ -406,26 +425,26 @@ func main() { } addAlphaFlagIfNeeded(app) - err := app.Run(os.Args) + err := app.Run(context.Background(), os.Args) if err != nil { log.Fatal(err) } } -func addAlphaFlagIfNeeded(app *cli.App) { +func addAlphaFlagIfNeeded(cmd *cli.Command) { if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { - app.Flags = append(app.Flags, cli.StringFlag{ - Name: "use-alpha", - Usage: "goss on macOS/Windows is alpha-quality. Set to 1 to use anyway.", - EnvVar: "GOSS_USE_ALPHA", - Value: "0", + cmd.Flags = append(cmd.Flags, &cli.StringFlag{ + Name: "use-alpha", + Usage: "goss on macOS/Windows is alpha-quality. Set to 1 to use anyway.", + Sources: cli.EnvVars("GOSS_USE_ALPHA"), + Value: "0", }) } } -func fatalAlphaIfNeeded(c *cli.Context) { +func fatalAlphaIfNeeded(c *cli.Command) { if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { - if c.GlobalString("use-alpha") != "1" { + if c.String("use-alpha") != "1" { howto := map[string]string{ "darwin": "export GOSS_USE_ALPHA=1", "windows": "In cmd: set GOSS_USE_ALPHA=1\nIn powershell: $env:GOSS_USE_ALPHA=1\nIn bash: export GOSS_USE_ALPHA=1", diff --git a/go.mod b/go.mod index b0375c1e..e8eca1e0 100644 --- a/go.mod +++ b/go.mod @@ -20,9 +20,9 @@ require ( github.com/prometheus/client_golang v1.19.1 github.com/prometheus/common v0.55.0 github.com/samber/lo v1.46.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.17.1 - github.com/urfave/cli v1.22.14 + github.com/urfave/cli/v3 v3.9.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.1 ) @@ -33,7 +33,6 @@ require ( github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -45,7 +44,6 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index f1b3a22a..0a60d88a 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= @@ -17,9 +16,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -84,8 +80,6 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -93,14 +87,9 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -108,8 +97,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= -github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +github.com/urfave/cli/v3 v3.9.0 h1:AV9lIiPv3ukYnxunaCUsHnEozptYmDN2F0+yWqLMn/c= +github.com/urfave/cli/v3 v3.9.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= @@ -132,7 +121,6 @@ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/util/config.go b/util/config.go index 3be5fa84..8d97bdda 100644 --- a/util/config.go +++ b/util/config.go @@ -14,7 +14,7 @@ import ( // ConfigOption manipulates Config type ConfigOption func(c *Config) error -// Config is the runtime configuration for the goss system, the cli.Context gets +// Config is the runtime configuration for the goss system, the cli.Command gets // converted to this and it allows other packages to embed goss by creating this // structure and using it when adding, validating etc. //