mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Added the project auto completion code (#959)
* Added the project auto completion code Signed-off-by: mik-dass <mrinald7@gmail.com> * Added getUserTypedCommands function fro getting user typed entitites Signed-off-by: mik-dass <mrinald7@gmail.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -151,6 +152,7 @@ func printUnmountedStorage(client *occlient.Client, applicationName string) {
|
||||
|
||||
func addProjectFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().String(util.ProjectFlagName, "", "Project, defaults to active project")
|
||||
completion.RegisterCommandFlagHandler(cmd, "project", completion.ProjectNameCompletionHandler)
|
||||
}
|
||||
|
||||
func addComponentFlag(cmd *cobra.Command) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -200,6 +201,7 @@ func init() {
|
||||
projectGetCmd.Flags().BoolVarP(&projectShortFlag, "short", "q", false, "If true, display only the project name")
|
||||
projectSetCmd.Flags().BoolVarP(&projectShortFlag, "short", "q", false, "If true, display only the project name")
|
||||
projectDeleteCmd.Flags().BoolVarP(&projectForceDeleteFlag, "force", "f", false, "Delete project without prompting")
|
||||
projectDeleteCmd.Flags().BoolVarP(&projectShortFlag, "short", "q", false, "Delete project without prompting")
|
||||
|
||||
projectCmd.Flags().AddFlagSet(projectGetCmd.Flags())
|
||||
projectCmd.AddCommand(projectGetCmd)
|
||||
@@ -212,5 +214,8 @@ func init() {
|
||||
projectCmd.Annotations = map[string]string{"command": "other"}
|
||||
projectCmd.SetUsageTemplate(cmdUsageTemplate)
|
||||
|
||||
completion.RegisterCommandHandler(projectSetCmd, completion.ProjectNameCompletionHandler)
|
||||
completion.RegisterCommandHandler(projectDeleteCmd, completion.ProjectNameCompletionHandler)
|
||||
|
||||
rootCmd.AddCommand(projectCmd)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/redhat-developer/odo/pkg/occlient"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/redhat-developer/odo/pkg/odo/util/completion"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ktesting "k8s.io/client-go/testing"
|
||||
@@ -20,17 +21,20 @@ func TestCompletions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
handler completion.ContextualizedPredictor
|
||||
cmd *cobra.Command
|
||||
last string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "Completing service create without input returns all available service class external names",
|
||||
handler: completion.ServiceClassCompletionHandler,
|
||||
cmd: serviceCreateCmd,
|
||||
want: []string{"foo", "bar", "boo"},
|
||||
},
|
||||
{
|
||||
name: "Completing service delete without input returns all available service instances",
|
||||
handler: completion.ServiceCompletionHandler,
|
||||
cmd: serviceDeleteCmd,
|
||||
want: []string{"foo"},
|
||||
},
|
||||
}
|
||||
@@ -67,7 +71,9 @@ func TestCompletions(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := complete.Args{Last: tt.last}
|
||||
got := tt.handler(nil, a, context)
|
||||
|
||||
got := tt.handler(tt.cmd, a, context)
|
||||
|
||||
if !equal(got, tt.want) {
|
||||
t.Errorf("Failed %s: got: %q, want: %q", t.Name(), got, tt.want)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/posener/complete"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type completionHandler struct {
|
||||
@@ -77,3 +78,52 @@ func GetCommandFlagHandler(command *cobra.Command, flag string) (predictor compl
|
||||
predictor, ok = completionHandlers[getCommandFlagCompletionHandlerKey(command, flag)]
|
||||
return
|
||||
}
|
||||
|
||||
// getCommandsAndFlags returns the commands and flags from the given input
|
||||
func getCommandsAndFlags(args []string, c *cobra.Command) (map[string]bool, map[string]string) {
|
||||
strippedCommandsMap := make(map[string]bool)
|
||||
setFlags := make(map[string]string)
|
||||
|
||||
if len(args) == 0 {
|
||||
return strippedCommandsMap, setFlags
|
||||
}
|
||||
err := c.ParseFlags(args)
|
||||
if err != nil {
|
||||
return strippedCommandsMap, setFlags
|
||||
}
|
||||
|
||||
flags := c.Flags()
|
||||
|
||||
cmds := flags.Args()
|
||||
flags.Visit(func(i *flag.Flag) {
|
||||
if i.Value.Type() != "bool" {
|
||||
setFlags[i.Name] = i.Value.String()
|
||||
}
|
||||
})
|
||||
|
||||
// send a map of commands for faster searching
|
||||
for _, strippedCommand := range cmds {
|
||||
strippedCommandsMap[strippedCommand] = true
|
||||
}
|
||||
|
||||
return strippedCommandsMap, setFlags
|
||||
}
|
||||
|
||||
// getUserTypedCommands returns only the user typed entities by excluding the cobra predefined commands
|
||||
func getUserTypedCommands(args complete.Args, command *cobra.Command) []string {
|
||||
var commands []string
|
||||
|
||||
// get only the user typed commands/flags and remove the cobra defined commands
|
||||
found := false
|
||||
for _, arg := range args.Completed {
|
||||
if arg == command.Name() && !found {
|
||||
found = true
|
||||
continue
|
||||
}
|
||||
if found {
|
||||
commands = append(commands, arg)
|
||||
}
|
||||
}
|
||||
|
||||
return commands
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/posener/complete"
|
||||
"github.com/redhat-developer/odo/pkg/application"
|
||||
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
|
||||
"github.com/redhat-developer/odo/pkg/project"
|
||||
"github.com/redhat-developer/odo/pkg/service"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -59,3 +60,23 @@ var FileCompletionHandler = func(cmd *cobra.Command, args complete.Args, context
|
||||
completions = append(completions, complete.PredictFiles("*").Predict(args)...)
|
||||
return
|
||||
}
|
||||
|
||||
// ProjectNameCompletionHandler provides project name completion
|
||||
var ProjectNameCompletionHandler = func(cmd *cobra.Command, args complete.Args, context *genericclioptions.Context) (completions []string) {
|
||||
completions = make([]string, 0)
|
||||
projects, err := project.List(context.Client)
|
||||
if err != nil {
|
||||
return completions
|
||||
}
|
||||
// extract the flags and commands from the user typed commands
|
||||
strippedCommands, _ := getCommandsAndFlags(getUserTypedCommands(args, cmd), cmd)
|
||||
for _, project := range projects {
|
||||
// we found the project name in the list which means
|
||||
// that the project name has been already selected by the user so no need to suggest more
|
||||
if val, ok := strippedCommands[project.Name]; ok && val {
|
||||
return nil
|
||||
}
|
||||
completions = append(completions, project.Name)
|
||||
}
|
||||
return completions
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user