diff --git a/cmd/completion.go b/cmd/completion.go new file mode 100644 index 00000000..07459f16 --- /dev/null +++ b/cmd/completion.go @@ -0,0 +1,174 @@ +package cmd + +import ( + "errors" + "github.com/spf13/cobra" + "os" +) + +func init() { + root.AddCommand(completionCmd) +} + +// completionCmd represents the completion command +var completionCmd = &cobra.Command{ + Use: "completion", + Short: "Generates bash completion scripts", + Long: `To load completion run + +source <(faas completion zsh) + +`, + ValidArgs: []string{"bash", "zsh"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) < 1 { + return errors.New("missing argument") + } + if args[0] == "bash" { + root.GenBashCompletion(os.Stdout) + return nil + } + if args[0] == "zsh" { + // manually edited script based on `root.GenBashCompletion(os.Stdout)` + // unfortunately it doesn't support completion so well as for bash + // some manual edits had to be done + os.Stdout.WriteString(` + +#compdef _faas faas + + +function _faas { + local -a commands + + _arguments -C \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' \ + "1: :->cmnds" \ + "*::arg:->args" + + case $state in + cmnds) + commands=( + "completion:Generates bash completion scripts" + "create:Create a Service Function" + "delete:Delete deployed Service Function" + "describe:Describe Service Function" + "help:Help about any command" + "list:Lists deployed Service Functions" + "run:Run Service Function locally" + "update:Update or create a deployed Service Function" + "version:Print version" + ) + _describe "command" commands + ;; + esac + + case "$words[1]" in + completion) + _faas_completion + ;; + create) + _faas_create + ;; + delete) + _faas_delete + ;; + describe) + _faas_describe + ;; + help) + _faas_help + ;; + list) + _faas_list + ;; + run) + _faas_run + ;; + update) + _faas_update + ;; + version) + _faas_version + ;; + esac +} + +function _list_funs() { + compadd $(faas list 2> /dev/null) +} + +function _list_langs() { + compadd js go java +} + +function _list_fmts() { + compadd yaml xml json +} + +function _faas_create { + _arguments \ + '1:string:_list_langs' \ + '(-i --internal)'{-i,--internal}'[Create a cluster-local service without a publicly accessible route. $FAAS_INTERNAL]' \ + '(-l --local)'{-l,--local}'[create the service function locally only.]' \ + '(-n --name)'{-n,--name}'[optionally specify an explicit name for the serive, overriding path-derivation. $FAAS_NAME]:' \ + '(-s --namespace)'{-s,--namespace}'[namespace at image registry (usually username or org name). $FAAS_NAMESPACE]:' \ + '(-r --registry)'{-r,--registry}'[image registry (ex: quay.io). $FAAS_REGISTRY]:' \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_delete { + _arguments \ + '(-n --name)'{-n,--name}'[optionally specify an explicit name to remove, overriding path-derivation. $FAAS_NAME]:string:_list_funs' \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_describe { + _arguments \ + '1:string:_list_funs' \ + '(-n --name)'{-n,--name}'[optionally specify an explicit name for the serive, overriding path-derivation. $FAAS_NAME]:string:_list_funs' \ + '(-o --output)'{-o,--output}'[optionally specify output format (yaml,xml,json).]:string:_list_fmts' \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_help { + _arguments \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_list { + _arguments \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_run { + _arguments \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_update { + _arguments \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + +function _faas_version { + _arguments \ + '--config[config file path]:' \ + '(-v --verbose)'{-v,--verbose}'[print verbose logs]' +} + + +`) + return nil + } + return errors.New("unknown shell, only bash and zsh are supported") + }, +} \ No newline at end of file diff --git a/cmd/create.go b/cmd/create.go index 2803e1f3..5f342b91 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -31,6 +31,8 @@ var createCmd = &cobra.Command{ Use: "create ", Short: "Create a Service Function", SuggestFor: []string{"init", "new"}, + ValidArgs: []string {"java", "go", "js"}, + Args: cobra.ExactArgs(1), RunE: create, PreRun: func(cmd *cobra.Command, args []string) { viper.BindPFlag("local", cmd.Flags().Lookup("local")) diff --git a/cmd/delete.go b/cmd/delete.go index 2e7f7bbf..2cbe27f1 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/boson-project/faas" + "github.com/boson-project/faas/knative" "github.com/boson-project/faas/kubectl" "github.com/ory/viper" "github.com/spf13/cobra" @@ -10,6 +11,21 @@ import ( func init() { root.AddCommand(deleteCmd) deleteCmd.Flags().StringP("name", "n", "", "optionally specify an explicit name to remove, overriding path-derivation. $FAAS_NAME") + deleteCmd.RegisterFlagCompletionFunc("name", func(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) { + lister, err := knative.NewLister(faas.DefaultNamespace) + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + s, err := lister.List() + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + strings = s + directive = cobra.ShellCompDirectiveDefault + return + }) } var deleteCmd = &cobra.Command{ diff --git a/cmd/describe.go b/cmd/describe.go index fd76ad04..550456bd 100644 --- a/cmd/describe.go +++ b/cmd/describe.go @@ -20,6 +20,28 @@ func init() { describeCmd.Flags().StringP("output", "o", "yaml", "optionally specify output format (yaml,xml,json).") describeCmd.Flags().StringP("name", "n", "", "optionally specify an explicit name for the serive, overriding path-derivation. $FAAS_NAME") + + describeCmd.RegisterFlagCompletionFunc("name", func(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) { + lister, err := knative.NewLister(faas.DefaultNamespace) + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + s, err := lister.List() + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + strings = s + directive = cobra.ShellCompDirectiveDefault + return + }) + + describeCmd.RegisterFlagCompletionFunc("output", func(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) { + directive = cobra.ShellCompDirectiveDefault + strings = []string{"yaml", "xml", "json"} + return + }) } var describeCmd = &cobra.Command{ @@ -27,6 +49,22 @@ var describeCmd = &cobra.Command{ Short: "Describe Service Function", Long: `Describe Service Function`, SuggestFor: []string{"desc"}, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) { + lister, err := knative.NewLister(faas.DefaultNamespace) + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + s, err := lister.List() + if err != nil { + directive = cobra.ShellCompDirectiveError + return + } + strings = s + directive = cobra.ShellCompDirectiveDefault + return + }, + Args: cobra.ExactArgs(1), RunE: describe, PreRun: func(cmd *cobra.Command, args []string) { viper.BindPFlag("output", cmd.Flags().Lookup("output"))