diff --git a/cli/main.go b/cli/main.go index e98568d46..4a4dd2ca0 100644 --- a/cli/main.go +++ b/cli/main.go @@ -68,6 +68,9 @@ var ( "serve": {}, "version": {}, "backend-metadata": {}, + // Special hidden commands used by cobra for completion + "__complete": {}, + "__completeNoDesc": {}, } unknownCommandRegexp = regexp.MustCompile(`unknown docker command: "([^"]*)"`) ) @@ -167,7 +170,7 @@ func main() { }) // populate the opts with the global flags - flags.Parse(os.Args[1:]) //nolint: errcheck + flags.Parse(os.Args[1:]) // nolint: errcheck level, err := logrus.ParseLevel(opts.LogLevel) if err != nil { @@ -223,18 +226,16 @@ func main() { volume.Command(ctype), ) - if ctype != store.DefaultContextType { - // On default context, "compose" is implemented by CLI Plugin - proxy := api.NewServiceProxy().WithService(service.ComposeService()) - command := compose2.RootCommand(ctype, proxy) + // On default context, "compose" is implemented by CLI Plugin + proxy := api.NewServiceProxy().WithService(service.ComposeService()) + command := compose2.RootCommand(ctype, proxy) - if ctype == store.AciContextType { - customizeCliForACI(command, proxy) - } - - root.AddCommand(command) + if ctype == store.AciContextType { + customizeCliForACI(command, proxy) } + root.AddCommand(command) + if err = root.ExecuteContext(ctx); err != nil { handleError(ctx, err, ctype, currentContext, cc, root) } diff --git a/cli/cmd/compose/completion.go b/cmd/compose/completion.go similarity index 100% rename from cli/cmd/compose/completion.go rename to cmd/compose/completion.go diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index 6d292b81d..c0404be2a 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -44,6 +44,9 @@ import ( // Command defines a compose CLI command as a func with args type Command func(context.Context, []string) error +// ValidArgsFn defines a completion func to be returned to fetch completion options +type ValidArgsFn func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) + // Adapt a Command func to cobra library func Adapt(fn Command) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { diff --git a/cmd/compose/ps.go b/cmd/compose/ps.go index 5249fcf2f..e5310aad0 100644 --- a/cmd/compose/ps.go +++ b/cmd/compose/ps.go @@ -76,6 +76,7 @@ func psCommand(p *projectOptions, backend api.Service) *cobra.Command { RunE: Adapt(func(ctx context.Context, args []string) error { return runPs(ctx, backend, args, opts) }), + ValidArgsFunction: psCompletion(p), } flags := cmd.Flags() flags.StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json]") @@ -184,3 +185,13 @@ func filterByStatus(containers []api.ContainerSummary, status string) []api.Cont } return filtered } + +func psCompletion(p *projectOptions) ValidArgsFn { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + project, err := p.toProject(nil) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return project.ServiceNames(), cobra.ShellCompDirectiveNoFileComp + } +}