Преглед на файлове

Make -l -D -H non-persistent to avoid conflict with subcommands

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof преди 4 години
родител
ревизия
9f80214dc2
променени са 4 файла, в които са добавени 47 реда и са изтрити 43 реда
  1. 4 3
      cli/cmd/compose/compose.go
  2. 38 30
      cli/main.go
  3. 0 5
      local/e2e/cli-only/e2e_test.go
  4. 5 5
      local/e2e/compose/logs_test.go

+ 4 - 3
cli/cmd/compose/compose.go

@@ -94,8 +94,9 @@ func (o *projectOptions) toProjectOptions() (*cli.ProjectOptions, error) {
 func Command(contextType string) *cobra.Command {
 	opts := projectOptions{}
 	command := &cobra.Command{
-		Short: "Docker Compose",
-		Use:   "compose",
+		Short:            "Docker Compose",
+		Use:              "compose",
+		TraverseChildren: true,
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
 			if contextType == store.DefaultContextType || contextType == store.LocalContextType {
 				fmt.Println("The new 'docker compose' command is currently experimental. To provide feedback or request new features please open issues at https://github.com/docker/compose-cli")
@@ -125,6 +126,6 @@ func Command(contextType string) *cobra.Command {
 		)
 	}
 	command.Flags().SetInterspersed(false)
-	opts.addProjectFlags(command.PersistentFlags())
+	opts.addProjectFlags(command.Flags())
 	return command
 }

+ 38 - 30
cli/main.go

@@ -102,9 +102,10 @@ func isContextAgnosticCommand(cmd *cobra.Command) bool {
 func main() {
 	var opts cliopts.GlobalOpts
 	root := &cobra.Command{
-		Use:           "docker",
-		SilenceErrors: true,
-		SilenceUsage:  true,
+		Use:              "docker",
+		SilenceErrors:    true,
+		SilenceUsage:     true,
+		TraverseChildren: true,
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
 			if !isContextAgnosticCommand(cmd) {
 				mobycli.ExecIfDefaultCtxType(cmd.Context(), cmd.Root())
@@ -112,7 +113,10 @@ func main() {
 			return nil
 		},
 		RunE: func(cmd *cobra.Command, args []string) error {
-			return cmd.Help()
+			if len(args) == 0 {
+				return cmd.Help()
+			}
+			return fmt.Errorf("unknown command %q", args[0])
 		},
 	}
 
@@ -146,20 +150,20 @@ func main() {
 		helpFunc(cmd, args)
 	})
 
-	root.PersistentFlags().StringVarP(&opts.LogLevel, "log-level", "l", "info", "Set the logging level (\"debug\"|\"info\"|\"warn\"|\"error\"|\"fatal\")")
-	root.PersistentFlags().BoolVarP(&opts.Debug, "debug", "D", false, "Enable debug output in the logs")
-	root.PersistentFlags().StringVarP(&opts.Host, "host", "H", "", "Daemon socket(s) to connect to")
-	opts.AddContextFlags(root.PersistentFlags())
-	opts.AddConfigFlags(root.PersistentFlags())
-	root.Flags().BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
+	flags := root.Flags()
+	flags.StringVarP(&opts.LogLevel, "log-level", "l", "info", "Set the logging level (\"debug\"|\"info\"|\"warn\"|\"error\"|\"fatal\")")
+	flags.BoolVarP(&opts.Debug, "debug", "D", false, "Enable debug output in the logs")
+	flags.StringVarP(&opts.Host, "host", "H", "", "Daemon socket(s) to connect to")
+	opts.AddContextFlags(flags)
+	opts.AddConfigFlags(flags)
+	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
 
 	walk(root, func(c *cobra.Command) {
 		c.Flags().BoolP("help", "h", false, "Help for "+c.Name())
 	})
 
 	// populate the opts with the global flags
-	_ = root.PersistentFlags().Parse(os.Args[1:])
-	_ = root.Flags().Parse(os.Args[1:])
+	flags.Parse(os.Args[1:]) //nolint: errcheck
 
 	level, err := logrus.ParseLevel(opts.LogLevel)
 	if err != nil {
@@ -208,28 +212,32 @@ func main() {
 	ctx = store.WithContextStore(ctx, s)
 
 	if err = root.ExecuteContext(ctx); err != nil {
-		// if user canceled request, simply exit without any error message
-		if errdefs.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {
-			metrics.Track(ctype, os.Args[1:], metrics.CanceledStatus)
-			os.Exit(130)
-		}
-		if ctype == store.AwsContextType {
-			exit(currentContext, errors.Errorf(`%q context type has been renamed. Recreate the context by running:
-$ docker context create %s <name>`, cc.Type(), store.EcsContextType), ctype)
-		}
-
-		// Context should always be handled by new CLI
-		requiredCmd, _, _ := root.Find(os.Args[1:])
-		if requiredCmd != nil && isContextAgnosticCommand(requiredCmd) {
-			exit(currentContext, err, ctype)
-		}
-		mobycli.ExecIfDefaultCtxType(ctx, root)
+		handleError(ctx, err, ctype, currentContext, cc, root)
+	}
+	metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus)
+}
 
-		checkIfUnknownCommandExistInDefaultContext(err, currentContext, ctype)
+func handleError(ctx context.Context, err error, ctype string, currentContext string, cc *store.DockerContext, root *cobra.Command) {
+	// if user canceled request, simply exit without any error message
+	if errdefs.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {
+		metrics.Track(ctype, os.Args[1:], metrics.CanceledStatus)
+		os.Exit(130)
+	}
+	if ctype == store.AwsContextType {
+		exit(currentContext, errors.Errorf(`%q context type has been renamed. Recreate the context by running:
+$ docker context create %s <name>`, cc.Type(), store.EcsContextType), ctype)
+	}
 
+	// Context should always be handled by new CLI
+	requiredCmd, _, _ := root.Find(os.Args[1:])
+	if requiredCmd != nil && isContextAgnosticCommand(requiredCmd) {
 		exit(currentContext, err, ctype)
 	}
-	metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus)
+	mobycli.ExecIfDefaultCtxType(ctx, root)
+
+	checkIfUnknownCommandExistInDefaultContext(err, currentContext, ctype)
+
+	exit(currentContext, err, ctype)
 }
 
 func exit(ctx string, err error, ctype string) {

+ 0 - 5
local/e2e/cli-only/e2e_test.go

@@ -450,11 +450,6 @@ func TestLegacyLogin(t *testing.T) {
 			Err:      "WARNING! Using --password via the CLI is insecure",
 		})
 	})
-
-	t.Run("login help global flags", func(t *testing.T) {
-		res := c.RunDockerCmd("login", "--help")
-		assert.Assert(t, strings.Contains(res.Combined(), "--log-level"))
-	})
 }
 
 func TestUnsupportedCommand(t *testing.T) {

+ 5 - 5
local/e2e/compose/logs_test.go

@@ -33,28 +33,28 @@ func TestLocalComposeLogs(t *testing.T) {
 	const projectName = "compose-e2e-logs"
 
 	t.Run("up", func(t *testing.T) {
-		c.RunDockerCmd("compose", "up", "-d", "-f", "./fixtures/logs-test/compose.yaml", "--project-name", projectName, "-d")
+		c.RunDockerCmd("compose", "-f", "./fixtures/logs-test/compose.yaml", "--project-name", projectName, "up", "-d")
 	})
 
 	t.Run("logs", func(t *testing.T) {
-		res := c.RunDockerCmd("compose", "logs", "--project-name", projectName)
+		res := c.RunDockerCmd("compose", "--project-name", projectName, "logs")
 		res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
 		res.Assert(t, icmd.Expected{Out: `hello`})
 	})
 
 	t.Run("logs ping", func(t *testing.T) {
-		res := c.RunDockerCmd("compose", "logs", "--project-name", projectName, "ping")
+		res := c.RunDockerCmd("compose", "--project-name", projectName, "logs", "ping")
 		res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
 		assert.Assert(t, !strings.Contains(res.Stdout(), "hello"))
 	})
 
 	t.Run("logs hello", func(t *testing.T) {
-		res := c.RunDockerCmd("compose", "logs", "--project-name", projectName, "hello", "ping")
+		res := c.RunDockerCmd("compose", "--project-name", projectName, "logs", "hello", "ping")
 		res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
 		res.Assert(t, icmd.Expected{Out: `hello`})
 	})
 
 	t.Run("down", func(t *testing.T) {
-		_ = c.RunDockerCmd("compose", "down", "--project-name", projectName)
+		_ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
 	})
 }