Skip to content

Commit

Permalink
Merge pull request #620 from tursodatabase/athos/group-parameters
Browse files Browse the repository at this point in the history
Get turso db locations (add|remove) parameters from CLI arguments
  • Loading branch information
athoscouto authored Sep 11, 2023
2 parents 1b87dbf + abccaf9 commit 322d714
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 35 deletions.
4 changes: 2 additions & 2 deletions internal/cmd/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions internal/cmd/group_flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
88 changes: 59 additions & 29 deletions internal/cmd/group_locations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -17,19 +18,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
Expand All @@ -38,7 +39,7 @@ var groupLocationsListCmd = &cobra.Command{
return err
}

groups, err := client.Groups.Get(groupFlag)
groups, err := client.Groups.Get(group)
if err != nil {
return err
}
Expand All @@ -49,13 +50,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),
ValidArgsFunction: noFilesArg,
Args: cobra.MinimumNArgs(2),
ValidArgsFunction: locationsCmdsArgs,
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
Expand All @@ -64,7 +66,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)
}
Expand All @@ -74,29 +77,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),
ValidArgsFunction: noFilesArg,
Args: cobra.MinimumNArgs(2),
ValidArgsFunction: locationsCmdsArgs,
RunE: func(cmd *cobra.Command, args []string) error {
if groupFlag == "" {
groupName := args[0]
if groupName == "" {
return fmt.Errorf("the group flag is required")
}

Expand All @@ -106,36 +116,56 @@ 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)
}
}

start := time.Now()
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
},
}

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
}

0 comments on commit 322d714

Please sign in to comment.