feat(flags): add '-prefix=name,serial,none' flag
The '-prefix' flag allows wsers to control the console output prefix
to a certain extent.
Change-Id: I11c20203d235ff0e4fd756dfabc0d57c9a13fc6c
Closes #11
diff --git a/doc.go b/doc.go
index 972fc06..5b02494 100644
--- a/doc.go
+++ b/doc.go
@@ -39,6 +39,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -96,6 +103,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -143,6 +157,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -204,6 +225,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -302,6 +330,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -385,6 +420,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -439,6 +481,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
@@ -492,6 +541,13 @@
'@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.
+ -prefix=name
+ Specify which output prefix to use. You can choose from the following
+ options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.
-seq=false
Run the command sequentially, instead of running it in parallel.
diff --git a/madb.go b/madb.go
index 9b2fe79..a335899 100644
--- a/madb.go
+++ b/madb.go
@@ -18,6 +18,7 @@
"encoding/json"
"flag"
"fmt"
+ "io"
"os"
"os/exec"
"path"
@@ -37,6 +38,7 @@
allEmulatorsFlag bool
devicesFlag string
sequentialFlag bool
+ prefixFlag string
clearCacheFlag bool
moduleFlag string
@@ -52,6 +54,11 @@
cmdMadb.Flags.BoolVar(&allEmulatorsFlag, "e", false, `Restrict the command to only run on emulators.`)
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.`)
cmdMadb.Flags.BoolVar(&sequentialFlag, "seq", false, `Run the command sequentially, instead of running it in parallel.`)
+ cmdMadb.Flags.StringVar(&prefixFlag, "prefix", "name", `Specify which output prefix to use. You can choose from the following options:
+ name - Display the nickname of the device. The serial number is used instead if the
+ nickname is not set for the given device.
+ serial - Display the serial number of the device.
+ none - Do not display the output prefix.`)
// Store the current working directory.
var err error
@@ -362,6 +369,11 @@
// Invokes the sub command on all the devices in parallel.
func (r subCommandRunner) Run(env *cmdline.Env, args []string) error {
+ prefixFlag = strings.ToLower(prefixFlag)
+ if prefixFlag != "auto" && prefixFlag != "serial" && prefixFlag != "none" {
+ return fmt.Errorf(`The -prefix flag value must be one of "auto", "serial", or "none".`)
+ }
+
if err := startAdbServer(); err != nil {
return err
}
@@ -432,20 +444,29 @@
}
func runGoshCommandForDevice(cmd *gosh.Cmd, d device, printUserID bool) error {
- var prefix string
- if printUserID && d.UserID != "" {
- prefix = "[" + d.displayName() + ":" + d.UserID + "]\t"
- } else {
- prefix = "[" + d.displayName() + "]\t"
+ return runGoshCommandForDeviceWithWriters(cmd, d, printUserID, os.Stdout, os.Stderr)
+}
+
+func runGoshCommandForDeviceWithWriters(cmd *gosh.Cmd, d device, printUserID bool, stdout, stderr io.Writer) error {
+ prefix := ""
+ if prefixFlag != "none" {
+ name := d.Serial
+ if prefixFlag == "name" {
+ name = d.displayName()
+ }
+ if printUserID && d.UserID != "" {
+ name = name + ":" + d.UserID
+ }
+ prefix = "[" + name + "]\t"
}
- stdout := textutil.PrefixLineWriter(os.Stdout, prefix)
- stderr := textutil.PrefixLineWriter(os.Stderr, prefix)
- cmd.AddStdoutWriter(stdout)
- cmd.AddStderrWriter(stderr)
+ prefixedStdout := textutil.PrefixLineWriter(stdout, prefix)
+ prefixedStderr := textutil.PrefixLineWriter(stderr, prefix)
+ cmd.AddStdoutWriter(prefixedStdout)
+ cmd.AddStderrWriter(prefixedStderr)
cmd.Run()
- stdout.Flush()
- stderr.Flush()
+ prefixedStdout.Flush()
+ prefixedStderr.Flush()
return cmd.Shell().Err
}
diff --git a/madb_test.go b/madb_test.go
index 769137c..0ef5843 100644
--- a/madb_test.go
+++ b/madb_test.go
@@ -5,13 +5,22 @@
package main
import (
+ "bytes"
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
+
+ "v.io/x/lib/gosh"
)
+func TestMain(m *testing.M) {
+ gosh.InitMain()
+ os.Exit(m.Run())
+}
+
func tempFilename(t *testing.T) string {
f, err := ioutil.TempFile("", "madb_test")
if err != nil {
@@ -434,3 +443,73 @@
}
}
}
+
+var helloFunc = gosh.RegisterFunc("helloFunc", func() {
+ fmt.Println("Hello, World!")
+})
+
+func TestOutputPrefix(t *testing.T) {
+ // Sample device.
+ d1 := device{
+ Serial: "deviceid01",
+ Type: realDevice,
+ Qualifiers: nil,
+ Nickname: "Alice",
+ Index: 1,
+ UserID: "",
+ }
+
+ d2 := device{
+ Serial: "deviceid02",
+ Type: realDevice,
+ Qualifiers: nil,
+ Nickname: "Bob",
+ Index: 2,
+ UserID: "10",
+ }
+
+ d3 := device{
+ Serial: "deviceid03",
+ Type: realDevice,
+ Qualifiers: nil,
+ Nickname: "",
+ Index: 3,
+ UserID: "",
+ }
+
+ sh := gosh.NewShell(nil)
+ defer sh.Cleanup()
+
+ tests := []struct {
+ prefixType string
+ d device
+ want string
+ }{
+ {"name", d1, "[Alice]\tHello, World!\n"},
+ {"name", d2, "[Bob:10]\tHello, World!\n"},
+ {"name", d3, "[deviceid03]\tHello, World!\n"},
+ {"serial", d1, "[deviceid01]\tHello, World!\n"},
+ {"serial", d2, "[deviceid02:10]\tHello, World!\n"},
+ {"serial", d3, "[deviceid03]\tHello, World!\n"},
+ {"none", d1, "Hello, World!\n"},
+ {"none", d2, "Hello, World!\n"},
+ {"none", d3, "Hello, World!\n"},
+ }
+
+ for i, test := range tests {
+ var b1, b2 bytes.Buffer
+
+ helloCmd := sh.FuncCmd(helloFunc)
+ prefixFlag = test.prefixType
+ if err := runGoshCommandForDeviceWithWriters(helloCmd, test.d, true, &b1, &b2); err != nil {
+ t.Fatalf("error occurred while running gosh command: %v", err)
+ }
+
+ if got, want := b1.String(), test.want; got != want {
+ t.Fatalf("unmatched results for tests[%v]: got %v, want %v", i, got, want)
+ }
+ if b2.String() != "" {
+ t.Fatalf("unexpected output to stderr for tests[%v]: %v", i, b2.String())
+ }
+ }
+}