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

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2021-02-03 14:02:12 +01:00
parent 4cbb33e20d
commit 9f80214dc2
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
4 changed files with 49 additions and 45 deletions

View File

@ -96,6 +96,7 @@ func Command(contextType string) *cobra.Command {
command := &cobra.Command{ command := &cobra.Command{
Short: "Docker Compose", Short: "Docker Compose",
Use: "compose", Use: "compose",
TraverseChildren: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error { PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if contextType == store.DefaultContextType || contextType == store.LocalContextType { 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") 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) command.Flags().SetInterspersed(false)
opts.addProjectFlags(command.PersistentFlags()) opts.addProjectFlags(command.Flags())
return command return command
} }

View File

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

View File

@ -450,11 +450,6 @@ func TestLegacyLogin(t *testing.T) {
Err: "WARNING! Using --password via the CLI is insecure", 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) { func TestUnsupportedCommand(t *testing.T) {

View File

@ -33,28 +33,28 @@ func TestLocalComposeLogs(t *testing.T) {
const projectName = "compose-e2e-logs" const projectName = "compose-e2e-logs"
t.Run("up", func(t *testing.T) { 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) { 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: `PING localhost (127.0.0.1)`})
res.Assert(t, icmd.Expected{Out: `hello`}) res.Assert(t, icmd.Expected{Out: `hello`})
}) })
t.Run("logs ping", func(t *testing.T) { 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)`}) res.Assert(t, icmd.Expected{Out: `PING localhost (127.0.0.1)`})
assert.Assert(t, !strings.Contains(res.Stdout(), "hello")) assert.Assert(t, !strings.Contains(res.Stdout(), "hello"))
}) })
t.Run("logs hello", func(t *testing.T) { 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: `PING localhost (127.0.0.1)`})
res.Assert(t, icmd.Expected{Out: `hello`}) res.Assert(t, icmd.Expected{Out: `hello`})
}) })
t.Run("down", func(t *testing.T) { t.Run("down", func(t *testing.T) {
_ = c.RunDockerCmd("compose", "down", "--project-name", projectName) _ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
}) })
} }