feat(group): add 'madb group rename' command
Change-Id: I67e1ac2c9cacfc2714a1655e0b2f1d60daf9333a
diff --git a/doc.go b/doc.go
index 31b6310..d60a6f3 100644
--- a/doc.go
+++ b/doc.go
@@ -233,6 +233,7 @@
The madb group commands are:
add Add members to a device group
remove Remove members from a device group
+ rename Rename an existing device group
Madb group add - Add members to a device group
@@ -269,6 +270,19 @@
<member> is a member specifier, which can be one of device serial, qualifier,
device index (e.g., '@1', '@2'), device nickname, or another device group.
+Madb group rename - Rename an existing device group
+
+Renames an existing device group.
+
+Usage:
+ madb group rename [flags] <old_name> <new_name>
+
+<old_name> is the name of an existing device group.
+
+<new_name> is the new name for the existing group. This must be an alpha-numeric
+string with no special characters or spaces, and must not conflict with another
+existing device or group name.
+
Madb install - Install your app on all devices
Installs your app on all devices.
diff --git a/group.go b/group.go
index dc1e563..2cbaf1d 100644
--- a/group.go
+++ b/group.go
@@ -13,7 +13,6 @@
)
// TODO(youngseokyoon): implement the following sub-commands.
-// - rename: rename a group
// - delete: delete a group
// - list: list all the groups and their members
// - clear-all: delete all the existing device groups
@@ -21,7 +20,11 @@
// TODO(youngseokyoon): use the groups for filtering devices.
var cmdMadbGroup = &cmdline.Command{
- Children: []*cmdline.Command{cmdMadbGroupAdd, cmdMadbGroupRemove},
+ Children: []*cmdline.Command{
+ cmdMadbGroupAdd,
+ cmdMadbGroupRemove,
+ cmdMadbGroupRename,
+ },
Name: "group",
DontInheritFlags: true,
Short: "Manage device groups",
@@ -140,6 +143,54 @@
return writeConfig(cfg, filename)
}
+var cmdMadbGroupRename = &cmdline.Command{
+ Runner: subCommandRunnerWithFilepath{runMadbGroupRename, getDefaultConfigFilePath},
+ Name: "rename",
+ Short: "Rename an existing device group",
+ Long: `
+Renames an existing device group.
+`,
+ ArgsName: "<old_name> <new_name>",
+ ArgsLong: `
+<old_name> is the name of an existing device group.
+
+<new_name> is the new name for the existing group.
+This must be an alpha-numeric string with no special characters or spaces,
+and must not conflict with another existing device or group name.
+`,
+}
+
+func runMadbGroupRename(env *cmdline.Env, args []string, filename string) error {
+ // Check if the arguments are valid.
+ if len(args) != 2 {
+ return env.UsageErrorf("There must be exactly two arguments.")
+ }
+
+ oldName, newName := args[0], args[1]
+ if !isValidName(oldName) {
+ return fmt.Errorf("Not a valid group name: %q", oldName)
+ }
+ if !isValidName(newName) {
+ return fmt.Errorf("Not a valid group name: %q", newName)
+ }
+
+ cfg, err := readConfig(filename)
+ if err != nil {
+ return err
+ }
+ if !isGroupName(oldName, cfg) {
+ return fmt.Errorf("Not an existing group name: %q", oldName)
+ }
+ if isNameInUse(newName, cfg) {
+ return fmt.Errorf("The provided name is already in use: %q", newName)
+ }
+
+ cfg.Groups[newName] = cfg.Groups[oldName]
+ delete(cfg.Groups, oldName)
+
+ return writeConfig(cfg, filename)
+}
+
// isValidMember takes a member string given as an argument, and returns nil
// when the member string is valid. Otherwise, an error is returned inicating
// the reason why the given member string is not valid.
diff --git a/group_test.go b/group_test.go
index a364714..23c235b 100644
--- a/group_test.go
+++ b/group_test.go
@@ -224,3 +224,101 @@
runGroupTests(t, tests)
}
+
+func TestMadbGroupRename(t *testing.T) {
+ tests := []testSequence{
+ {
+ {
+ runMadbGroupRename,
+ []string{},
+ map[string][]string{},
+ true,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP1"},
+ map[string][]string{},
+ true,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP1", "GROUP2"},
+ map[string][]string{},
+ true,
+ },
+ },
+ {
+ {
+ runMadbGroupAdd,
+ []string{"GROUP1", "SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"},
+ map[string][]string{"GROUP1": []string{"SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"}},
+ false,
+ },
+ {
+ runMadbGroupAdd,
+ []string{"GROUP2", "SERIAL3", "NICKNAME4"},
+ map[string][]string{
+ "GROUP1": []string{"SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"},
+ "GROUP2": []string{"SERIAL3", "NICKNAME4"},
+ },
+ false,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP1", "GROUP3"},
+ map[string][]string{
+ "GROUP2": []string{"SERIAL3", "NICKNAME4"},
+ "GROUP3": []string{"SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"},
+ },
+ false,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP2", "_!@#"},
+ map[string][]string{
+ "GROUP2": []string{"SERIAL3", "NICKNAME4"},
+ "GROUP3": []string{"SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"},
+ },
+ true,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP2", "GROUP3"},
+ map[string][]string{
+ "GROUP2": []string{"SERIAL3", "NICKNAME4"},
+ "GROUP3": []string{"SERIAL1", "NICKNAME1", "NICKNAME2", "SERIAL2", "NICKNAME3"},
+ },
+ true,
+ },
+ },
+ }
+
+ runGroupTests(t, tests)
+}
+
+func TestMadbGroupRenameNameConflict(t *testing.T) {
+ tests := []testSequence{
+ {
+ {
+ runMadbNameSet,
+ []string{"SERIAL1", "NICKNAME1"},
+ map[string][]string{},
+ false,
+ },
+ {
+ runMadbGroupAdd,
+ []string{"GROUP1", "SERIAL1"},
+ map[string][]string{"GROUP1": []string{"SERIAL1"}},
+ false,
+ },
+ {
+ runMadbGroupRename,
+ []string{"GROUP1", "NICKNAME1"},
+ map[string][]string{"GROUP1": []string{"SERIAL1"}},
+ true,
+ },
+ },
+ }
+
+ runGroupTests(t, tests)
+}