devtools/madb: specify devices with their indices.
This allows users to specify devices with their devices indicies. For
example,
madb -n=@1,@2 start
will only start the app on the first and second devices, and not on
the res.
Change-Id: I96573e50e5693e5ca5abbb7ad4b4d851ee33fa7b
diff --git a/doc.go b/doc.go
index 1e78339..5733921 100644
--- a/doc.go
+++ b/doc.go
@@ -30,8 +30,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
The global flags are:
-metadata=<just specify -metadata to activate>
@@ -78,8 +80,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb exec - Run the provided adb command on all devices and emulators concurrently
@@ -106,8 +110,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb name - Manage device nicknames
@@ -129,8 +135,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb name set
@@ -171,8 +179,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb name unset
@@ -191,8 +201,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb name list
@@ -207,8 +219,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb name clear-all
@@ -223,8 +237,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb start - Launch your app on all devices
@@ -279,8 +295,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb stop - Stop your app on all devices
@@ -324,8 +342,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb uninstall - Uninstall your app from all devices
@@ -368,8 +388,10 @@
-e=false
Restrict the command to only run on emulators.
-n=
- Comma-separated device serials, qualifiers, or nicknames (set by 'madb
- name'). Command will be run only on specified devices.
+ Comma-separated device serials, qualifiers, device indices (e.g., '@1',
+ '@2'), or nicknames (set by 'madb name'). A device index is specified by an
+ '@' sign followed by the index of the device in the output of 'adb devices'
+ command, starting from 1. Command will be run only on specified devices.
Madb help - Display help for commands or topics
diff --git a/madb.go b/madb.go
index 5542a84..7078841 100644
--- a/madb.go
+++ b/madb.go
@@ -16,6 +16,7 @@
"os/exec"
"path"
"path/filepath"
+ "strconv"
"strings"
"sync"
@@ -39,7 +40,7 @@
func init() {
cmdMadb.Flags.BoolVar(&allDevicesFlag, "d", false, `Restrict the command to only run on real devices.`)
cmdMadb.Flags.BoolVar(&allEmulatorsFlag, "e", false, `Restrict the command to only run on emulators.`)
- cmdMadb.Flags.StringVar(&devicesFlag, "n", "", `Comma-separated device serials, qualifiers, or nicknames (set by 'madb name'). Command will be run only on specified devices.`)
+ cmdMadb.Flags.StringVar(&devicesFlag, "n", "", `Comma-separated device serials, qualifiers, device indices (e.g., '@1', '@2'), or nicknames (set by 'madb name'). A device index is specified by an '@' sign followed by the index of the device in the output of 'adb devices' command, starting from 1. Command will be run only on specified devices.`)
// Store the current working directory.
var err error
@@ -95,6 +96,7 @@
Type deviceType
Qualifiers []string
Nickname string
+ Index int
}
// Returns the display name which is intended to be used as the console output prefix.
@@ -135,17 +137,18 @@
}
// Iterate over all the device serial numbers, starting from the second line.
- for _, line := range lines[1:] {
+ for i, line := range lines[1:] {
fields := strings.Fields(line)
if len(fields) <= 1 || fields[1] == "offline" {
continue
}
- // Fill in the device serial and all the qualifiers.
+ // Fill in the device serial, all the qualifiers, and the device index.
d := device{
Serial: fields[0],
Qualifiers: fields[2:],
+ Index: i + 1,
}
// Determine whether this device is an emulator or a real device.
@@ -191,7 +194,10 @@
return nil, err
}
- filtered := filterSpecifiedDevices(allDevices)
+ filtered, err := filterSpecifiedDevices(allDevices)
+ if err != nil {
+ return nil, err
+ }
if len(filtered) == 0 {
return nil, fmt.Errorf("No devices matching the device specifiers.")
@@ -200,21 +206,42 @@
return filtered, nil
}
-func filterSpecifiedDevices(devices []device) []device {
+type deviceSpec struct {
+ index int
+ token string
+}
+
+func filterSpecifiedDevices(devices []device) ([]device, error) {
// If no device specifier flags are set, run on all devices and emulators.
if noDevicesSpecified() {
- return devices
+ return devices, nil
}
result := make([]device, 0, len(devices))
+ var specs = []deviceSpec{}
+ if devicesFlag != "" {
+ tokens := strings.Split(devicesFlag, ",")
+ for _, token := range tokens {
+ if strings.HasPrefix(token, "@") {
+ index, err := strconv.Atoi(token[1:])
+ if err != nil || index <= 0 {
+ return nil, fmt.Errorf("Invalid device specifier %q. '@' sign must be followed by a numeric device index starting from 1.", token)
+ }
+ specs = append(specs, deviceSpec{index, ""})
+ } else {
+ specs = append(specs, deviceSpec{0, token})
+ }
+ }
+ }
+
for _, d := range devices {
- if shouldIncludeDevice(d) {
+ if shouldIncludeDevice(d, specs) {
result = append(result, d)
}
}
- return result
+ return result, nil
}
func noDevicesSpecified() bool {
@@ -223,7 +250,7 @@
devicesFlag == ""
}
-func shouldIncludeDevice(d device) bool {
+func shouldIncludeDevice(d device, specs []deviceSpec) bool {
if allDevicesFlag && d.Type == realDevice {
return true
}
@@ -232,19 +259,25 @@
return true
}
- tokens := strings.Split(devicesFlag, ",")
- for _, token := range tokens {
+ for _, spec := range specs {
// Ignore empty tokens
- if token == "" {
+ if spec.index == 0 && spec.token == "" {
continue
}
- if d.Serial == token || d.Nickname == token {
+ if spec.index > 0 {
+ if d.Index == spec.index {
+ return true
+ }
+ continue
+ }
+
+ if d.Serial == spec.token || d.Nickname == spec.token {
return true
}
for _, qualifier := range d.Qualifiers {
- if qualifier == token {
+ if qualifier == spec.token {
return true
}
}
diff --git a/madb_test.go b/madb_test.go
index 261c592..6c4ec79 100644
--- a/madb_test.go
+++ b/madb_test.go
@@ -43,12 +43,14 @@
Type: realDevice,
Qualifiers: []string{"usb:3-3.4.3", "product:bullhead", "model:Nexus_5X", "device:bullhead"},
Nickname: "",
+ Index: 1,
},
device{
Serial: "emulator-5554",
Type: emulator,
Qualifiers: []string{"product:sdk_phone_armv7", "model:sdk_phone_armv7", "device:generic"},
Nickname: "",
+ Index: 2,
},
}
@@ -86,6 +88,7 @@
Type: realDevice,
Qualifiers: []string{"product:sdk_phone_armv7", "model:sdk_phone_armv7", "device:generic"},
Nickname: "",
+ Index: 2,
},
}
@@ -116,12 +119,14 @@
Type: realDevice,
Qualifiers: []string{"usb:3-3.4.3", "product:bullhead", "model:Nexus_5X", "device:bullhead"},
Nickname: "MyPhone",
+ Index: 1,
},
device{
Serial: "emulator-5554",
Type: emulator,
Qualifiers: []string{"product:sdk_phone_armv7", "model:sdk_phone_armv7", "device:generic"},
Nickname: "ARMv7",
+ Index: 2,
},
}
@@ -137,6 +142,7 @@
Type: realDevice,
Qualifiers: []string{"usb:3-3.4.3", "product:bullhead", "model:Nexus_5X", "device:bullhead"},
Nickname: "MyPhone",
+ Index: 1,
}
d2 := device{
@@ -144,6 +150,7 @@
Type: realDevice,
Qualifiers: []string{"usb:3-3.4.1", "product:volantisg", "model:Nexus_9", "device:flounder_lte"},
Nickname: "",
+ Index: 2,
}
e1 := device{
@@ -151,6 +158,7 @@
Type: emulator,
Qualifiers: []string{"product:sdk_phone_armv7", "model:sdk_phone_armv7", "device:generic"},
Nickname: "ARMv7",
+ Index: 3,
}
d3 := device{
@@ -158,6 +166,7 @@
Type: realDevice,
Qualifiers: []string{"usb:3-3.3", "product:bullhead", "model:Nexus_5X", "device:bullhead"},
Nickname: "SecondPhone",
+ Index: 4,
}
e2 := device{
@@ -165,6 +174,7 @@
Type: emulator,
Qualifiers: []string{"product:sdk_phone_armv7", "model:sdk_phone_armv7", "device:generic"},
Nickname: "",
+ Index: 5,
}
allDevices := []device{d1, d2, e1, d3, e2}
@@ -185,8 +195,10 @@
{deviceFlags{false, true, ""}, []device{e1, e2}}, // Only -e is specified
{deviceFlags{false, false, "device:bullhead"}, []device{d1, d3}}, // Device qualifier
{deviceFlags{false, false, "ARMv7,SecondPhone"}, []device{e1, d3}}, // Nicknames
+ {deviceFlags{false, false, "@2,@4"}, []device{d2, d3}}, // Device Indices
{deviceFlags{true, false, "ARMv7"}, []device{d1, d2, e1, d3}}, // Combinations
{deviceFlags{false, true, "model:Nexus_9"}, []device{d2, e1, e2}}, // Combinations
+ {deviceFlags{false, false, "@1,SecondPhone"}, []device{d1, d3}}, // Combinations
}
for i, testCase := range testCases {
@@ -194,7 +206,12 @@
allEmulatorsFlag = testCase.flags.allEmulators
devicesFlag = testCase.flags.devices
- if got := filterSpecifiedDevices(allDevices); !reflect.DeepEqual(got, testCase.want) {
+ got, err := filterSpecifiedDevices(allDevices)
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+
+ if !reflect.DeepEqual(got, testCase.want) {
t.Fatalf("unmatched results for testCases[%v]: got %v, want %v", i, got, testCase.want)
}
}