Skip to content

Commit

Permalink
feat(resolve): add 'madb resolve' command
Browse files Browse the repository at this point in the history
This command prints out the device serials from the given nicknames or
other device specifiers. This would make it easier to use the device
nicknames defined by madb in other command line tools or in shell
scripts.

Change-Id: I7fcb92e5c017000a9c7bb1fd08895f7fc9aa268d
Closes: #10
  • Loading branch information
YoungSeok Yoon committed Jun 23, 2016
1 parent d9365a3 commit 5110ef4
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 25 deletions.
19 changes: 19 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The madb commands are:
group Manage device groups
install Install your app on all devices
name Manage device nicknames
resolve Resolve device specifiers into device serials
shell Run the provided adb shell command on all devices and emulators
concurrently
start Launch your app on all devices
Expand Down Expand Up @@ -455,6 +456,24 @@ Clears all the currently stored nicknames of device serials.
Usage:
madb name clear-all [flags]
Madb resolve - Resolve device specifiers into device serials
Resolves the provided device specifiers and prints out their device serials,
each in a separate line. This command only displays the unique serials of the
devices that are currently available.
This command can be useful when you want to use the device nicknames and groups
defined by madb in other command line tools. For example, to run a flutter app
on "MyTablet" device, you can use the following command (in Bash):
flutter run --device $(madb resolve MyTablet)
Usage:
madb resolve [flags] <specifier1> [<specifier2> ...]
<specifier> can be anything that is accepted in the '-n' flag (see 'madb help').
It can be a device serial, qualifier, index, nickname, or a device group name.
Madb shell - Run the provided adb shell command on all devices and emulators concurrently
Runs the provided adb shell command on all devices and emulators concurrently.
Expand Down
32 changes: 16 additions & 16 deletions madb.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ var cmdMadb = &cmdline.Command{
cmdMadbGroup,
cmdMadbInstall,
cmdMadbName,
cmdMadbResolve,
cmdMadbShell,
cmdMadbStart,
cmdMadbStop,
Expand Down Expand Up @@ -233,12 +234,13 @@ func getSpecifiedDevices() ([]device, error) {
return nil, err
}

allDevices, err := getDevices(cfg)
devices, err := getDevices(cfg)
if err != nil {
return nil, err
}

filtered, err := filterSpecifiedDevices(allDevices, cfg)
tokens := strings.Split(devicesFlag, ",")
filtered, err := filterSpecifiedDevices(devices, cfg, allDevicesFlag, allEmulatorsFlag, tokens)
if err != nil {
return nil, err
}
Expand All @@ -255,18 +257,22 @@ type deviceSpec struct {
token string
}

func filterSpecifiedDevices(devices []device, cfg *config) ([]device, error) {
func filterSpecifiedDevices(devices []device, cfg *config, allDevices, allEmulators bool, tokens []string) ([]device, error) {
// If the tokens only contains one empty string, treat it as an empty slice.
if len(tokens) == 1 && tokens[0] == "" {
tokens = []string{}
}

// If no device specifier flags are set, run on all devices and emulators.
if noDevicesSpecified() {
if allDevices == false && allEmulators == false && len(tokens) == 0 {
return devices, nil
}

result := make([]device, 0, len(devices))

var specs = []deviceSpec{}
if devicesFlag != "" {
if len(tokens) > 0 {
// Check if the provided specifiers are all valid.
tokens := strings.Split(devicesFlag, ",")
for _, token := range tokens {
if err := isValidDeviceSpecifier(token); err != nil {
return nil, err
Expand All @@ -279,7 +285,7 @@ func filterSpecifiedDevices(devices []device, cfg *config) ([]device, error) {
}

for _, d := range devices {
if shouldIncludeDevice(d, specs) {
if shouldIncludeDevice(d, specs, allDevices, allEmulators) {
result = append(result, d)
}
}
Expand All @@ -304,18 +310,12 @@ func getDeviceSpecsFromTokens(tokens []string, cfg *config) []deviceSpec {
return specs
}

func noDevicesSpecified() bool {
return allDevicesFlag == false &&
allEmulatorsFlag == false &&
devicesFlag == ""
}

func shouldIncludeDevice(d device, specs []deviceSpec) bool {
if allDevicesFlag && d.Type == realDevice {
func shouldIncludeDevice(d device, specs []deviceSpec, allDevices, allEmulators bool) bool {
if allDevices && d.Type == realDevice {
return true
}

if allEmulatorsFlag && d.Type == emulator {
if allEmulators && d.Type == emulator {
return true
}

Expand Down
16 changes: 7 additions & 9 deletions madb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"reflect"
"strings"
"testing"

"v.io/x/lib/gosh"
Expand Down Expand Up @@ -210,7 +211,7 @@ func TestGetSpecifiedDevices(t *testing.T) {
devices string
}

testCases := []struct {
tests := []struct {
flags deviceFlags
want []device
}{
Expand Down Expand Up @@ -240,18 +241,15 @@ func TestGetSpecifiedDevices(t *testing.T) {
},
}

for i, testCase := range testCases {
allDevicesFlag = testCase.flags.allDevices
allEmulatorsFlag = testCase.flags.allEmulators
devicesFlag = testCase.flags.devices

got, err := filterSpecifiedDevices(allDevices, cfg)
for i, test := range tests {
tokens := strings.Split(test.flags.devices, ",")
got, err := filterSpecifiedDevices(allDevices, cfg, test.flags.allDevices, test.flags.allEmulators, tokens)
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)
if !reflect.DeepEqual(got, test.want) {
t.Fatalf("unmatched results for testCases[%v]: got %v, want %v", i, got, test.want)
}
}
}
Expand Down
57 changes: 57 additions & 0 deletions resolve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"fmt"

"v.io/x/lib/cmdline"
)

var cmdMadbResolve = &cmdline.Command{
Runner: subCommandRunnerWithFilepath{runMadbResolve, getDefaultConfigFilePath},
Name: "resolve",
DontInheritFlags: true,
Short: "Resolve device specifiers into device serials",
Long: `
Resolves the provided device specifiers and prints out their device serials,
each in a separate line. This command only displays the unique serials of the
devices that are currently available.
This command can be useful when you want to use the device nicknames and groups
defined by madb in other command line tools. For example, to run a flutter app
on "MyTablet" device, you can use the following command (in Bash):
flutter run --device $(madb resolve MyTablet)
`,
ArgsName: "<specifier1> [<specifier2> ...]",
ArgsLong: `
<specifier> can be anything that is accepted in the '-n' flag (see 'madb help').
It can be a device serial, qualifier, index, nickname, or a device group name.
`,
}

func runMadbResolve(env *cmdline.Env, args []string, filename string) error {
cfg, err := readConfig(filename)
if err != nil {
return err
}

devices, err := getDevices(cfg)
if err != nil {
return err
}

filtered, err := filterSpecifiedDevices(devices, cfg, false, false, args)
if err != nil {
return err
}

for _, d := range filtered {
fmt.Println(d.Serial)
}

return nil
}

0 comments on commit 5110ef4

Please sign in to comment.