Add shell completion for bash and zsh

This commit is contained in:
Matej Vasek 2020-05-26 23:15:37 +02:00
parent a0e9fcb11c
commit acbaf48c0b
4 changed files with 230 additions and 0 deletions

174
cmd/completion.go Normal file
View File

@ -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")
},
}

View File

@ -31,6 +31,8 @@ var createCmd = &cobra.Command{
Use: "create <language>",
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"))

View File

@ -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{

View File

@ -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"))