diff --git a/doc.go b/doc.go index 50d0ebb..b8612b2 100644 --- a/doc.go +++ b/doc.go @@ -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 @@ -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] [ ...] + + 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. diff --git a/madb.go b/madb.go index b6560a1..b007e45 100644 --- a/madb.go +++ b/madb.go @@ -88,6 +88,7 @@ var cmdMadb = &cmdline.Command{ cmdMadbGroup, cmdMadbInstall, cmdMadbName, + cmdMadbResolve, cmdMadbShell, cmdMadbStart, cmdMadbStop, @@ -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 } @@ -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 @@ -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) } } @@ -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 } diff --git a/madb_test.go b/madb_test.go index 2444704..f2c5fc9 100644 --- a/madb_test.go +++ b/madb_test.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" "v.io/x/lib/gosh" @@ -210,7 +211,7 @@ func TestGetSpecifiedDevices(t *testing.T) { devices string } - testCases := []struct { + tests := []struct { flags deviceFlags want []device }{ @@ -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) } } } diff --git a/resolve.go b/resolve.go new file mode 100644 index 0000000..8703c9e --- /dev/null +++ b/resolve.go @@ -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: " [ ...]", + ArgsLong: ` + 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 +}