Просмотр исходного кода

Merge pull request #1226 from docker/loglevel

Add support for --log-level
Guillaume Tardif 5 лет назад
Родитель
Сommit
24d40ba6ac

+ 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")
@@ -126,6 +127,6 @@ func Command(contextType string) *cobra.Command {
 		)
 	}
 	command.Flags().SetInterspersed(false)
-	opts.addProjectFlags(command.PersistentFlags())
+	opts.addProjectFlags(command.Flags())
 	return command
 }

+ 0 - 2
cli/cmd/login/login.go

@@ -25,7 +25,6 @@ import (
 
 	"github.com/docker/compose-cli/api/client"
 	"github.com/docker/compose-cli/api/errdefs"
-	"github.com/docker/compose-cli/cli/cmd/mobyflags"
 	"github.com/docker/compose-cli/cli/mobycli"
 )
 
@@ -43,7 +42,6 @@ func Command() *cobra.Command {
 	flags.StringP("username", "u", "", "username")
 	flags.StringP("password", "p", "", "password")
 	flags.BoolP("password-stdin", "", false, "Take the password from stdin")
-	mobyflags.AddMobyFlagsForRetrocompatibility(flags)
 
 	cmd.AddCommand(AzureLoginCommand())
 	return cmd

+ 0 - 37
cli/cmd/mobyflags/mobyflags.go

@@ -1,37 +0,0 @@
-/*
-   Copyright 2020 Docker Compose CLI authors
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package mobyflags
-
-import (
-	"log"
-
-	flag "github.com/spf13/pflag"
-)
-
-// AddMobyFlagsForRetrocompatibility adds retrocompatibility flags to our commands
-func AddMobyFlagsForRetrocompatibility(flags *flag.FlagSet) {
-	const logLevelFlag = "log-level"
-	flags.StringP(logLevelFlag, "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
-	markHidden(flags, logLevelFlag)
-}
-
-func markHidden(flags *flag.FlagSet, flagName string) {
-	err := flags.MarkHidden(flagName)
-	if err != nil {
-		log.Fatal(err)
-	}
-}

+ 0 - 2
cli/cmd/version.go

@@ -23,7 +23,6 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"github.com/docker/compose-cli/cli/cmd/mobyflags"
 	"github.com/docker/compose-cli/cli/formatter"
 	"github.com/docker/compose-cli/cli/mobycli"
 	"github.com/docker/compose-cli/internal"
@@ -45,7 +44,6 @@ func VersionCommand() *cobra.Command {
 	flags := cmd.Flags()
 	flags.StringP(formatOpt, "f", "", "Format the output. Values: [pretty | json]. (Default: pretty)")
 	flags.String("kubeconfig", "", "Kubernetes config file")
-	mobyflags.AddMobyFlagsForRetrocompatibility(flags)
 
 	return cmd
 }

+ 45 - 29
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,19 +150,27 @@ func main() {
 		helpFunc(cmd, args)
 	})
 
-	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 {
+		fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", opts.LogLevel)
+		os.Exit(1)
+	}
+	logrus.SetLevel(level)
 	if opts.Debug {
 		logrus.SetLevel(logrus.DebugLevel)
 	}
@@ -200,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) {

+ 4 - 3
cli/options/options.go

@@ -25,7 +25,8 @@ import (
 type GlobalOpts struct {
 	apicontext.ContextFlags
 	cliconfig.ConfigFlags
-	Debug   bool
-	Version bool
-	Host    string
+	Debug    bool
+	LogLevel string
+	Version  bool
+	Host     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")
 	})
 }