1*333d2b36SAndroid Build Coastguard Worker// Copyright 2021 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage main 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "bufio" 19*333d2b36SAndroid Build Coastguard Worker "bytes" 20*333d2b36SAndroid Build Coastguard Worker "encoding/json" 21*333d2b36SAndroid Build Coastguard Worker "flag" 22*333d2b36SAndroid Build Coastguard Worker "fmt" 23*333d2b36SAndroid Build Coastguard Worker "io/ioutil" 24*333d2b36SAndroid Build Coastguard Worker "os" 25*333d2b36SAndroid Build Coastguard Worker "os/exec" 26*333d2b36SAndroid Build Coastguard Worker "path/filepath" 27*333d2b36SAndroid Build Coastguard Worker "sort" 28*333d2b36SAndroid Build Coastguard Worker "strings" 29*333d2b36SAndroid Build Coastguard Worker "text/template" 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 32*333d2b36SAndroid Build Coastguard Worker 33*333d2b36SAndroid Build Coastguard Worker "android/soong/bpfix/bpfix" 34*333d2b36SAndroid Build Coastguard Worker) 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Workertype RewriteNames []RewriteName 37*333d2b36SAndroid Build Coastguard Workertype RewriteName struct { 38*333d2b36SAndroid Build Coastguard Worker prefix string 39*333d2b36SAndroid Build Coastguard Worker repl string 40*333d2b36SAndroid Build Coastguard Worker} 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) String() string { 43*333d2b36SAndroid Build Coastguard Worker return "" 44*333d2b36SAndroid Build Coastguard Worker} 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) Set(v string) error { 47*333d2b36SAndroid Build Coastguard Worker split := strings.SplitN(v, "=", 2) 48*333d2b36SAndroid Build Coastguard Worker if len(split) != 2 { 49*333d2b36SAndroid Build Coastguard Worker return fmt.Errorf("Must be in the form of <prefix>=<replace>") 50*333d2b36SAndroid Build Coastguard Worker } 51*333d2b36SAndroid Build Coastguard Worker *r = append(*r, RewriteName{ 52*333d2b36SAndroid Build Coastguard Worker prefix: split[0], 53*333d2b36SAndroid Build Coastguard Worker repl: split[1], 54*333d2b36SAndroid Build Coastguard Worker }) 55*333d2b36SAndroid Build Coastguard Worker return nil 56*333d2b36SAndroid Build Coastguard Worker} 57*333d2b36SAndroid Build Coastguard Worker 58*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) GoToBp(name string) string { 59*333d2b36SAndroid Build Coastguard Worker ret := name 60*333d2b36SAndroid Build Coastguard Worker for _, r := range *r { 61*333d2b36SAndroid Build Coastguard Worker prefix := r.prefix 62*333d2b36SAndroid Build Coastguard Worker if name == prefix { 63*333d2b36SAndroid Build Coastguard Worker ret = r.repl 64*333d2b36SAndroid Build Coastguard Worker break 65*333d2b36SAndroid Build Coastguard Worker } 66*333d2b36SAndroid Build Coastguard Worker prefix += "/" 67*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(name, prefix) { 68*333d2b36SAndroid Build Coastguard Worker ret = r.repl + "-" + strings.TrimPrefix(name, prefix) 69*333d2b36SAndroid Build Coastguard Worker } 70*333d2b36SAndroid Build Coastguard Worker } 71*333d2b36SAndroid Build Coastguard Worker return strings.ReplaceAll(ret, "/", "-") 72*333d2b36SAndroid Build Coastguard Worker} 73*333d2b36SAndroid Build Coastguard Worker 74*333d2b36SAndroid Build Coastguard Workervar rewriteNames = RewriteNames{} 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Workertype Exclude map[string]bool 77*333d2b36SAndroid Build Coastguard Worker 78*333d2b36SAndroid Build Coastguard Workerfunc (e Exclude) String() string { 79*333d2b36SAndroid Build Coastguard Worker return "" 80*333d2b36SAndroid Build Coastguard Worker} 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Workerfunc (e Exclude) Set(v string) error { 83*333d2b36SAndroid Build Coastguard Worker e[v] = true 84*333d2b36SAndroid Build Coastguard Worker return nil 85*333d2b36SAndroid Build Coastguard Worker} 86*333d2b36SAndroid Build Coastguard Worker 87*333d2b36SAndroid Build Coastguard Workervar excludes = make(Exclude) 88*333d2b36SAndroid Build Coastguard Workervar excludeDeps = make(Exclude) 89*333d2b36SAndroid Build Coastguard Workervar excludeSrcs = make(Exclude) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Workertype StringList []string 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Workerfunc (l *StringList) String() string { 94*333d2b36SAndroid Build Coastguard Worker return strings.Join(*l, " ") 95*333d2b36SAndroid Build Coastguard Worker} 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Workerfunc (l *StringList) Set(v string) error { 98*333d2b36SAndroid Build Coastguard Worker *l = append(*l, strings.Fields(v)...) 99*333d2b36SAndroid Build Coastguard Worker return nil 100*333d2b36SAndroid Build Coastguard Worker} 101*333d2b36SAndroid Build Coastguard Worker 102*333d2b36SAndroid Build Coastguard Workertype GoModule struct { 103*333d2b36SAndroid Build Coastguard Worker Dir string 104*333d2b36SAndroid Build Coastguard Worker} 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Workertype GoPackage struct { 107*333d2b36SAndroid Build Coastguard Worker ExportToAndroid bool 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker Dir string 110*333d2b36SAndroid Build Coastguard Worker ImportPath string 111*333d2b36SAndroid Build Coastguard Worker Name string 112*333d2b36SAndroid Build Coastguard Worker Imports []string 113*333d2b36SAndroid Build Coastguard Worker GoFiles []string 114*333d2b36SAndroid Build Coastguard Worker TestGoFiles []string 115*333d2b36SAndroid Build Coastguard Worker TestImports []string 116*333d2b36SAndroid Build Coastguard Worker 117*333d2b36SAndroid Build Coastguard Worker Module *GoModule 118*333d2b36SAndroid Build Coastguard Worker} 119*333d2b36SAndroid Build Coastguard Worker 120*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) IsCommand() bool { 121*333d2b36SAndroid Build Coastguard Worker return g.Name == "main" 122*333d2b36SAndroid Build Coastguard Worker} 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) BpModuleType() string { 125*333d2b36SAndroid Build Coastguard Worker if g.IsCommand() { 126*333d2b36SAndroid Build Coastguard Worker return "blueprint_go_binary" 127*333d2b36SAndroid Build Coastguard Worker } 128*333d2b36SAndroid Build Coastguard Worker return "bootstrap_go_package" 129*333d2b36SAndroid Build Coastguard Worker} 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) BpName() string { 132*333d2b36SAndroid Build Coastguard Worker if g.IsCommand() { 133*333d2b36SAndroid Build Coastguard Worker return rewriteNames.GoToBp(filepath.Base(g.ImportPath)) 134*333d2b36SAndroid Build Coastguard Worker } 135*333d2b36SAndroid Build Coastguard Worker return rewriteNames.GoToBp(g.ImportPath) 136*333d2b36SAndroid Build Coastguard Worker} 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) BpDeps(deps []string) []string { 139*333d2b36SAndroid Build Coastguard Worker var ret []string 140*333d2b36SAndroid Build Coastguard Worker for _, d := range deps { 141*333d2b36SAndroid Build Coastguard Worker // Ignore stdlib dependencies 142*333d2b36SAndroid Build Coastguard Worker if !strings.Contains(d, ".") { 143*333d2b36SAndroid Build Coastguard Worker continue 144*333d2b36SAndroid Build Coastguard Worker } 145*333d2b36SAndroid Build Coastguard Worker if _, ok := excludeDeps[d]; ok { 146*333d2b36SAndroid Build Coastguard Worker continue 147*333d2b36SAndroid Build Coastguard Worker } 148*333d2b36SAndroid Build Coastguard Worker name := rewriteNames.GoToBp(d) 149*333d2b36SAndroid Build Coastguard Worker ret = append(ret, name) 150*333d2b36SAndroid Build Coastguard Worker } 151*333d2b36SAndroid Build Coastguard Worker return ret 152*333d2b36SAndroid Build Coastguard Worker} 153*333d2b36SAndroid Build Coastguard Worker 154*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) BpSrcs(srcs []string) []string { 155*333d2b36SAndroid Build Coastguard Worker var ret []string 156*333d2b36SAndroid Build Coastguard Worker prefix, err := filepath.Rel(g.Module.Dir, g.Dir) 157*333d2b36SAndroid Build Coastguard Worker if err != nil { 158*333d2b36SAndroid Build Coastguard Worker panic(err) 159*333d2b36SAndroid Build Coastguard Worker } 160*333d2b36SAndroid Build Coastguard Worker for _, f := range srcs { 161*333d2b36SAndroid Build Coastguard Worker f = filepath.Join(prefix, f) 162*333d2b36SAndroid Build Coastguard Worker if _, ok := excludeSrcs[f]; ok { 163*333d2b36SAndroid Build Coastguard Worker continue 164*333d2b36SAndroid Build Coastguard Worker } 165*333d2b36SAndroid Build Coastguard Worker ret = append(ret, f) 166*333d2b36SAndroid Build Coastguard Worker } 167*333d2b36SAndroid Build Coastguard Worker return ret 168*333d2b36SAndroid Build Coastguard Worker} 169*333d2b36SAndroid Build Coastguard Worker 170*333d2b36SAndroid Build Coastguard Worker// AllImports combines Imports and TestImports, as blueprint does not differentiate these. 171*333d2b36SAndroid Build Coastguard Workerfunc (g GoPackage) AllImports() []string { 172*333d2b36SAndroid Build Coastguard Worker imports := append([]string(nil), g.Imports...) 173*333d2b36SAndroid Build Coastguard Worker imports = append(imports, g.TestImports...) 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Worker if len(imports) == 0 { 176*333d2b36SAndroid Build Coastguard Worker return nil 177*333d2b36SAndroid Build Coastguard Worker } 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker // Sort and de-duplicate 180*333d2b36SAndroid Build Coastguard Worker sort.Strings(imports) 181*333d2b36SAndroid Build Coastguard Worker j := 0 182*333d2b36SAndroid Build Coastguard Worker for i := 1; i < len(imports); i++ { 183*333d2b36SAndroid Build Coastguard Worker if imports[i] == imports[j] { 184*333d2b36SAndroid Build Coastguard Worker continue 185*333d2b36SAndroid Build Coastguard Worker } 186*333d2b36SAndroid Build Coastguard Worker j++ 187*333d2b36SAndroid Build Coastguard Worker imports[j] = imports[i] 188*333d2b36SAndroid Build Coastguard Worker } 189*333d2b36SAndroid Build Coastguard Worker return imports[:j+1] 190*333d2b36SAndroid Build Coastguard Worker} 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Workervar bpTemplate = template.Must(template.New("bp").Parse(` 193*333d2b36SAndroid Build Coastguard Worker{{.BpModuleType}} { 194*333d2b36SAndroid Build Coastguard Worker name: "{{.BpName}}", 195*333d2b36SAndroid Build Coastguard Worker {{- if not .IsCommand}} 196*333d2b36SAndroid Build Coastguard Worker pkgPath: "{{.ImportPath}}", 197*333d2b36SAndroid Build Coastguard Worker {{- end}} 198*333d2b36SAndroid Build Coastguard Worker {{- if .BpDeps .AllImports}} 199*333d2b36SAndroid Build Coastguard Worker deps: [ 200*333d2b36SAndroid Build Coastguard Worker {{- range .BpDeps .AllImports}} 201*333d2b36SAndroid Build Coastguard Worker "{{.}}", 202*333d2b36SAndroid Build Coastguard Worker {{- end}} 203*333d2b36SAndroid Build Coastguard Worker ], 204*333d2b36SAndroid Build Coastguard Worker {{- end}} 205*333d2b36SAndroid Build Coastguard Worker {{- if .BpSrcs .GoFiles}} 206*333d2b36SAndroid Build Coastguard Worker srcs: [ 207*333d2b36SAndroid Build Coastguard Worker {{- range .BpSrcs .GoFiles}} 208*333d2b36SAndroid Build Coastguard Worker "{{.}}", 209*333d2b36SAndroid Build Coastguard Worker {{- end}} 210*333d2b36SAndroid Build Coastguard Worker ], 211*333d2b36SAndroid Build Coastguard Worker {{- end}} 212*333d2b36SAndroid Build Coastguard Worker {{- if .BpSrcs .TestGoFiles}} 213*333d2b36SAndroid Build Coastguard Worker testSrcs: [ 214*333d2b36SAndroid Build Coastguard Worker {{- range .BpSrcs .TestGoFiles}} 215*333d2b36SAndroid Build Coastguard Worker "{{.}}", 216*333d2b36SAndroid Build Coastguard Worker {{- end}} 217*333d2b36SAndroid Build Coastguard Worker ], 218*333d2b36SAndroid Build Coastguard Worker {{- end}} 219*333d2b36SAndroid Build Coastguard Worker} 220*333d2b36SAndroid Build Coastguard Worker`)) 221*333d2b36SAndroid Build Coastguard Worker 222*333d2b36SAndroid Build Coastguard Workerfunc rerunForRegen(filename string) error { 223*333d2b36SAndroid Build Coastguard Worker buf, err := ioutil.ReadFile(filename) 224*333d2b36SAndroid Build Coastguard Worker if err != nil { 225*333d2b36SAndroid Build Coastguard Worker return err 226*333d2b36SAndroid Build Coastguard Worker } 227*333d2b36SAndroid Build Coastguard Worker 228*333d2b36SAndroid Build Coastguard Worker scanner := bufio.NewScanner(bytes.NewBuffer(buf)) 229*333d2b36SAndroid Build Coastguard Worker 230*333d2b36SAndroid Build Coastguard Worker // Skip the first line in the file 231*333d2b36SAndroid Build Coastguard Worker for i := 0; i < 2; i++ { 232*333d2b36SAndroid Build Coastguard Worker if !scanner.Scan() { 233*333d2b36SAndroid Build Coastguard Worker if scanner.Err() != nil { 234*333d2b36SAndroid Build Coastguard Worker return scanner.Err() 235*333d2b36SAndroid Build Coastguard Worker } else { 236*333d2b36SAndroid Build Coastguard Worker return fmt.Errorf("unexpected EOF") 237*333d2b36SAndroid Build Coastguard Worker } 238*333d2b36SAndroid Build Coastguard Worker } 239*333d2b36SAndroid Build Coastguard Worker } 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker // Extract the old args from the file 242*333d2b36SAndroid Build Coastguard Worker line := scanner.Text() 243*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(line, "// go2bp ") { 244*333d2b36SAndroid Build Coastguard Worker line = strings.TrimPrefix(line, "// go2bp ") 245*333d2b36SAndroid Build Coastguard Worker } else { 246*333d2b36SAndroid Build Coastguard Worker return fmt.Errorf("unexpected second line: %q", line) 247*333d2b36SAndroid Build Coastguard Worker } 248*333d2b36SAndroid Build Coastguard Worker args := strings.Split(line, " ") 249*333d2b36SAndroid Build Coastguard Worker lastArg := args[len(args)-1] 250*333d2b36SAndroid Build Coastguard Worker args = args[:len(args)-1] 251*333d2b36SAndroid Build Coastguard Worker 252*333d2b36SAndroid Build Coastguard Worker // Append all current command line args except -regen <file> to the ones from the file 253*333d2b36SAndroid Build Coastguard Worker for i := 1; i < len(os.Args); i++ { 254*333d2b36SAndroid Build Coastguard Worker if os.Args[i] == "-regen" || os.Args[i] == "--regen" { 255*333d2b36SAndroid Build Coastguard Worker i++ 256*333d2b36SAndroid Build Coastguard Worker } else { 257*333d2b36SAndroid Build Coastguard Worker args = append(args, os.Args[i]) 258*333d2b36SAndroid Build Coastguard Worker } 259*333d2b36SAndroid Build Coastguard Worker } 260*333d2b36SAndroid Build Coastguard Worker args = append(args, lastArg) 261*333d2b36SAndroid Build Coastguard Worker 262*333d2b36SAndroid Build Coastguard Worker cmd := os.Args[0] + " " + strings.Join(args, " ") 263*333d2b36SAndroid Build Coastguard Worker // Re-exec pom2bp with the new arguments 264*333d2b36SAndroid Build Coastguard Worker output, err := exec.Command("/bin/sh", "-c", cmd).Output() 265*333d2b36SAndroid Build Coastguard Worker if exitErr, _ := err.(*exec.ExitError); exitErr != nil { 266*333d2b36SAndroid Build Coastguard Worker return fmt.Errorf("failed to run %s\n%s", cmd, string(exitErr.Stderr)) 267*333d2b36SAndroid Build Coastguard Worker } else if err != nil { 268*333d2b36SAndroid Build Coastguard Worker return err 269*333d2b36SAndroid Build Coastguard Worker } 270*333d2b36SAndroid Build Coastguard Worker 271*333d2b36SAndroid Build Coastguard Worker return ioutil.WriteFile(filename, output, 0666) 272*333d2b36SAndroid Build Coastguard Worker} 273*333d2b36SAndroid Build Coastguard Worker 274*333d2b36SAndroid Build Coastguard Workerfunc main() { 275*333d2b36SAndroid Build Coastguard Worker flag.Usage = func() { 276*333d2b36SAndroid Build Coastguard Worker fmt.Fprintf(os.Stderr, `go2bp, a tool to create Android.bp files from go modules 277*333d2b36SAndroid Build Coastguard Worker 278*333d2b36SAndroid Build Coastguard WorkerThe tool will extract the necessary information from Go files to create an Android.bp that can 279*333d2b36SAndroid Build Coastguard Workercompile them. This needs to be run from the same directory as the go.mod file. 280*333d2b36SAndroid Build Coastguard Worker 281*333d2b36SAndroid Build Coastguard WorkerUsage: %s [--rewrite <pkg-prefix>=<replace>] [-exclude <package>] [-regen <file>] 282*333d2b36SAndroid Build Coastguard Worker 283*333d2b36SAndroid Build Coastguard Worker -rewrite <pkg-prefix>=<replace> 284*333d2b36SAndroid Build Coastguard Worker rewrite can be used to specify mappings between go package paths and Android.bp modules. The -rewrite 285*333d2b36SAndroid Build Coastguard Worker option can be specified multiple times. When determining the Android.bp module for a given Go 286*333d2b36SAndroid Build Coastguard Worker package, mappings are searched in the order they were specified. The first <pkg-prefix> matching 287*333d2b36SAndroid Build Coastguard Worker either the package directly, or as the prefix '<pkg-prefix>/' will be replaced with <replace>. 288*333d2b36SAndroid Build Coastguard Worker After all replacements are finished, all '/' characters are replaced with '-'. 289*333d2b36SAndroid Build Coastguard Worker -exclude <package> 290*333d2b36SAndroid Build Coastguard Worker Don't put the specified go package in the Android.bp file. 291*333d2b36SAndroid Build Coastguard Worker -exclude-deps <package> 292*333d2b36SAndroid Build Coastguard Worker Don't put the specified go package in the dependency lists. 293*333d2b36SAndroid Build Coastguard Worker -exclude-srcs <module> 294*333d2b36SAndroid Build Coastguard Worker Don't put the specified source files in srcs or testSrcs lists. 295*333d2b36SAndroid Build Coastguard Worker -limit <package> 296*333d2b36SAndroid Build Coastguard Worker If set, limit the output to the specified packages and their dependencies. 297*333d2b36SAndroid Build Coastguard Worker -skip-tests 298*333d2b36SAndroid Build Coastguard Worker If passed, don't write out any test srcs or dependencies to the Android.bp output. 299*333d2b36SAndroid Build Coastguard Worker -regen <file> 300*333d2b36SAndroid Build Coastguard Worker Read arguments from <file> and overwrite it. 301*333d2b36SAndroid Build Coastguard Worker 302*333d2b36SAndroid Build Coastguard Worker`, os.Args[0]) 303*333d2b36SAndroid Build Coastguard Worker } 304*333d2b36SAndroid Build Coastguard Worker 305*333d2b36SAndroid Build Coastguard Worker var regen string 306*333d2b36SAndroid Build Coastguard Worker var skipTests bool 307*333d2b36SAndroid Build Coastguard Worker limit := StringList{} 308*333d2b36SAndroid Build Coastguard Worker 309*333d2b36SAndroid Build Coastguard Worker flag.Var(&excludes, "exclude", "Exclude go package") 310*333d2b36SAndroid Build Coastguard Worker flag.Var(&excludeDeps, "exclude-dep", "Exclude go package from deps") 311*333d2b36SAndroid Build Coastguard Worker flag.Var(&excludeSrcs, "exclude-src", "Exclude go file from source lists") 312*333d2b36SAndroid Build Coastguard Worker flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names") 313*333d2b36SAndroid Build Coastguard Worker flag.Var(&limit, "limit", "If set, only includes the dependencies of the listed packages") 314*333d2b36SAndroid Build Coastguard Worker flag.BoolVar(&skipTests, "skip-tests", false, "Whether to skip test sources") 315*333d2b36SAndroid Build Coastguard Worker flag.StringVar(®en, "regen", "", "Rewrite specified file") 316*333d2b36SAndroid Build Coastguard Worker flag.Parse() 317*333d2b36SAndroid Build Coastguard Worker 318*333d2b36SAndroid Build Coastguard Worker if regen != "" { 319*333d2b36SAndroid Build Coastguard Worker err := rerunForRegen(regen) 320*333d2b36SAndroid Build Coastguard Worker if err != nil { 321*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, err) 322*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 323*333d2b36SAndroid Build Coastguard Worker } 324*333d2b36SAndroid Build Coastguard Worker os.Exit(0) 325*333d2b36SAndroid Build Coastguard Worker } 326*333d2b36SAndroid Build Coastguard Worker 327*333d2b36SAndroid Build Coastguard Worker if flag.NArg() != 0 { 328*333d2b36SAndroid Build Coastguard Worker fmt.Fprintf(os.Stderr, "Unused argument detected: %v\n", flag.Args()) 329*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 330*333d2b36SAndroid Build Coastguard Worker } 331*333d2b36SAndroid Build Coastguard Worker 332*333d2b36SAndroid Build Coastguard Worker if _, err := os.Stat("go.mod"); err != nil { 333*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, "go.mod file not found") 334*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 335*333d2b36SAndroid Build Coastguard Worker } 336*333d2b36SAndroid Build Coastguard Worker 337*333d2b36SAndroid Build Coastguard Worker cmd := exec.Command("go", "list", "-json", "./...") 338*333d2b36SAndroid Build Coastguard Worker var stdoutb, stderrb bytes.Buffer 339*333d2b36SAndroid Build Coastguard Worker cmd.Stdout = &stdoutb 340*333d2b36SAndroid Build Coastguard Worker cmd.Stderr = &stderrb 341*333d2b36SAndroid Build Coastguard Worker if err := cmd.Run(); err != nil { 342*333d2b36SAndroid Build Coastguard Worker fmt.Fprintf(os.Stderr, "Running %q to dump the Go packages failed: %v, stderr:\n%s\n", 343*333d2b36SAndroid Build Coastguard Worker cmd.String(), err, stderrb.Bytes()) 344*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 345*333d2b36SAndroid Build Coastguard Worker } 346*333d2b36SAndroid Build Coastguard Worker decoder := json.NewDecoder(bytes.NewReader(stdoutb.Bytes())) 347*333d2b36SAndroid Build Coastguard Worker 348*333d2b36SAndroid Build Coastguard Worker pkgs := []*GoPackage{} 349*333d2b36SAndroid Build Coastguard Worker pkgMap := map[string]*GoPackage{} 350*333d2b36SAndroid Build Coastguard Worker for decoder.More() { 351*333d2b36SAndroid Build Coastguard Worker pkg := GoPackage{} 352*333d2b36SAndroid Build Coastguard Worker err := decoder.Decode(&pkg) 353*333d2b36SAndroid Build Coastguard Worker if err != nil { 354*333d2b36SAndroid Build Coastguard Worker fmt.Fprintf(os.Stderr, "Failed to parse json: %v\n", err) 355*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 356*333d2b36SAndroid Build Coastguard Worker } 357*333d2b36SAndroid Build Coastguard Worker if len(limit) == 0 { 358*333d2b36SAndroid Build Coastguard Worker pkg.ExportToAndroid = true 359*333d2b36SAndroid Build Coastguard Worker } 360*333d2b36SAndroid Build Coastguard Worker if skipTests { 361*333d2b36SAndroid Build Coastguard Worker pkg.TestGoFiles = nil 362*333d2b36SAndroid Build Coastguard Worker pkg.TestImports = nil 363*333d2b36SAndroid Build Coastguard Worker } 364*333d2b36SAndroid Build Coastguard Worker pkgs = append(pkgs, &pkg) 365*333d2b36SAndroid Build Coastguard Worker pkgMap[pkg.ImportPath] = &pkg 366*333d2b36SAndroid Build Coastguard Worker } 367*333d2b36SAndroid Build Coastguard Worker 368*333d2b36SAndroid Build Coastguard Worker buf := &bytes.Buffer{} 369*333d2b36SAndroid Build Coastguard Worker 370*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(buf, "// Automatically generated with:") 371*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(buf, "// go2bp", strings.Join(proptools.ShellEscapeList(os.Args[1:]), " ")) 372*333d2b36SAndroid Build Coastguard Worker 373*333d2b36SAndroid Build Coastguard Worker var mark func(string) 374*333d2b36SAndroid Build Coastguard Worker mark = func(pkgName string) { 375*333d2b36SAndroid Build Coastguard Worker if excludes[pkgName] { 376*333d2b36SAndroid Build Coastguard Worker return 377*333d2b36SAndroid Build Coastguard Worker } 378*333d2b36SAndroid Build Coastguard Worker if pkg, ok := pkgMap[pkgName]; ok && !pkg.ExportToAndroid { 379*333d2b36SAndroid Build Coastguard Worker pkg.ExportToAndroid = true 380*333d2b36SAndroid Build Coastguard Worker for _, dep := range pkg.AllImports() { 381*333d2b36SAndroid Build Coastguard Worker if !excludeDeps[dep] { 382*333d2b36SAndroid Build Coastguard Worker mark(dep) 383*333d2b36SAndroid Build Coastguard Worker } 384*333d2b36SAndroid Build Coastguard Worker } 385*333d2b36SAndroid Build Coastguard Worker } 386*333d2b36SAndroid Build Coastguard Worker } 387*333d2b36SAndroid Build Coastguard Worker 388*333d2b36SAndroid Build Coastguard Worker for _, pkgName := range limit { 389*333d2b36SAndroid Build Coastguard Worker mark(pkgName) 390*333d2b36SAndroid Build Coastguard Worker } 391*333d2b36SAndroid Build Coastguard Worker 392*333d2b36SAndroid Build Coastguard Worker for _, pkg := range pkgs { 393*333d2b36SAndroid Build Coastguard Worker if !pkg.ExportToAndroid || excludes[pkg.ImportPath] { 394*333d2b36SAndroid Build Coastguard Worker continue 395*333d2b36SAndroid Build Coastguard Worker } 396*333d2b36SAndroid Build Coastguard Worker if len(pkg.BpSrcs(pkg.GoFiles)) == 0 && len(pkg.BpSrcs(pkg.TestGoFiles)) == 0 { 397*333d2b36SAndroid Build Coastguard Worker continue 398*333d2b36SAndroid Build Coastguard Worker } 399*333d2b36SAndroid Build Coastguard Worker err := bpTemplate.Execute(buf, pkg) 400*333d2b36SAndroid Build Coastguard Worker if err != nil { 401*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, "Error writing", pkg.Name, err) 402*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 403*333d2b36SAndroid Build Coastguard Worker } 404*333d2b36SAndroid Build Coastguard Worker } 405*333d2b36SAndroid Build Coastguard Worker 406*333d2b36SAndroid Build Coastguard Worker out, err := bpfix.Reformat(buf.String()) 407*333d2b36SAndroid Build Coastguard Worker if err != nil { 408*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, "Error formatting output", err) 409*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 410*333d2b36SAndroid Build Coastguard Worker } 411*333d2b36SAndroid Build Coastguard Worker 412*333d2b36SAndroid Build Coastguard Worker os.Stdout.WriteString(out) 413*333d2b36SAndroid Build Coastguard Worker} 414