diff --git a/internal/core/autocomplete.go b/internal/core/autocomplete.go index a14b676ce3..3a26548193 100644 --- a/internal/core/autocomplete.go +++ b/internal/core/autocomplete.go @@ -37,7 +37,7 @@ const ( // AutoCompleteArgFunc is the function called to complete arguments values. // It is retrieved from core.ArgSpec.AutoCompleteFunc. -type AutoCompleteArgFunc func(ctx context.Context, prefix string) AutocompleteSuggestions +type AutoCompleteArgFunc func(ctx context.Context, prefix string, request any) AutocompleteSuggestions // AutoCompleteNode is a node in the AutoComplete Tree. // An AutoCompleteNode can either represent a command, a subcommand, or a command argument. @@ -361,7 +361,7 @@ func AutoCompleteArgValue(ctx context.Context, cmd *Command, argSpec *ArgSpec, a return nil } if argSpec.AutoCompleteFunc != nil { - return argSpec.AutoCompleteFunc(ctx, argValuePrefix) + return argSpec.AutoCompleteFunc(ctx, argValuePrefix, requestFromCompletedArgs(cmd, completedArgs)) } possibleValues := []string(nil) diff --git a/internal/core/autocomplete_test.go b/internal/core/autocomplete_test.go index 7a225dc0ad..060311d6a7 100644 --- a/internal/core/autocomplete_test.go +++ b/internal/core/autocomplete_test.go @@ -29,7 +29,7 @@ func testAutocompleteGetCommands() *Commands { }, { Name: "size", - AutoCompleteFunc: func(_ context.Context, prefix string) AutocompleteSuggestions { + AutoCompleteFunc: func(_ context.Context, prefix string, _ any) AutocompleteSuggestions { return []string{regexp.MustCompile("[a-z]").ReplaceAllString(prefix, "")} }, EnumValues: []string{"S", "M", "L", "XL", "XXL"}, diff --git a/internal/core/autocomplete_utils.go b/internal/core/autocomplete_utils.go index c228e1bc26..b49ea1aa72 100644 --- a/internal/core/autocomplete_utils.go +++ b/internal/core/autocomplete_utils.go @@ -59,7 +59,7 @@ func getGlobalFlags(ctx context.Context) []FlagSpec { } func AutocompleteProfileName() AutoCompleteArgFunc { - return func(ctx context.Context, prefix string) AutocompleteSuggestions { + return func(ctx context.Context, prefix string, _ any) AutocompleteSuggestions { res := AutocompleteSuggestions(nil) configPath := ExtractConfigPath(ctx) config, err := scw.LoadConfigFromPath(configPath) @@ -204,3 +204,19 @@ func listRawArgsLocalities(completedArgs map[string]string, cmd *Command) []stri } return listRawArgs } + +func flattenCompleteArgs(completedArgs map[string]string) []string { + rawArgs := make([]string, 0, len(completedArgs)) + for arg, value := range completedArgs { + rawArgs = append(rawArgs, arg+value) // "region=" + "nl-ams" + } + + return rawArgs +} + +func requestFromCompletedArgs(cmd *Command, completedArgs map[string]string) any { + request := reflect.New(cmd.ArgsType).Interface() + _ = args.UnmarshalStruct(flattenCompleteArgs(completedArgs), request) + + return request +} diff --git a/internal/namespaces/iam/v1alpha1/custom.go b/internal/namespaces/iam/v1alpha1/custom.go index 45a15d7796..1e7748d8de 100644 --- a/internal/namespaces/iam/v1alpha1/custom.go +++ b/internal/namespaces/iam/v1alpha1/custom.go @@ -48,7 +48,7 @@ func GetCommands() *core.Commands { // Autocomplete permission set names using IAM API. cmds.MustFind("iam", "policy", "create").Override(func(c *core.Command) *core.Command { - c.ArgSpecs.GetByName("rules.{index}.permission-set-names.{index}").AutoCompleteFunc = func(ctx context.Context, _ string) core.AutocompleteSuggestions { + c.ArgSpecs.GetByName("rules.{index}.permission-set-names.{index}").AutoCompleteFunc = func(ctx context.Context, _ string, _ any) core.AutocompleteSuggestions { client := core.ExtractClient(ctx) api := iam.NewAPI(client) // TODO: store result in a CLI cache diff --git a/internal/namespaces/instance/v1/custom_server.go b/internal/namespaces/instance/v1/custom_server.go index 4b91cb0b47..acfbca82e0 100644 --- a/internal/namespaces/instance/v1/custom_server.go +++ b/internal/namespaces/instance/v1/custom_server.go @@ -323,9 +323,12 @@ func serverUpdateBuilder(c *core.Command) *core.Command { func serverGetBuilder(c *core.Command) *core.Command { // This method is here as a proof of concept before we find the correct way to implement it at larger scale - c.ArgSpecs.GetPositionalArg().AutoCompleteFunc = func(ctx context.Context, prefix string) core.AutocompleteSuggestions { + c.ArgSpecs.GetPositionalArg().AutoCompleteFunc = func(ctx context.Context, prefix string, request any) core.AutocompleteSuggestions { + req := request.(*instance.GetServerRequest) api := instance.NewAPI(core.ExtractClient(ctx)) - resp, err := api.ListServers(&instance.ListServersRequest{}, scw.WithAllPages()) + resp, err := api.ListServers(&instance.ListServersRequest{ + Zone: req.Zone, + }, scw.WithAllPages()) if err != nil { return nil } diff --git a/internal/namespaces/instance/v1/custom_server_create.go b/internal/namespaces/instance/v1/custom_server_create.go index 8eaf7dbc21..dcd9c33f0b 100644 --- a/internal/namespaces/instance/v1/custom_server_create.go +++ b/internal/namespaces/instance/v1/custom_server_create.go @@ -727,7 +727,7 @@ func sanitizeVolumeMap(serverName string, volumes map[string]*instance.VolumeSer // Caching listImage response for shell completion var completeListImagesCache *marketplace.ListImagesResponse -func instanceServerCreateImageAutoCompleteFunc(ctx context.Context, prefix string) core.AutocompleteSuggestions { +func instanceServerCreateImageAutoCompleteFunc(ctx context.Context, prefix string, _ any) core.AutocompleteSuggestions { suggestions := core.AutocompleteSuggestions(nil) client := core.ExtractClient(ctx) diff --git a/internal/namespaces/instance/v1/helpers_types.go b/internal/namespaces/instance/v1/helpers_types.go index 99976b222f..3a161fb116 100644 --- a/internal/namespaces/instance/v1/helpers_types.go +++ b/internal/namespaces/instance/v1/helpers_types.go @@ -68,7 +68,7 @@ var serverTypes = []string{ "H100-2-80G", } -func completeServerType(_ context.Context, prefix string) core.AutocompleteSuggestions { +func completeServerType(_ context.Context, prefix string, _ any) core.AutocompleteSuggestions { suggestions := []string(nil) for _, serverType := range serverTypes { diff --git a/internal/namespaces/k8s/v1/custom_cluster.go b/internal/namespaces/k8s/v1/custom_cluster.go index 0c27860e37..6b41fa3361 100644 --- a/internal/namespaces/k8s/v1/custom_cluster.go +++ b/internal/namespaces/k8s/v1/custom_cluster.go @@ -441,14 +441,17 @@ func k8sClusterWaitCommand() *core.Command { // Caching ListClusterTypes response for shell completion var completeListClusterTypesCache *k8s.ListClusterTypesResponse -func autocompleteClusterType(ctx context.Context, prefix string) core.AutocompleteSuggestions { +func autocompleteClusterType(ctx context.Context, prefix string, request any) core.AutocompleteSuggestions { + req := request.(*k8s.CreateClusterRequest) suggestions := core.AutocompleteSuggestions(nil) client := core.ExtractClient(ctx) api := k8s.NewAPI(client) if completeListClusterTypesCache == nil { - res, err := api.ListClusterTypes(&k8s.ListClusterTypesRequest{}) + res, err := api.ListClusterTypes(&k8s.ListClusterTypesRequest{ + Region: req.Region, + }) if err != nil { return nil } @@ -467,14 +470,17 @@ func autocompleteClusterType(ctx context.Context, prefix string) core.Autocomple // Caching ListK8SVersions response for shell completion var completeListK8SVersionsCache *k8s.ListVersionsResponse -func autocompleteK8SVersion(ctx context.Context, prefix string) core.AutocompleteSuggestions { +func autocompleteK8SVersion(ctx context.Context, prefix string, request any) core.AutocompleteSuggestions { + req := request.(*k8s.CreateClusterRequest) suggestions := core.AutocompleteSuggestions(nil) client := core.ExtractClient(ctx) api := k8s.NewAPI(client) if completeListK8SVersionsCache == nil { - res, err := api.ListVersions(&k8s.ListVersionsRequest{}) + res, err := api.ListVersions(&k8s.ListVersionsRequest{ + Region: req.Region, + }) if err != nil { return nil } diff --git a/internal/namespaces/rdb/v1/custom_instance.go b/internal/namespaces/rdb/v1/custom_instance.go index 6000c13a33..69b9619c28 100644 --- a/internal/namespaces/rdb/v1/custom_instance.go +++ b/internal/namespaces/rdb/v1/custom_instance.go @@ -170,14 +170,24 @@ var completeListNodeTypeCache *rdb.ListNodeTypesResponse var completeListEngineCache *rdb.ListDatabaseEnginesResponse -func autoCompleteNodeType(ctx context.Context, prefix string) core.AutocompleteSuggestions { +func autoCompleteNodeType(ctx context.Context, prefix string, request any) core.AutocompleteSuggestions { + region := scw.Region("") + switch req := request.(type) { + case *rdb.CreateInstanceRequest: + region = req.Region + case *rdb.UpgradeInstanceRequest: + region = req.Region + } + suggestions := core.AutocompleteSuggestions(nil) client := core.ExtractClient(ctx) api := rdb.NewAPI(client) if completeListNodeTypeCache == nil { - res, err := api.ListNodeTypes(&rdb.ListNodeTypesRequest{}, scw.WithAllPages()) + res, err := api.ListNodeTypes(&rdb.ListNodeTypesRequest{ + Region: region, + }, scw.WithAllPages()) if err != nil { return nil } @@ -193,13 +203,16 @@ func autoCompleteNodeType(ctx context.Context, prefix string) core.AutocompleteS return suggestions } -func autoCompleteDatabaseEngines(ctx context.Context, prefix string) core.AutocompleteSuggestions { +func autoCompleteDatabaseEngines(ctx context.Context, prefix string, request any) core.AutocompleteSuggestions { + req := request.(*rdb.CreateInstanceRequest) suggestion := core.AutocompleteSuggestions(nil) client := core.ExtractClient(ctx) api := rdb.NewAPI(client) if completeListEngineCache == nil { - res, err := api.ListDatabaseEngines(&rdb.ListDatabaseEnginesRequest{}, scw.WithAllPages()) + res, err := api.ListDatabaseEngines(&rdb.ListDatabaseEnginesRequest{ + Region: req.Region, + }, scw.WithAllPages()) if err != nil { return nil }