@@ -9,6 +9,7 @@ package main
99import (
1010 "bytes"
1111 "fmt"
12+ "go/build"
1213 "io"
1314 "log"
1415 "os"
@@ -32,33 +33,36 @@ func run(args ...string) string {
3233 return buf .String ()
3334}
3435
36+ const (
37+ // Directory structure on the target device androidtest.bash assumes.
38+ deviceGoroot = "/data/local/tmp/goroot"
39+ deviceGopath = "/data/local/tmp/gopath"
40+ )
41+
3542func main () {
3643 log .SetFlags (0 )
3744 log .SetPrefix ("go_android_exec: " )
3845
39- // Determine thepackage by examining the current working
46+ // Prepare a temporary directory that will be cleaned up at the end.
47+ deviceGotmp := fmt .Sprintf ("/data/local/tmp/%s-%d" ,
48+ filepath .Base (os .Args [1 ]), os .Getpid ())
49+ run ("shell" , "mkdir" , "-p" , deviceGotmp )
50+
51+ // Determine the package by examining the current working
4052 // directory, which will look something like
41- // "$GOROOT/src/mime/multipart". We extract everything
42- // after the $GOROOT to run on the same relative directory
43- // on the target device.
44- //
45- // TODO(crawshaw): Pick useful subdir when we are not
46- // inside a GOROOT, e.g. we are in a GOPATH.
47- cwd , err := os .Getwd ()
48- if err != nil {
49- log .Fatal (err )
53+ // "$GOROOT/src/mime/multipart" or "$GOPATH/src/golang.org/x/mobile".
54+ // We extract everything after the $GOROOT or $GOPATH to run on the
55+ // same relative directory on the target device.
56+ subdir , inGoRoot := subdir ()
57+ deviceCwd := filepath .Join (deviceGoroot , subdir )
58+ if ! inGoRoot {
59+ deviceCwd = filepath .Join (deviceGopath , subdir )
5060 }
51- subdir , err := filepath .Rel (runtime .GOROOT (), cwd )
52- if err != nil {
53- log .Fatal (err )
54- }
55- subdir = filepath .ToSlash (subdir )
5661
5762 // Binary names can conflict.
5863 // E.g. template.test from the {html,text}/template packages.
5964 binName := filepath .Base (os .Args [1 ])
60- deviceGoroot := "/data/local/tmp/goroot"
61- deviceBin := fmt .Sprintf ("%s/%s-%d" , deviceGoroot , binName , os .Getpid ())
65+ deviceBin := fmt .Sprintf ("%s/%s-%d" , deviceGotmp , binName , os .Getpid ())
6266
6367 // The push of the binary happens in parallel with other tests.
6468 // Unfortunately, a simultaneous call to adb shell hold open
@@ -71,19 +75,22 @@ func main() {
7175
7276 // The adb shell command will return an exit code of 0 regardless
7377 // of the command run. E.g.
74- // $ adb shell false
75- // $ echo $?
76- // 0
78+ // $ adb shell false
79+ // $ echo $?
80+ // 0
7781 // https://code.google.com/p/android/issues/detail?id=3254
7882 // So we append the exitcode to the output and parse it from there.
7983 const exitstr = "exitcode="
80- cmd := `export TMPDIR="/data/local/tmp "` +
84+ cmd := `export TMPDIR="` + deviceGotmp + ` "` +
8185 `; export GOROOT="` + deviceGoroot + `"` +
82- `; cd "$GOROOT/` + subdir + `"` +
86+ `; export GOPATH="` + deviceGopath + `"` +
87+ `; cd "` + deviceCwd + `"` +
8388 "; '" + deviceBin + "' " + strings .Join (os .Args [2 :], " " ) +
8489 "; echo -n " + exitstr + "$?"
8590 output := run ("shell" , cmd )
86- run ("shell" , "rm '" + deviceBin + "'" ) // cleanup
91+
92+ run ("shell" , "rm" , "-rf" , deviceGotmp ) // Clean up.
93+
8794 output = output [strings .LastIndex (output , "\n " )+ 1 :]
8895 if ! strings .HasPrefix (output , exitstr ) {
8996 log .Fatalf ("no exit code: %q" , output )
@@ -94,3 +101,32 @@ func main() {
94101 }
95102 os .Exit (code )
96103}
104+
105+ // subdir determines the package based on the current working directory,
106+ // and returns the path to the package source relative to $GOROOT (or $GOPATH).
107+ func subdir () (pkgpath string , underGoRoot bool ) {
108+ cwd , err := os .Getwd ()
109+ if err != nil {
110+ log .Fatal (err )
111+ }
112+ if root := runtime .GOROOT (); strings .HasPrefix (cwd , root ) {
113+ subdir , err := filepath .Rel (root , cwd )
114+ if err != nil {
115+ log .Fatal (err )
116+ }
117+ return subdir , true
118+ }
119+
120+ for _ , p := range filepath .SplitList (build .Default .GOPATH ) {
121+ if ! strings .HasPrefix (cwd , p ) {
122+ continue
123+ }
124+ subdir , err := filepath .Rel (p , cwd )
125+ if err == nil {
126+ return subdir , false
127+ }
128+ }
129+ log .Fatalf ("the current path %q is not in either GOROOT(%q) or GOPATH(%q)" ,
130+ cwd , runtime .GOROOT (), build .Default .GOPATH )
131+ return "" , false
132+ }
0 commit comments