diff --git a/cli/command/stack/cmd.go b/cli/command/stack/cmd.go index 0416885ee109..851ac13c4af8 100644 --- a/cli/command/stack/cmd.go +++ b/cli/command/stack/cmd.go @@ -8,6 +8,7 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" + cliconfig "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -27,7 +28,11 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command { Short: "Manage Docker stacks", Args: cli.NoArgs, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - orchestrator, err := getOrchestrator(dockerCli.ConfigFile(), cmd, dockerCli.Err()) + configFile := dockerCli.ConfigFile() + if configFile == nil { + configFile = cliconfig.LoadDefaultConfigFile(dockerCli.Err()) + } + orchestrator, err := getOrchestrator(configFile, cmd, dockerCli.Err()) if err != nil { return err } @@ -42,9 +47,13 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command { }, } defaultHelpFunc := cmd.HelpFunc() - cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { - hideOrchestrationFlags(cmd, opts.orchestrator) - defaultHelpFunc(cmd, args) + cmd.SetHelpFunc(func(c *cobra.Command, args []string) { + if err := cmd.PersistentPreRunE(c, args); err != nil { + fmt.Fprintln(dockerCli.Err(), err) + return + } + hideOrchestrationFlags(c, opts.orchestrator) + defaultHelpFunc(c, args) }) cmd.AddCommand( newDeployCommand(dockerCli, &opts), diff --git a/cli/command/stack/deploy.go b/cli/command/stack/deploy.go index 0165bbda1a76..6c083eb2fb1a 100644 --- a/cli/command/stack/deploy.go +++ b/cli/command/stack/deploy.go @@ -58,7 +58,7 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma flags.StringVar(&opts.Bundlefile, "bundle-file", "", "Path to a Distributed Application Bundle file") flags.SetAnnotation("bundle-file", "experimental", nil) flags.SetAnnotation("bundle-file", "swarm", nil) - flags.StringSliceVarP(&opts.Composefiles, "compose-file", "c", []string{}, "Path to a Compose file") + flags.StringSliceVarP(&opts.Composefiles, "compose-file", "c", []string{}, `Path to a Compose file, or "-" to read from stdin`) flags.SetAnnotation("compose-file", "version", []string{"1.25"}) flags.BoolVar(&opts.SendRegistryAuth, "with-registry-auth", false, "Send registry authentication details to Swarm agents") flags.SetAnnotation("with-registry-auth", "swarm", nil) diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 32ad4848a202..917ce6b1145a 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -2209,7 +2209,7 @@ __docker_stack_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help)--bundle-file=[Path to a Distributed Application Bundle file]:dab:_files -g \"*.dab\"" \ - "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file]:compose file:_files -g \"*.(yml|yaml)\"" \ + "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file, or '-' to read from stdin]:compose file:_files -g \"*.(yml|yaml)\"" \ "($help)--with-registry-auth[Send registry authentication details to Swarm agents]" \ "($help -):stack:__docker_complete_stacks" && ret=0 ;; diff --git a/docs/reference/commandline/deploy.md b/docs/reference/commandline/deploy.md index af08bfe52cc3..e31a3858c6c0 100644 --- a/docs/reference/commandline/deploy.md +++ b/docs/reference/commandline/deploy.md @@ -28,7 +28,7 @@ Aliases: Options: --bundle-file string Path to a Distributed Application Bundle file - --compose-file string Path to a Compose file + --compose-file string Path to a Compose file, or "-" to read from stdin --help Print usage --prune Prune services that are no longer referenced --with-registry-auth Send registry authentication details to Swarm agents diff --git a/docs/reference/commandline/stack_deploy.md b/docs/reference/commandline/stack_deploy.md index 8f7687bce863..9542973aeb5d 100644 --- a/docs/reference/commandline/stack_deploy.md +++ b/docs/reference/commandline/stack_deploy.md @@ -25,7 +25,7 @@ Aliases: Options: --bundle-file string Path to a Distributed Application Bundle file - -c, --compose-file strings Path to a Compose file + -c, --compose-file strings Path to a Compose file, or "-" to read from stdin --help Print usage --kubeconfig string Kubernetes config file --namespace string Kubernetes namespace to use diff --git a/e2e/stack/help_test.go b/e2e/stack/help_test.go new file mode 100644 index 000000000000..e356fcae16c3 --- /dev/null +++ b/e2e/stack/help_test.go @@ -0,0 +1,24 @@ +package stack + +import ( + "fmt" + "testing" + + "gotest.tools/golden" + "gotest.tools/icmd" +) + +func TestStackDeployHelp(t *testing.T) { + t.Run("Swarm", func(t *testing.T) { + testStackDeployHelp(t, "swarm") + }) + t.Run("Kubernetes", func(t *testing.T) { + testStackDeployHelp(t, "kubernetes") + }) +} + +func testStackDeployHelp(t *testing.T, orchestrator string) { + result := icmd.RunCommand("docker", "stack", "deploy", "--orchestrator", orchestrator, "--help") + result.Assert(t, icmd.Success) + golden.Assert(t, result.Stdout(), fmt.Sprintf("stack-deploy-help-%s.golden", orchestrator)) +} diff --git a/e2e/stack/testdata/stack-deploy-help-kubernetes.golden b/e2e/stack/testdata/stack-deploy-help-kubernetes.golden new file mode 100644 index 000000000000..a0d6080a1121 --- /dev/null +++ b/e2e/stack/testdata/stack-deploy-help-kubernetes.golden @@ -0,0 +1,14 @@ + +Usage: docker stack deploy [OPTIONS] STACK + +Deploy a new stack or update an existing stack + +Aliases: + deploy, up + +Options: + -c, --compose-file strings Path to a Compose file, or "-" to read + from stdin + --kubeconfig string Kubernetes config file + --namespace string Kubernetes namespace to use + --orchestrator string Orchestrator to use (swarm|kubernetes|all) diff --git a/e2e/stack/testdata/stack-deploy-help-swarm.golden b/e2e/stack/testdata/stack-deploy-help-swarm.golden new file mode 100644 index 000000000000..5532dc01527a --- /dev/null +++ b/e2e/stack/testdata/stack-deploy-help-swarm.golden @@ -0,0 +1,19 @@ + +Usage: docker stack deploy [OPTIONS] STACK + +Deploy a new stack or update an existing stack + +Aliases: + deploy, up + +Options: + --bundle-file string Path to a Distributed Application Bundle file + -c, --compose-file strings Path to a Compose file, or "-" to read + from stdin + --orchestrator string Orchestrator to use (swarm|kubernetes|all) + --prune Prune services that are no longer referenced + --resolve-image string Query the registry to resolve image digest + and supported platforms + ("always"|"changed"|"never") (default "always") + --with-registry-auth Send registry authentication details to + Swarm agents