From c6c7cabc10d81e08c9b6735fc5d0ceecbcc54e79 Mon Sep 17 00:00:00 2001 From: Athos Couto Date: Mon, 11 Sep 2023 10:26:56 -0300 Subject: [PATCH 1/3] Use parameters for group and locations on turso group locations cmds --- internal/cmd/group_flag.go | 4 -- internal/cmd/group_locations.go | 70 ++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/internal/cmd/group_flag.go b/internal/cmd/group_flag.go index 8dd39302..67a56048 100644 --- a/internal/cmd/group_flag.go +++ b/internal/cmd/group_flag.go @@ -8,7 +8,3 @@ func addGroupFlag(cmd *cobra.Command) { cmd.Flags().StringVar(&groupFlag, "group", "", "create the database in the specified group") cmd.Flags().MarkHidden("group") } - -func addPersistentGroupFlag(cmd *cobra.Command, description string) { - cmd.PersistentFlags().StringVarP(&groupFlag, "group", "g", "", description) -} diff --git a/internal/cmd/group_locations.go b/internal/cmd/group_locations.go index 64409c9d..6e5c90df 100644 --- a/internal/cmd/group_locations.go +++ b/internal/cmd/group_locations.go @@ -17,19 +17,19 @@ var groupLocationsCmd = &cobra.Command{ func init() { groupCmd.AddCommand(groupLocationsCmd) groupLocationsCmd.AddCommand(groupLocationsListCmd) - addPersistentGroupFlag(groupLocationsCmd, "Use the specified group as target for the operation") groupLocationsCmd.AddCommand(groupLocationAddCmd) groupLocationsCmd.AddCommand(groupsLocationsRmCmd) } var groupLocationsListCmd = &cobra.Command{ - Use: "list", + Use: "list [group]", Short: "List database group locations", - Args: cobra.NoArgs, + Args: cobra.ExactArgs(1), ValidArgsFunction: noFilesArg, RunE: func(cmd *cobra.Command, args []string) error { - if groupFlag == "" { - return fmt.Errorf("the group flag is required") + group := args[0] + if group == "" { + return fmt.Errorf("the first argument must contain a group name") } cmd.SilenceUsage = true @@ -38,7 +38,7 @@ var groupLocationsListCmd = &cobra.Command{ return err } - groups, err := client.Groups.Get(groupFlag) + groups, err := client.Groups.Get(group) if err != nil { return err } @@ -49,13 +49,14 @@ var groupLocationsListCmd = &cobra.Command{ } var groupLocationAddCmd = &cobra.Command{ - Use: "add [...locations]", + Use: "add [group] [...locations]", Short: "Add locations to a database group", - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(2), ValidArgsFunction: noFilesArg, RunE: func(cmd *cobra.Command, args []string) error { - if groupFlag == "" { - return fmt.Errorf("the group flag is required") + group := args[0] + if group == "" { + return fmt.Errorf("the first argument must contain a group name") } cmd.SilenceUsage = true @@ -64,7 +65,8 @@ var groupLocationAddCmd = &cobra.Command{ return err } - for _, location := range args { + locations := args[1:] + for _, location := range locations { if !isValidLocation(client, location) { return fmt.Errorf("location '%s' is not a valid one", location) } @@ -74,29 +76,36 @@ var groupLocationAddCmd = &cobra.Command{ spinner := prompt.Spinner("") defer spinner.Stop() - for _, location := range args { - description := fmt.Sprintf("Replicating group %s to %s...", internal.Emph(groupFlag), internal.Emph(location)) + for _, location := range locations { + description := fmt.Sprintf("Replicating group %s to %s...", internal.Emph(group), internal.Emph(location)) spinner.Text(description) - if err := client.Groups.AddLocation(groupFlag, location); err != nil { - return fmt.Errorf("failed to replicate group %s to %s: %w", groupFlag, location, err) + if err := client.Groups.AddLocation(group, location); err != nil { + return fmt.Errorf("failed to replicate group %s to %s: %w", group, location, err) } } spinner.Stop() elapsed := time.Since(start) - fmt.Printf("Group %s replicated to %d locations in %d seconds.\n", internal.Emph(groupFlag), len(args), int(elapsed.Seconds())) + + if len(locations) == 1 { + fmt.Printf("Group %s replicated to %s in %d seconds.\n", internal.Emph(group), internal.Emph(locations[0]), int(elapsed.Seconds())) + return nil + } + + fmt.Printf("Group %s replicated to %d locations in %d seconds.\n", internal.Emph(group), len(locations), int(elapsed.Seconds())) return nil }, } var groupsLocationsRmCmd = &cobra.Command{ - Use: "remove [...locations]", + Use: "remove [group] [...locations]", Short: "Remove locations from a database group", - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(2), ValidArgsFunction: noFilesArg, RunE: func(cmd *cobra.Command, args []string) error { - if groupFlag == "" { + groupName := args[0] + if groupName == "" { return fmt.Errorf("the group flag is required") } @@ -106,17 +115,18 @@ var groupsLocationsRmCmd = &cobra.Command{ return err } - group, err := client.Groups.Get(groupFlag) + group, err := client.Groups.Get(groupName) if err != nil { return err } - for _, location := range args { + locations := args[1:] + for _, location := range locations { if !isValidLocation(client, location) { return fmt.Errorf("location '%s' is not a valid one", location) } if group.Primary == location { - return fmt.Errorf("cannot remove primary location '%s' from group '%s'", location, groupFlag) + return fmt.Errorf("cannot remove primary location '%s' from group '%s'", location, groupName) } } @@ -124,18 +134,24 @@ var groupsLocationsRmCmd = &cobra.Command{ spinner := prompt.Spinner("") defer spinner.Stop() - for _, location := range args { - description := fmt.Sprintf("Removing group %s from %s...", internal.Emph(groupFlag), internal.Emph(location)) + for _, location := range locations { + description := fmt.Sprintf("Removing group %s from %s...", internal.Emph(groupName), internal.Emph(location)) spinner.Text(description) - if err := client.Groups.RemoveLocation(groupFlag, location); err != nil { - return fmt.Errorf("failed to remove group %s from %s: %w", groupFlag, location, err) + if err := client.Groups.RemoveLocation(groupName, location); err != nil { + return fmt.Errorf("failed to remove group %s from %s: %w", groupName, location, err) } } spinner.Stop() elapsed := time.Since(start) - fmt.Printf("Group %s removed from %d locations in %d seconds.\n", internal.Emph(groupFlag), len(args), int(elapsed.Seconds())) + + if len(locations) == 1 { + fmt.Printf("Group %s removed from %s in %d seconds.\n", internal.Emph(groupName), internal.Emph(locations[0]), int(elapsed.Seconds())) + return nil + } + + fmt.Printf("Group %s removed from %d locations in %d seconds.\n", internal.Emph(groupName), len(locations), int(elapsed.Seconds())) return nil }, } From 17fc9bbffbdf55cca7db7fc8bcf1f67e5fc3a955 Mon Sep 17 00:00:00 2001 From: Athos Couto Date: Mon, 11 Sep 2023 10:28:43 -0300 Subject: [PATCH 2/3] Get group as the first parameter and locations as flags on turso group locations cmds --- internal/cmd/group.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/group.go b/internal/cmd/group.go index c41e6845..5a94bda8 100644 --- a/internal/cmd/group.go +++ b/internal/cmd/group.go @@ -48,7 +48,7 @@ var groupsListCmd = &cobra.Command{ } var groupsCreateCmd = &cobra.Command{ - Use: "create [group_name]", + Use: "create [group]", Short: "Create a database group", Args: cobra.ExactArgs(1), ValidArgsFunction: noFilesArg, @@ -89,7 +89,7 @@ var groupsCreateCmd = &cobra.Command{ } var groupsDestroyCmd = &cobra.Command{ - Use: "destroy [group_name]", + Use: "destroy [group]", Short: "Destroy a database group", Args: cobra.ExactArgs(1), ValidArgsFunction: noFilesArg, From abccaf9a391544a8eec55b27be038d6d86fed9a7 Mon Sep 17 00:00:00 2001 From: Athos Couto Date: Mon, 11 Sep 2023 10:32:12 -0300 Subject: [PATCH 3/3] Add autocompletion for regions at turso group locations (add|remove) --- internal/cmd/group_locations.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/internal/cmd/group_locations.go b/internal/cmd/group_locations.go index 6e5c90df..ee60d81f 100644 --- a/internal/cmd/group_locations.go +++ b/internal/cmd/group_locations.go @@ -7,6 +7,7 @@ import ( "github.com/chiselstrike/iku-turso-cli/internal" "github.com/chiselstrike/iku-turso-cli/internal/prompt" "github.com/spf13/cobra" + "golang.org/x/exp/maps" ) var groupLocationsCmd = &cobra.Command{ @@ -52,7 +53,7 @@ var groupLocationAddCmd = &cobra.Command{ Use: "add [group] [...locations]", Short: "Add locations to a database group", Args: cobra.MinimumNArgs(2), - ValidArgsFunction: noFilesArg, + ValidArgsFunction: locationsCmdsArgs, RunE: func(cmd *cobra.Command, args []string) error { group := args[0] if group == "" { @@ -102,7 +103,7 @@ var groupsLocationsRmCmd = &cobra.Command{ Use: "remove [group] [...locations]", Short: "Remove locations from a database group", Args: cobra.MinimumNArgs(2), - ValidArgsFunction: noFilesArg, + ValidArgsFunction: locationsCmdsArgs, RunE: func(cmd *cobra.Command, args []string) error { groupName := args[0] if groupName == "" { @@ -155,3 +156,16 @@ var groupsLocationsRmCmd = &cobra.Command{ return nil }, } + +func locationsCmdsArgs(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + client, err := createTursoClientFromAccessToken(false) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace + } + if len(args) == 0 { + // TODO: add completion for group names + return nil, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace + } + locations, _ := locations(client) + return maps.Keys(locations), cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace +}