1// +build ignore 2 3/* 4Copyright 2017 The Perkeep Authors. 5 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17*/ 18 19// This program builds the Perkeep Android application. It is meant to be run 20// within the relevant docker container. 21package main 22 23import ( 24 "bufio" 25 "flag" 26 "fmt" 27 "io/ioutil" 28 "log" 29 "os" 30 "os/exec" 31 "path/filepath" 32 "regexp" 33 "strings" 34) 35 36var flagRelease = flag.Bool("release", false, "Whether to assemble the release build, instead of the debug build.") 37 38// TODO(mpl): not sure if the version in app/build.gradle should have anything 39// to do with the version we want to use here. look into that later. 40const appVersion = "0.7" 41 42var ( 43 camliDir = filepath.Join(os.Getenv("GOPATH"), "src/perkeep.org") 44 projectDir = filepath.Join(os.Getenv("GOPATH"), "src/perkeep.org/clients/android") 45 pkputBin = filepath.Join(projectDir, "app/build/generated/assets/pk-put.arm") 46 assetsDir = filepath.Join(projectDir, "app/src/main/assets") 47) 48 49func main() { 50 flag.Parse() 51 if !inDocker() { 52 fmt.Fprintf(os.Stderr, "Usage error: this program should be run within a docker container\n") 53 os.Exit(2) 54 } 55 buildCamput() 56 writeVersion() 57 buildApp() 58} 59 60func buildApp() { 61 cmd := exec.Command("./gradlew", "assembleDebug") 62 if *flagRelease { 63 cmd = exec.Command("./gradlew", "assembleRelease") 64 } 65 cmd.Stdout = os.Stdout 66 cmd.Stderr = os.Stderr 67 if err := cmd.Run(); err != nil { 68 log.Fatalf("Error building Android app: %v", err) 69 } 70} 71 72func writeVersion() { 73 if err := ioutil.WriteFile(filepath.Join(assetsDir, "pk-put-version.txt"), []byte(version()), 0600); err != nil { 74 log.Fatalf("Error writing app version file: %v", err) 75 } 76} 77 78func buildCamput() { 79 os.Setenv("GOARCH", "arm") 80 os.Setenv("GOARM", "7") 81 cmd := exec.Command("go", "build", "-o", pkputBin, "perkeep.org/cmd/pk-put") 82 cmd.Stdout = os.Stdout 83 cmd.Stderr = os.Stderr 84 if err := cmd.Run(); err != nil { 85 log.Fatalf("Error building pk-put for Android: %v", err) 86 } 87 88 if err := os.Rename(pkputBin, filepath.Join(assetsDir, "pk-put.arm")); err != nil { 89 log.Fatalf("Error moving pk-put to assets dir: %v", err) 90 } 91} 92 93func version() string { 94 return "app " + appVersion + " pk-put " + getVersion() + " " + goVersion() 95} 96 97func goVersion() string { 98 out, err := exec.Command("go", "version").Output() 99 if err != nil { 100 log.Fatalf("Error getting Go version with the 'go' command: %v", err) 101 } 102 return string(out) 103} 104 105// getVersion returns the version of Perkeep. Either from a VERSION file at the root, 106// or from git. 107func getVersion() string { 108 slurp, err := ioutil.ReadFile(filepath.Join(camliDir, "VERSION")) 109 if err == nil { 110 return strings.TrimSpace(string(slurp)) 111 } 112 return gitVersion() 113} 114 115var gitVersionRx = regexp.MustCompile(`\b\d\d\d\d-\d\d-\d\d-[0-9a-f]{10,10}\b`) 116 117// gitVersion returns the git version of the git repo at camRoot as a 118// string of the form "yyyy-mm-dd-xxxxxxx", with an optional trailing 119// '+' if there are any local uncommitted modifications to the tree. 120func gitVersion() string { 121 cmd := exec.Command("git", "rev-list", "--max-count=1", "--pretty=format:'%ad-%h'", 122 "--date=short", "--abbrev=10", "HEAD") 123 cmd.Dir = camliDir 124 out, err := cmd.Output() 125 if err != nil { 126 log.Fatalf("Error running git rev-list in %s: %v", camliDir, err) 127 } 128 v := strings.TrimSpace(string(out)) 129 if m := gitVersionRx.FindStringSubmatch(v); m != nil { 130 v = m[0] 131 } else { 132 panic("Failed to find git version in " + v) 133 } 134 cmd = exec.Command("git", "diff", "--exit-code") 135 cmd.Dir = camliDir 136 if err := cmd.Run(); err != nil { 137 v += "+" 138 } 139 return v 140} 141 142func inDocker() bool { 143 r, err := os.Open("/proc/self/cgroup") 144 if err != nil { 145 log.Fatalf(`can't open "/proc/self/cgroup": %v`, err) 146 } 147 defer r.Close() 148 sc := bufio.NewScanner(r) 149 for sc.Scan() { 150 l := sc.Text() 151 fields := strings.SplitN(l, ":", 3) 152 if len(fields) != 3 { 153 log.Fatal(`unexpected line in "/proc/self/cgroup"`) 154 } 155 if !(strings.HasPrefix(fields[2], "/docker/") || 156 strings.HasPrefix(fields[2], "/system.slice/docker.service")) { 157 return false 158 } 159 } 160 if err := sc.Err(); err != nil { 161 log.Fatal(err) 162 } 163 return true 164} 165