diff --git a/cmd/completion.go b/cmd/completion.go index 1f75e506..0ae968ff 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -4,6 +4,7 @@ import ( "log" "os" + metalgo "github.com/metal-stack/metal-go" "github.com/spf13/cobra" ) @@ -48,84 +49,101 @@ rm -f ~/.zcompdump* }, } -const bashCompletionFunc = ` -__metalctl_get_images() -{ - local template - template="{{ .id }}" - local metalctl_out - if metalctl_out=$(metalctl image list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func imageListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.ImageList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, i := range resp.Image { + names = append(names, *i.ID) + } + return names, cobra.ShellCompDirectiveDefault } -__metalctl_get_partitions() -{ - local template - template="{{ .id }}" - local metalctl_out - if metalctl_out=$(metalctl partition list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func partitionListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.PartitionList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, p := range resp.Partition { + names = append(names, *p.ID) + } + return names, cobra.ShellCompDirectiveDefault } -__metalctl_get_sizes() -{ - local template - template="{{ .id }}" - local metalctl_out - if metalctl_out=$(metalctl size list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func sizeListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.SizeList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, s := range resp.Size { + names = append(names, *s.ID) + } + return names, cobra.ShellCompDirectiveDefault } -__metalctl_get_machines() -{ - local template - template="{{ .id }}" - local metalctl_out - if metalctl_out=$(metalctl machine list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func machineListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.MachineList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, m := range resp.Machines { + names = append(names, *m.ID) + } + return names, cobra.ShellCompDirectiveDefault } - -__metalctl_get_networks() -{ - local template - template="{{ .id }}" - local metalctl_out - if metalctl_out=$(metalctl network list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func networkListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.NetworkList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, n := range resp.Networks { + names = append(names, *n.ID) + } + return names, cobra.ShellCompDirectiveDefault } -__metalctl_get_ips() -{ - local template - template="{{ .ipaddress }}" - local metalctl_out - if metalctl_out=$(metalctl network ip list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func ipListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.IPList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, i := range resp.IPs { + names = append(names, *i.Ipaddress) + } + return names, cobra.ShellCompDirectiveDefault } - -__metalctl_get_projects() -{ - local template - template="{{ if .allocation }} {{ .allocation.project }} {{ end }}" - local metalctl_out - if metalctl_out=$(metalctl machine list -o template --template="${template}" 2>/dev/null); then - COMPREPLY=( $( compgen -W "${metalctl_out}[*]" -- "$cur" ) ) - fi +func projectListCompletion(driver *metalgo.Driver) ([]string, cobra.ShellCompDirective) { + resp, err := driver.ProjectList() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, p := range resp.Project { + names = append(names, p.Meta.ID) + } + return names, cobra.ShellCompDirectiveDefault } - -__metalctl_get_output_formats() -{ - COMPREPLY=( $( compgen -W "table wide markdown json yaml template" -- "$cur" ) ) +func contextListCompletion() ([]string, cobra.ShellCompDirective) { + ctxs, err := getContexts() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for name := range ctxs.Contexts { + names = append(names, name) + } + return names, cobra.ShellCompDirectiveDefault } - -__metalctl_get_orders() -{ - COMPREPLY=( $( compgen -W "size id status event when partition project" -- "$cur" ) ) +func outputFormatListCompletion() ([]string, cobra.ShellCompDirective) { + return []string{"table", "wide", "markdown", "json", "yaml", "template"}, cobra.ShellCompDirectiveDefault +} +func outputOrderListCompletion() ([]string, cobra.ShellCompDirective) { + return []string{"size", "id", "status", "event", "when", "partition", "project"}, cobra.ShellCompDirectiveDefault } -` diff --git a/cmd/context.go b/cmd/context.go index 1612e052..45d2b7fb 100644 --- a/cmd/context.go +++ b/cmd/context.go @@ -34,7 +34,7 @@ var ( if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - return contextListInternal() + return contextListCompletion() }, Example: ` @@ -98,18 +98,6 @@ func contextList() error { return printer.Print(ctxs) } -func contextListInternal() ([]string, cobra.ShellCompDirective) { - ctxs, err := getContexts() - if err != nil { - return nil, cobra.ShellCompDirectiveError - } - var names []string - for name := range ctxs.Contexts { - names = append(names, name) - } - return names, cobra.ShellCompDirectiveDefault -} - func mustDefaultContext() Context { ctxs, err := getContexts() if err != nil { diff --git a/cmd/machine.go b/cmd/machine.go index 3c23692c..d0e57e9a 100644 --- a/cmd/machine.go +++ b/cmd/machine.go @@ -278,11 +278,21 @@ func init() { machineListCmd.Flags().StringVarP(&filterOpts.Mac, "mac", "", "", "mac to filter [optional]") machineListCmd.Flags().StringSliceVar(&filterOpts.Tags, "tags", []string{}, "tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".") - machineListCmd.Flags().SetAnnotation("partition", cobra.BashCompCustom, []string{"__metalctl_get_partitions"}) - machineListCmd.Flags().SetAnnotation("image", cobra.BashCompCustom, []string{"__metalctl_get_images"}) - machineListCmd.Flags().SetAnnotation("size", cobra.BashCompCustom, []string{"__metalctl_get_sizes"}) - machineListCmd.Flags().SetAnnotation("project", cobra.BashCompCustom, []string{"__metalctl_get_projects"}) - machineListCmd.Flags().SetAnnotation("id", cobra.BashCompCustom, []string{"__metalctl_get_machines"}) + machineListCmd.RegisterFlagCompletionFunc("partition", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return partitionListCompletion(driver) + }) + machineListCmd.RegisterFlagCompletionFunc("size", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return sizeListCompletion(driver) + }) + machineListCmd.RegisterFlagCompletionFunc("project", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return projectListCompletion(driver) + }) + machineListCmd.RegisterFlagCompletionFunc("id", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return machineListCompletion(driver) + }) + machineListCmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return imageListCompletion(driver) + }) machineIpmiCmd.Flags().StringVarP(&filterOpts.ID, "id", "", "", "ID to filter [optional]") machineIpmiCmd.Flags().StringVarP(&filterOpts.Partition, "partition", "", "", "partition to filter [optional]") @@ -294,11 +304,18 @@ func init() { machineIpmiCmd.Flags().StringVarP(&filterOpts.Mac, "mac", "", "", "mac to filter [optional]") machineIpmiCmd.Flags().StringSliceVar(&filterOpts.Tags, "tags", []string{}, "tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".") - machineIpmiCmd.Flags().SetAnnotation("partition", cobra.BashCompCustom, []string{"__metalctl_get_partitions"}) - machineIpmiCmd.Flags().SetAnnotation("image", cobra.BashCompCustom, []string{"__metalctl_get_images"}) - machineIpmiCmd.Flags().SetAnnotation("size", cobra.BashCompCustom, []string{"__metalctl_get_sizes"}) - machineIpmiCmd.Flags().SetAnnotation("project", cobra.BashCompCustom, []string{"__metalctl_get_projects"}) - machineIpmiCmd.Flags().SetAnnotation("id", cobra.BashCompCustom, []string{"__metalctl_get_machines"}) + machineIpmiCmd.RegisterFlagCompletionFunc("partition", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return partitionListCompletion(driver) + }) + machineIpmiCmd.RegisterFlagCompletionFunc("size", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return sizeListCompletion(driver) + }) + machineIpmiCmd.RegisterFlagCompletionFunc("project", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return projectListCompletion(driver) + }) + machineIpmiCmd.RegisterFlagCompletionFunc("id", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return machineListCompletion(driver) + }) machineCmd.AddCommand(machineListCmd) machineCmd.AddCommand(machineDestroyCmd) @@ -392,13 +409,28 @@ MODE can be omitted or one of: cmd.MarkFlagRequired("project") // Completion for arguments - cmd.Flags().SetAnnotation("networks", cobra.BashCompCustom, []string{"__metalctl_get_networks"}) - cmd.Flags().SetAnnotation("ips", cobra.BashCompCustom, []string{"__metalctl_get_ips"}) - cmd.Flags().SetAnnotation("image", cobra.BashCompCustom, []string{"__metalctl_get_images"}) - cmd.Flags().SetAnnotation("partition", cobra.BashCompCustom, []string{"__metalctl_get_partitions"}) - cmd.Flags().SetAnnotation("size", cobra.BashCompCustom, []string{"__metalctl_get_sizes"}) - cmd.Flags().SetAnnotation("id", cobra.BashCompCustom, []string{"__metalctl_get_machines"}) - cmd.Flags().SetAnnotation("project", cobra.BashCompCustom, []string{"__metalctl_get_projects"}) + cmd.RegisterFlagCompletionFunc("networks", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return networkListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("ips", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return ipListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("partition", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return partitionListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("size", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return sizeListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("project", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return projectListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("id", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return machineListCompletion(driver) + }) + cmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return imageListCompletion(driver) + }) + } func machineCreate(driver *metalgo.Driver) error { diff --git a/cmd/root.go b/cmd/root.go index 84d632d7..06cb953b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -49,8 +49,7 @@ var ( PersistentPreRun: func(cmd *cobra.Command, args []string) { initPrinter() }, - SilenceUsage: true, - BashCompletionFunction: bashCompletionFunc, + SilenceUsage: true, } markdownCmd = &cobra.Command{ @@ -114,8 +113,12 @@ Example image update: # metalctl image update -f ubuntu.yaml `) - rootCmd.PersistentFlags().SetAnnotation("output-format", cobra.BashCompCustom, []string{"__metalctl_get_output_formats"}) - rootCmd.PersistentFlags().SetAnnotation("order", cobra.BashCompCustom, []string{"__metalctl_get_orders"}) + rootCmd.RegisterFlagCompletionFunc("output-format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return outputFormatListCompletion() + }) + rootCmd.RegisterFlagCompletionFunc("order", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return outputOrderListCompletion() + }) rootCmd.AddCommand(completionCmd) rootCmd.AddCommand(zshCompletionCmd)