]> Cypherpunks repositories - gostls13.git/commitdiff
misc/android: choose the right subdirectory for bin under GOPATH.
authorHyang-Ah Hana Kim <hakim@google.com>
Thu, 15 Jan 2015 21:47:41 +0000 (16:47 -0500)
committerHyang-Ah Hana Kim <hyangah@gmail.com>
Fri, 16 Jan 2015 22:02:52 +0000 (22:02 +0000)
This change includes the cleanup of temporary files created during
the binary execution as well.

Change-Id: Ic01a0a537d1daafcaa3acda1ec344aff5dcddfc2
Reviewed-on: https://go-review.googlesource.com/2903
Reviewed-by: David Crawshaw <crawshaw@golang.org>
misc/android/README
misc/android/go_android_exec.go

index 5f24fafc7c4d7b0488557ddf50c64ad4ebb1b350..7b17d879e864df5b02123b207e9d26001ab832d1 100644 (file)
@@ -2,9 +2,9 @@ Android
 =======
 
 For details on developing Go for Android, see the documentation in the
-go.mobile subrepository:
+mobile subrepository:
 
-       https://code.google.com/p/go/source/browse/README?repo=mobile
+       https://github.com/golang/mobile
 
 To run the standard library tests, see androidtest.bash. Run it as
 
index e32a805a8ca798b42c9023485a71488f96cdcee7..a67e990c349890eb4b127a65bc91fb48b961c1f9 100644 (file)
@@ -9,6 +9,7 @@ package main
 import (
        "bytes"
        "fmt"
+       "go/build"
        "io"
        "log"
        "os"
@@ -32,33 +33,36 @@ func run(args ...string) string {
        return buf.String()
 }
 
+const (
+       // Directory structure on the target device androidtest.bash assumes.
+       deviceGoroot = "/data/local/tmp/goroot"
+       deviceGopath = "/data/local/tmp/gopath"
+)
+
 func main() {
        log.SetFlags(0)
        log.SetPrefix("go_android_exec: ")
 
-       // Determine thepackage by examining the current working
+       // Prepare a temporary directory that will be cleaned up at the end.
+       deviceGotmp := fmt.Sprintf("/data/local/tmp/%s-%d",
+               filepath.Base(os.Args[1]), os.Getpid())
+       run("shell", "mkdir", "-p", deviceGotmp)
+
+       // Determine the package by examining the current working
        // directory, which will look something like
-       // "$GOROOT/src/mime/multipart". We extract everything
-       // after the $GOROOT to run on the same relative directory
-       // on the target device.
-       //
-       // TODO(crawshaw): Pick useful subdir when we are not
-       // inside a GOROOT, e.g. we are in a GOPATH.
-       cwd, err := os.Getwd()
-       if err != nil {
-               log.Fatal(err)
+       // "$GOROOT/src/mime/multipart" or "$GOPATH/src/golang.org/x/mobile".
+       // We extract everything after the $GOROOT or $GOPATH to run on the
+       // same relative directory on the target device.
+       subdir, inGoRoot := subdir()
+       deviceCwd := filepath.Join(deviceGoroot, subdir)
+       if !inGoRoot {
+               deviceCwd = filepath.Join(deviceGopath, subdir)
        }
-       subdir, err := filepath.Rel(runtime.GOROOT(), cwd)
-       if err != nil {
-               log.Fatal(err)
-       }
-       subdir = filepath.ToSlash(subdir)
 
        // Binary names can conflict.
        // E.g. template.test from the {html,text}/template packages.
        binName := filepath.Base(os.Args[1])
-       deviceGoroot := "/data/local/tmp/goroot"
-       deviceBin := fmt.Sprintf("%s/%s-%d", deviceGoroot, binName, os.Getpid())
+       deviceBin := fmt.Sprintf("%s/%s-%d", deviceGotmp, binName, os.Getpid())
 
        // The push of the binary happens in parallel with other tests.
        // Unfortunately, a simultaneous call to adb shell hold open
@@ -71,19 +75,22 @@ func main() {
 
        // The adb shell command will return an exit code of 0 regardless
        // of the command run. E.g.
-       //      $ adb shell false
-       //      $ echo $?
-       //      0
+       //      $ adb shell false
+       //      $ echo $?
+       //      0
        // https://code.google.com/p/android/issues/detail?id=3254
        // So we append the exitcode to the output and parse it from there.
        const exitstr = "exitcode="
-       cmd := `export TMPDIR="/data/local/tmp"` +
+       cmd := `export TMPDIR="` + deviceGotmp + `"` +
                `; export GOROOT="` + deviceGoroot + `"` +
-               `; cd "$GOROOT/` + subdir + `"` +
+               `; export GOPATH="` + deviceGopath + `"` +
+               `; cd "` + deviceCwd + `"` +
                "; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
                "; echo -n " + exitstr + "$?"
        output := run("shell", cmd)
-       run("shell", "rm '"+deviceBin+"'") // cleanup
+
+       run("shell", "rm", "-rf", deviceGotmp) // Clean up.
+
        output = output[strings.LastIndex(output, "\n")+1:]
        if !strings.HasPrefix(output, exitstr) {
                log.Fatalf("no exit code: %q", output)
@@ -94,3 +101,32 @@ func main() {
        }
        os.Exit(code)
 }
+
+// subdir determines the package based on the current working directory,
+// and returns the path to the package source relative to $GOROOT (or $GOPATH).
+func subdir() (pkgpath string, underGoRoot bool) {
+       cwd, err := os.Getwd()
+       if err != nil {
+               log.Fatal(err)
+       }
+       if root := runtime.GOROOT(); strings.HasPrefix(cwd, root) {
+               subdir, err := filepath.Rel(root, cwd)
+               if err != nil {
+                       log.Fatal(err)
+               }
+               return subdir, true
+       }
+
+       for _, p := range filepath.SplitList(build.Default.GOPATH) {
+               if !strings.HasPrefix(cwd, p) {
+                       continue
+               }
+               subdir, err := filepath.Rel(p, cwd)
+               if err == nil {
+                       return subdir, false
+               }
+       }
+       log.Fatalf("the current path %q is not in either GOROOT(%q) or GOPATH(%q)",
+               cwd, runtime.GOROOT(), build.Default.GOPATH)
+       return "", false
+}