xref: /aosp_15_r20/build/soong/cmd/pom2bp/pom2bp.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 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	"archive/zip"
19*333d2b36SAndroid Build Coastguard Worker	"bufio"
20*333d2b36SAndroid Build Coastguard Worker	"bytes"
21*333d2b36SAndroid Build Coastguard Worker	"encoding/xml"
22*333d2b36SAndroid Build Coastguard Worker	"flag"
23*333d2b36SAndroid Build Coastguard Worker	"fmt"
24*333d2b36SAndroid Build Coastguard Worker	"io/ioutil"
25*333d2b36SAndroid Build Coastguard Worker	"os"
26*333d2b36SAndroid Build Coastguard Worker	"os/exec"
27*333d2b36SAndroid Build Coastguard Worker	"path"
28*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
29*333d2b36SAndroid Build Coastguard Worker	"regexp"
30*333d2b36SAndroid Build Coastguard Worker	"sort"
31*333d2b36SAndroid Build Coastguard Worker	"strings"
32*333d2b36SAndroid Build Coastguard Worker	"text/template"
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Worker	"android/soong/bpfix/bpfix"
37*333d2b36SAndroid Build Coastguard Worker)
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Workertype RewriteNames []RewriteName
40*333d2b36SAndroid Build Coastguard Workertype RewriteName struct {
41*333d2b36SAndroid Build Coastguard Worker	regexp *regexp.Regexp
42*333d2b36SAndroid Build Coastguard Worker	repl   string
43*333d2b36SAndroid Build Coastguard Worker}
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) String() string {
46*333d2b36SAndroid Build Coastguard Worker	return ""
47*333d2b36SAndroid Build Coastguard Worker}
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) Set(v string) error {
50*333d2b36SAndroid Build Coastguard Worker	split := strings.SplitN(v, "=", 2)
51*333d2b36SAndroid Build Coastguard Worker	if len(split) != 2 {
52*333d2b36SAndroid Build Coastguard Worker		return fmt.Errorf("Must be in the form of <regex>=<replace>")
53*333d2b36SAndroid Build Coastguard Worker	}
54*333d2b36SAndroid Build Coastguard Worker	regex, err := regexp.Compile(split[0])
55*333d2b36SAndroid Build Coastguard Worker	if err != nil {
56*333d2b36SAndroid Build Coastguard Worker		return nil
57*333d2b36SAndroid Build Coastguard Worker	}
58*333d2b36SAndroid Build Coastguard Worker	*r = append(*r, RewriteName{
59*333d2b36SAndroid Build Coastguard Worker		regexp: regex,
60*333d2b36SAndroid Build Coastguard Worker		repl:   split[1],
61*333d2b36SAndroid Build Coastguard Worker	})
62*333d2b36SAndroid Build Coastguard Worker	return nil
63*333d2b36SAndroid Build Coastguard Worker}
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Workerfunc (r *RewriteNames) MavenToBp(groupId string, artifactId string) string {
66*333d2b36SAndroid Build Coastguard Worker	for _, r := range *r {
67*333d2b36SAndroid Build Coastguard Worker		if r.regexp.MatchString(groupId + ":" + artifactId) {
68*333d2b36SAndroid Build Coastguard Worker			return r.regexp.ReplaceAllString(groupId+":"+artifactId, r.repl)
69*333d2b36SAndroid Build Coastguard Worker		} else if r.regexp.MatchString(artifactId) {
70*333d2b36SAndroid Build Coastguard Worker			return r.regexp.ReplaceAllString(artifactId, r.repl)
71*333d2b36SAndroid Build Coastguard Worker		}
72*333d2b36SAndroid Build Coastguard Worker	}
73*333d2b36SAndroid Build Coastguard Worker	return artifactId
74*333d2b36SAndroid Build Coastguard Worker}
75*333d2b36SAndroid Build Coastguard Worker
76*333d2b36SAndroid Build Coastguard Workervar rewriteNames = RewriteNames{}
77*333d2b36SAndroid Build Coastguard Worker
78*333d2b36SAndroid Build Coastguard Workertype ExtraDeps map[string][]string
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Workerfunc (d ExtraDeps) String() string {
81*333d2b36SAndroid Build Coastguard Worker	return ""
82*333d2b36SAndroid Build Coastguard Worker}
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Workerfunc (d ExtraDeps) Set(v string) error {
85*333d2b36SAndroid Build Coastguard Worker	split := strings.SplitN(v, "=", 2)
86*333d2b36SAndroid Build Coastguard Worker	if len(split) != 2 {
87*333d2b36SAndroid Build Coastguard Worker		return fmt.Errorf("Must be in the form of <module>=<module>[,<module>]")
88*333d2b36SAndroid Build Coastguard Worker	}
89*333d2b36SAndroid Build Coastguard Worker	d[split[0]] = strings.Split(split[1], ",")
90*333d2b36SAndroid Build Coastguard Worker	return nil
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workervar extraStaticLibs = make(ExtraDeps)
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Workervar extraLibs = make(ExtraDeps)
96*333d2b36SAndroid Build Coastguard Worker
97*333d2b36SAndroid Build Coastguard Workervar optionalUsesLibs = make(ExtraDeps)
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Workertype Exclude map[string]bool
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Workerfunc (e Exclude) String() string {
102*333d2b36SAndroid Build Coastguard Worker	return ""
103*333d2b36SAndroid Build Coastguard Worker}
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Workerfunc (e Exclude) Set(v string) error {
106*333d2b36SAndroid Build Coastguard Worker	e[v] = true
107*333d2b36SAndroid Build Coastguard Worker	return nil
108*333d2b36SAndroid Build Coastguard Worker}
109*333d2b36SAndroid Build Coastguard Worker
110*333d2b36SAndroid Build Coastguard Workervar excludes = make(Exclude)
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Workertype HostModuleNames map[string]bool
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Workerfunc (n HostModuleNames) IsHostModule(groupId string, artifactId string) bool {
115*333d2b36SAndroid Build Coastguard Worker	_, found := n[groupId+":"+artifactId]
116*333d2b36SAndroid Build Coastguard Worker	return found
117*333d2b36SAndroid Build Coastguard Worker}
118*333d2b36SAndroid Build Coastguard Worker
119*333d2b36SAndroid Build Coastguard Workerfunc (n HostModuleNames) String() string {
120*333d2b36SAndroid Build Coastguard Worker	return ""
121*333d2b36SAndroid Build Coastguard Worker}
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Workerfunc (n HostModuleNames) Set(v string) error {
124*333d2b36SAndroid Build Coastguard Worker	n[v] = true
125*333d2b36SAndroid Build Coastguard Worker	return nil
126*333d2b36SAndroid Build Coastguard Worker}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Workervar hostModuleNames = HostModuleNames{}
129*333d2b36SAndroid Build Coastguard Worker
130*333d2b36SAndroid Build Coastguard Workertype HostAndDeviceModuleNames map[string]bool
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Workerfunc (n HostAndDeviceModuleNames) IsHostAndDeviceModule(groupId string, artifactId string) bool {
133*333d2b36SAndroid Build Coastguard Worker	_, found := n[groupId+":"+artifactId]
134*333d2b36SAndroid Build Coastguard Worker
135*333d2b36SAndroid Build Coastguard Worker	return found
136*333d2b36SAndroid Build Coastguard Worker}
137*333d2b36SAndroid Build Coastguard Worker
138*333d2b36SAndroid Build Coastguard Workerfunc (n HostAndDeviceModuleNames) String() string {
139*333d2b36SAndroid Build Coastguard Worker	return ""
140*333d2b36SAndroid Build Coastguard Worker}
141*333d2b36SAndroid Build Coastguard Worker
142*333d2b36SAndroid Build Coastguard Workerfunc (n HostAndDeviceModuleNames) Set(v string) error {
143*333d2b36SAndroid Build Coastguard Worker	n[v] = true
144*333d2b36SAndroid Build Coastguard Worker	return nil
145*333d2b36SAndroid Build Coastguard Worker}
146*333d2b36SAndroid Build Coastguard Worker
147*333d2b36SAndroid Build Coastguard Workervar hostAndDeviceModuleNames = HostAndDeviceModuleNames{}
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Workervar sdkVersion string
150*333d2b36SAndroid Build Coastguard Workervar defaultMinSdkVersion string
151*333d2b36SAndroid Build Coastguard Workervar useVersion string
152*333d2b36SAndroid Build Coastguard Workervar staticDeps bool
153*333d2b36SAndroid Build Coastguard Workervar writeCmd bool
154*333d2b36SAndroid Build Coastguard Workervar jetifier bool
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Workerfunc InList(s string, list []string) bool {
157*333d2b36SAndroid Build Coastguard Worker	for _, l := range list {
158*333d2b36SAndroid Build Coastguard Worker		if l == s {
159*333d2b36SAndroid Build Coastguard Worker			return true
160*333d2b36SAndroid Build Coastguard Worker		}
161*333d2b36SAndroid Build Coastguard Worker	}
162*333d2b36SAndroid Build Coastguard Worker
163*333d2b36SAndroid Build Coastguard Worker	return false
164*333d2b36SAndroid Build Coastguard Worker}
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Workertype Dependency struct {
167*333d2b36SAndroid Build Coastguard Worker	XMLName xml.Name `xml:"dependency"`
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker	BpTarget    string `xml:"-"`
170*333d2b36SAndroid Build Coastguard Worker	BazelTarget string `xml:"-"`
171*333d2b36SAndroid Build Coastguard Worker
172*333d2b36SAndroid Build Coastguard Worker	GroupId    string `xml:"groupId"`
173*333d2b36SAndroid Build Coastguard Worker	ArtifactId string `xml:"artifactId"`
174*333d2b36SAndroid Build Coastguard Worker	Version    string `xml:"version"`
175*333d2b36SAndroid Build Coastguard Worker	Type       string `xml:"type"`
176*333d2b36SAndroid Build Coastguard Worker	Scope      string `xml:"scope"`
177*333d2b36SAndroid Build Coastguard Worker}
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Workerfunc (d Dependency) BpName() string {
180*333d2b36SAndroid Build Coastguard Worker	if d.BpTarget == "" {
181*333d2b36SAndroid Build Coastguard Worker		d.BpTarget = rewriteNames.MavenToBp(d.GroupId, d.ArtifactId)
182*333d2b36SAndroid Build Coastguard Worker	}
183*333d2b36SAndroid Build Coastguard Worker	return d.BpTarget
184*333d2b36SAndroid Build Coastguard Worker}
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Workertype Pom struct {
187*333d2b36SAndroid Build Coastguard Worker	XMLName xml.Name `xml:"http://maven.apache.org/POM/4.0.0 project"`
188*333d2b36SAndroid Build Coastguard Worker
189*333d2b36SAndroid Build Coastguard Worker	PomFile       string `xml:"-"`
190*333d2b36SAndroid Build Coastguard Worker	ArtifactFile  string `xml:"-"`
191*333d2b36SAndroid Build Coastguard Worker	BpTarget      string `xml:"-"`
192*333d2b36SAndroid Build Coastguard Worker	MinSdkVersion string `xml:"-"`
193*333d2b36SAndroid Build Coastguard Worker
194*333d2b36SAndroid Build Coastguard Worker	GroupId    string `xml:"groupId"`
195*333d2b36SAndroid Build Coastguard Worker	ArtifactId string `xml:"artifactId"`
196*333d2b36SAndroid Build Coastguard Worker	Version    string `xml:"version"`
197*333d2b36SAndroid Build Coastguard Worker	Packaging  string `xml:"packaging"`
198*333d2b36SAndroid Build Coastguard Worker
199*333d2b36SAndroid Build Coastguard Worker	Dependencies []*Dependency `xml:"dependencies>dependency"`
200*333d2b36SAndroid Build Coastguard Worker}
201*333d2b36SAndroid Build Coastguard Worker
202*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsAar() bool {
203*333d2b36SAndroid Build Coastguard Worker	return p.Packaging == "aar"
204*333d2b36SAndroid Build Coastguard Worker}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsJar() bool {
207*333d2b36SAndroid Build Coastguard Worker	return p.Packaging == "jar"
208*333d2b36SAndroid Build Coastguard Worker}
209*333d2b36SAndroid Build Coastguard Worker
210*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsApk() bool {
211*333d2b36SAndroid Build Coastguard Worker	return p.Packaging == "apk"
212*333d2b36SAndroid Build Coastguard Worker}
213*333d2b36SAndroid Build Coastguard Worker
214*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsHostModule() bool {
215*333d2b36SAndroid Build Coastguard Worker	return hostModuleNames.IsHostModule(p.GroupId, p.ArtifactId)
216*333d2b36SAndroid Build Coastguard Worker}
217*333d2b36SAndroid Build Coastguard Worker
218*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsDeviceModule() bool {
219*333d2b36SAndroid Build Coastguard Worker	return !p.IsHostModule()
220*333d2b36SAndroid Build Coastguard Worker}
221*333d2b36SAndroid Build Coastguard Worker
222*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsHostAndDeviceModule() bool {
223*333d2b36SAndroid Build Coastguard Worker	return hostAndDeviceModuleNames.IsHostAndDeviceModule(p.GroupId, p.ArtifactId)
224*333d2b36SAndroid Build Coastguard Worker}
225*333d2b36SAndroid Build Coastguard Worker
226*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) IsHostOnly() bool {
227*333d2b36SAndroid Build Coastguard Worker	return p.IsHostModule() && !p.IsHostAndDeviceModule()
228*333d2b36SAndroid Build Coastguard Worker}
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) ModuleType() string {
231*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
232*333d2b36SAndroid Build Coastguard Worker		return "android_library"
233*333d2b36SAndroid Build Coastguard Worker	} else if p.IsHostOnly() {
234*333d2b36SAndroid Build Coastguard Worker		return "java_library_host"
235*333d2b36SAndroid Build Coastguard Worker	} else {
236*333d2b36SAndroid Build Coastguard Worker		return "java_library_static"
237*333d2b36SAndroid Build Coastguard Worker	}
238*333d2b36SAndroid Build Coastguard Worker}
239*333d2b36SAndroid Build Coastguard Worker
240*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelTargetType() string {
241*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
242*333d2b36SAndroid Build Coastguard Worker		return "android_library"
243*333d2b36SAndroid Build Coastguard Worker	} else {
244*333d2b36SAndroid Build Coastguard Worker		return "java_library"
245*333d2b36SAndroid Build Coastguard Worker	}
246*333d2b36SAndroid Build Coastguard Worker}
247*333d2b36SAndroid Build Coastguard Worker
248*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) ImportModuleType() string {
249*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
250*333d2b36SAndroid Build Coastguard Worker		return "android_library_import"
251*333d2b36SAndroid Build Coastguard Worker	} else if p.IsApk() {
252*333d2b36SAndroid Build Coastguard Worker		return "android_app_import"
253*333d2b36SAndroid Build Coastguard Worker	} else if p.IsHostOnly() {
254*333d2b36SAndroid Build Coastguard Worker		return "java_import_host"
255*333d2b36SAndroid Build Coastguard Worker	} else {
256*333d2b36SAndroid Build Coastguard Worker		return "java_import"
257*333d2b36SAndroid Build Coastguard Worker	}
258*333d2b36SAndroid Build Coastguard Worker}
259*333d2b36SAndroid Build Coastguard Worker
260*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelImportTargetType() string {
261*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
262*333d2b36SAndroid Build Coastguard Worker		return "aar_import"
263*333d2b36SAndroid Build Coastguard Worker	} else if p.IsApk() {
264*333d2b36SAndroid Build Coastguard Worker		return "apk_import"
265*333d2b36SAndroid Build Coastguard Worker	} else {
266*333d2b36SAndroid Build Coastguard Worker		return "java_import"
267*333d2b36SAndroid Build Coastguard Worker	}
268*333d2b36SAndroid Build Coastguard Worker}
269*333d2b36SAndroid Build Coastguard Worker
270*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) ImportProperty() string {
271*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
272*333d2b36SAndroid Build Coastguard Worker		return "aars"
273*333d2b36SAndroid Build Coastguard Worker	} else if p.IsApk() {
274*333d2b36SAndroid Build Coastguard Worker		return "apk"
275*333d2b36SAndroid Build Coastguard Worker	} else {
276*333d2b36SAndroid Build Coastguard Worker		return "jars"
277*333d2b36SAndroid Build Coastguard Worker	}
278*333d2b36SAndroid Build Coastguard Worker}
279*333d2b36SAndroid Build Coastguard Worker
280*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelImportProperty() string {
281*333d2b36SAndroid Build Coastguard Worker	if p.IsAar() {
282*333d2b36SAndroid Build Coastguard Worker		return "aar"
283*333d2b36SAndroid Build Coastguard Worker	} else if p.IsApk() {
284*333d2b36SAndroid Build Coastguard Worker		return "apk"
285*333d2b36SAndroid Build Coastguard Worker	} else {
286*333d2b36SAndroid Build Coastguard Worker		return "jars"
287*333d2b36SAndroid Build Coastguard Worker	}
288*333d2b36SAndroid Build Coastguard Worker}
289*333d2b36SAndroid Build Coastguard Worker
290*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpName() string {
291*333d2b36SAndroid Build Coastguard Worker	if p.BpTarget == "" {
292*333d2b36SAndroid Build Coastguard Worker		p.BpTarget = rewriteNames.MavenToBp(p.GroupId, p.ArtifactId)
293*333d2b36SAndroid Build Coastguard Worker	}
294*333d2b36SAndroid Build Coastguard Worker	return p.BpTarget
295*333d2b36SAndroid Build Coastguard Worker}
296*333d2b36SAndroid Build Coastguard Worker
297*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpJarDeps() []string {
298*333d2b36SAndroid Build Coastguard Worker	return p.BpDeps("jar", []string{"compile", "runtime"})
299*333d2b36SAndroid Build Coastguard Worker}
300*333d2b36SAndroid Build Coastguard Worker
301*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpAarDeps() []string {
302*333d2b36SAndroid Build Coastguard Worker	return p.BpDeps("aar", []string{"compile", "runtime"})
303*333d2b36SAndroid Build Coastguard Worker}
304*333d2b36SAndroid Build Coastguard Worker
305*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelJarDeps() []string {
306*333d2b36SAndroid Build Coastguard Worker	return p.BazelDeps("jar", []string{"compile", "runtime"})
307*333d2b36SAndroid Build Coastguard Worker}
308*333d2b36SAndroid Build Coastguard Worker
309*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelAarDeps() []string {
310*333d2b36SAndroid Build Coastguard Worker	return p.BazelDeps("aar", []string{"compile", "runtime"})
311*333d2b36SAndroid Build Coastguard Worker}
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpExtraStaticLibs() []string {
314*333d2b36SAndroid Build Coastguard Worker	return extraStaticLibs[p.BpName()]
315*333d2b36SAndroid Build Coastguard Worker}
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpExtraLibs() []string {
318*333d2b36SAndroid Build Coastguard Worker	return extraLibs[p.BpName()]
319*333d2b36SAndroid Build Coastguard Worker}
320*333d2b36SAndroid Build Coastguard Worker
321*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpOptionalUsesLibs() []string {
322*333d2b36SAndroid Build Coastguard Worker	return optionalUsesLibs[p.BpName()]
323*333d2b36SAndroid Build Coastguard Worker}
324*333d2b36SAndroid Build Coastguard Worker
325*333d2b36SAndroid Build Coastguard Worker// BpDeps obtains dependencies filtered by type and scope. The results of this
326*333d2b36SAndroid Build Coastguard Worker// method are formatted as Android.bp targets, e.g. run through MavenToBp rules.
327*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BpDeps(typeExt string, scopes []string) []string {
328*333d2b36SAndroid Build Coastguard Worker	var ret []string
329*333d2b36SAndroid Build Coastguard Worker	for _, d := range p.Dependencies {
330*333d2b36SAndroid Build Coastguard Worker		if d.Type != typeExt || !InList(d.Scope, scopes) {
331*333d2b36SAndroid Build Coastguard Worker			continue
332*333d2b36SAndroid Build Coastguard Worker		}
333*333d2b36SAndroid Build Coastguard Worker		name := rewriteNames.MavenToBp(d.GroupId, d.ArtifactId)
334*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, name)
335*333d2b36SAndroid Build Coastguard Worker	}
336*333d2b36SAndroid Build Coastguard Worker	return ret
337*333d2b36SAndroid Build Coastguard Worker}
338*333d2b36SAndroid Build Coastguard Worker
339*333d2b36SAndroid Build Coastguard Worker// BazelDeps obtains dependencies filtered by type and scope. The results of this
340*333d2b36SAndroid Build Coastguard Worker// method are formatted as Bazel BUILD targets.
341*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) BazelDeps(typeExt string, scopes []string) []string {
342*333d2b36SAndroid Build Coastguard Worker	var ret []string
343*333d2b36SAndroid Build Coastguard Worker	for _, d := range p.Dependencies {
344*333d2b36SAndroid Build Coastguard Worker		if d.Type != typeExt || !InList(d.Scope, scopes) {
345*333d2b36SAndroid Build Coastguard Worker			continue
346*333d2b36SAndroid Build Coastguard Worker		}
347*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, d.BazelTarget)
348*333d2b36SAndroid Build Coastguard Worker	}
349*333d2b36SAndroid Build Coastguard Worker	return ret
350*333d2b36SAndroid Build Coastguard Worker}
351*333d2b36SAndroid Build Coastguard Worker
352*333d2b36SAndroid Build Coastguard Workerfunc PathModVars() (string, string, string) {
353*333d2b36SAndroid Build Coastguard Worker	cmd := "/bin/bash"
354*333d2b36SAndroid Build Coastguard Worker	androidTop := os.Getenv("ANDROID_BUILD_TOP")
355*333d2b36SAndroid Build Coastguard Worker	envSetupSh := path.Join(androidTop, "build/envsetup.sh")
356*333d2b36SAndroid Build Coastguard Worker	return cmd, androidTop, envSetupSh
357*333d2b36SAndroid Build Coastguard Worker}
358*333d2b36SAndroid Build Coastguard Worker
359*333d2b36SAndroid Build Coastguard Workerfunc InitRefreshMod(poms []*Pom) error {
360*333d2b36SAndroid Build Coastguard Worker	cmd, _, envSetupSh := PathModVars()
361*333d2b36SAndroid Build Coastguard Worker	// refreshmod is expensive, so if pathmod is already working we can skip it.
362*333d2b36SAndroid Build Coastguard Worker	_, err := exec.Command(cmd, "-c", ". "+envSetupSh+" && pathmod "+poms[0].BpName()).Output()
363*333d2b36SAndroid Build Coastguard Worker	if exitErr, _ := err.(*exec.ExitError); exitErr != nil || err != nil {
364*333d2b36SAndroid Build Coastguard Worker		_, err := exec.Command(cmd, "-c", ". "+envSetupSh+" && refreshmod").Output()
365*333d2b36SAndroid Build Coastguard Worker		if exitErr, _ := err.(*exec.ExitError); exitErr != nil {
366*333d2b36SAndroid Build Coastguard Worker			return fmt.Errorf("failed to run %s\n%s\ntry running lunch.", cmd, string(exitErr.Stderr))
367*333d2b36SAndroid Build Coastguard Worker		} else if err != nil {
368*333d2b36SAndroid Build Coastguard Worker			return err
369*333d2b36SAndroid Build Coastguard Worker		}
370*333d2b36SAndroid Build Coastguard Worker	}
371*333d2b36SAndroid Build Coastguard Worker	return nil
372*333d2b36SAndroid Build Coastguard Worker}
373*333d2b36SAndroid Build Coastguard Worker
374*333d2b36SAndroid Build Coastguard Workerfunc BazelifyExtraDeps(extraDeps ExtraDeps, modules map[string]*Pom) error {
375*333d2b36SAndroid Build Coastguard Worker	for _, deps := range extraDeps {
376*333d2b36SAndroid Build Coastguard Worker		for _, dep := range deps {
377*333d2b36SAndroid Build Coastguard Worker			bazelName, err := BpNameToBazelTarget(dep, modules)
378*333d2b36SAndroid Build Coastguard Worker			if err != nil {
379*333d2b36SAndroid Build Coastguard Worker				return err
380*333d2b36SAndroid Build Coastguard Worker			}
381*333d2b36SAndroid Build Coastguard Worker			dep = bazelName
382*333d2b36SAndroid Build Coastguard Worker		}
383*333d2b36SAndroid Build Coastguard Worker
384*333d2b36SAndroid Build Coastguard Worker	}
385*333d2b36SAndroid Build Coastguard Worker	return nil
386*333d2b36SAndroid Build Coastguard Worker}
387*333d2b36SAndroid Build Coastguard Worker
388*333d2b36SAndroid Build Coastguard Workerfunc (p *Pom) GetBazelDepNames(modules map[string]*Pom) error {
389*333d2b36SAndroid Build Coastguard Worker	for _, d := range p.Dependencies {
390*333d2b36SAndroid Build Coastguard Worker		bazelName, err := BpNameToBazelTarget(d.BpName(), modules)
391*333d2b36SAndroid Build Coastguard Worker		if err != nil {
392*333d2b36SAndroid Build Coastguard Worker			return err
393*333d2b36SAndroid Build Coastguard Worker		}
394*333d2b36SAndroid Build Coastguard Worker		d.BazelTarget = bazelName
395*333d2b36SAndroid Build Coastguard Worker	}
396*333d2b36SAndroid Build Coastguard Worker	return nil
397*333d2b36SAndroid Build Coastguard Worker}
398*333d2b36SAndroid Build Coastguard Worker
399*333d2b36SAndroid Build Coastguard Workerfunc BpNameToBazelTarget(bpName string, modules map[string]*Pom) (string, error) {
400*333d2b36SAndroid Build Coastguard Worker	cmd, androidTop, envSetupSh := PathModVars()
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Worker	if _, ok := modules[bpName]; ok {
403*333d2b36SAndroid Build Coastguard Worker		// We've seen the POM for this dependency, it will be local to the output BUILD file
404*333d2b36SAndroid Build Coastguard Worker		return ":" + bpName, nil
405*333d2b36SAndroid Build Coastguard Worker	} else {
406*333d2b36SAndroid Build Coastguard Worker		// we don't have the POM for this artifact, find and use the fully qualified target name.
407*333d2b36SAndroid Build Coastguard Worker		output, err := exec.Command(cmd, "-c", ". "+envSetupSh+" && pathmod "+bpName).Output()
408*333d2b36SAndroid Build Coastguard Worker		if exitErr, _ := err.(*exec.ExitError); exitErr != nil {
409*333d2b36SAndroid Build Coastguard Worker			return "", fmt.Errorf("failed to run %s %s\n%s", cmd, bpName, string(exitErr.Stderr))
410*333d2b36SAndroid Build Coastguard Worker		} else if err != nil {
411*333d2b36SAndroid Build Coastguard Worker			return "", err
412*333d2b36SAndroid Build Coastguard Worker		}
413*333d2b36SAndroid Build Coastguard Worker		relPath := ""
414*333d2b36SAndroid Build Coastguard Worker		for _, line := range strings.Fields(string(output)) {
415*333d2b36SAndroid Build Coastguard Worker			if strings.Contains(line, androidTop) {
416*333d2b36SAndroid Build Coastguard Worker				relPath = strings.TrimPrefix(line, androidTop)
417*333d2b36SAndroid Build Coastguard Worker				relPath = strings.TrimLeft(relPath, "/")
418*333d2b36SAndroid Build Coastguard Worker			}
419*333d2b36SAndroid Build Coastguard Worker		}
420*333d2b36SAndroid Build Coastguard Worker		return "//" + relPath + ":" + bpName, nil
421*333d2b36SAndroid Build Coastguard Worker	}
422*333d2b36SAndroid Build Coastguard Worker}
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) SdkVersion() string {
425*333d2b36SAndroid Build Coastguard Worker	return sdkVersion
426*333d2b36SAndroid Build Coastguard Worker}
427*333d2b36SAndroid Build Coastguard Worker
428*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) DefaultMinSdkVersion() string {
429*333d2b36SAndroid Build Coastguard Worker	return defaultMinSdkVersion
430*333d2b36SAndroid Build Coastguard Worker}
431*333d2b36SAndroid Build Coastguard Worker
432*333d2b36SAndroid Build Coastguard Workerfunc (p Pom) Jetifier() bool {
433*333d2b36SAndroid Build Coastguard Worker	return jetifier
434*333d2b36SAndroid Build Coastguard Worker}
435*333d2b36SAndroid Build Coastguard Worker
436*333d2b36SAndroid Build Coastguard Workerfunc (p *Pom) FixDeps(modules map[string]*Pom) {
437*333d2b36SAndroid Build Coastguard Worker	for _, d := range p.Dependencies {
438*333d2b36SAndroid Build Coastguard Worker		if d.Type == "" {
439*333d2b36SAndroid Build Coastguard Worker			if depPom, ok := modules[d.BpName()]; ok {
440*333d2b36SAndroid Build Coastguard Worker				// We've seen the POM for this dependency, use its packaging
441*333d2b36SAndroid Build Coastguard Worker				// as the dependency type rather than Maven spec default.
442*333d2b36SAndroid Build Coastguard Worker				d.Type = depPom.Packaging
443*333d2b36SAndroid Build Coastguard Worker			} else {
444*333d2b36SAndroid Build Coastguard Worker				// Dependency type was not specified and we don't have the POM
445*333d2b36SAndroid Build Coastguard Worker				// for this artifact, use the default from Maven spec.
446*333d2b36SAndroid Build Coastguard Worker				d.Type = "jar"
447*333d2b36SAndroid Build Coastguard Worker			}
448*333d2b36SAndroid Build Coastguard Worker		}
449*333d2b36SAndroid Build Coastguard Worker		if d.Scope == "" {
450*333d2b36SAndroid Build Coastguard Worker			// Scope was not specified, use the default from Maven spec.
451*333d2b36SAndroid Build Coastguard Worker			d.Scope = "compile"
452*333d2b36SAndroid Build Coastguard Worker		}
453*333d2b36SAndroid Build Coastguard Worker	}
454*333d2b36SAndroid Build Coastguard Worker}
455*333d2b36SAndroid Build Coastguard Worker
456*333d2b36SAndroid Build Coastguard Worker// ExtractMinSdkVersion extracts the minSdkVersion from the AndroidManifest.xml file inside an aar file, or sets it
457*333d2b36SAndroid Build Coastguard Worker// to "current" if it is not present.
458*333d2b36SAndroid Build Coastguard Workerfunc (p *Pom) ExtractMinSdkVersion() error {
459*333d2b36SAndroid Build Coastguard Worker	aar, err := zip.OpenReader(p.ArtifactFile)
460*333d2b36SAndroid Build Coastguard Worker	if err != nil {
461*333d2b36SAndroid Build Coastguard Worker		return err
462*333d2b36SAndroid Build Coastguard Worker	}
463*333d2b36SAndroid Build Coastguard Worker	defer aar.Close()
464*333d2b36SAndroid Build Coastguard Worker
465*333d2b36SAndroid Build Coastguard Worker	var manifest *zip.File
466*333d2b36SAndroid Build Coastguard Worker	for _, f := range aar.File {
467*333d2b36SAndroid Build Coastguard Worker		if f.Name == "AndroidManifest.xml" {
468*333d2b36SAndroid Build Coastguard Worker			manifest = f
469*333d2b36SAndroid Build Coastguard Worker			break
470*333d2b36SAndroid Build Coastguard Worker		}
471*333d2b36SAndroid Build Coastguard Worker	}
472*333d2b36SAndroid Build Coastguard Worker
473*333d2b36SAndroid Build Coastguard Worker	if manifest == nil {
474*333d2b36SAndroid Build Coastguard Worker		return fmt.Errorf("failed to find AndroidManifest.xml in %s", p.ArtifactFile)
475*333d2b36SAndroid Build Coastguard Worker	}
476*333d2b36SAndroid Build Coastguard Worker
477*333d2b36SAndroid Build Coastguard Worker	r, err := manifest.Open()
478*333d2b36SAndroid Build Coastguard Worker	if err != nil {
479*333d2b36SAndroid Build Coastguard Worker		return err
480*333d2b36SAndroid Build Coastguard Worker	}
481*333d2b36SAndroid Build Coastguard Worker	defer r.Close()
482*333d2b36SAndroid Build Coastguard Worker
483*333d2b36SAndroid Build Coastguard Worker	decoder := xml.NewDecoder(r)
484*333d2b36SAndroid Build Coastguard Worker
485*333d2b36SAndroid Build Coastguard Worker	manifestData := struct {
486*333d2b36SAndroid Build Coastguard Worker		XMLName  xml.Name `xml:"manifest"`
487*333d2b36SAndroid Build Coastguard Worker		Uses_sdk struct {
488*333d2b36SAndroid Build Coastguard Worker			MinSdkVersion string `xml:"http://schemas.android.com/apk/res/android minSdkVersion,attr"`
489*333d2b36SAndroid Build Coastguard Worker		} `xml:"uses-sdk"`
490*333d2b36SAndroid Build Coastguard Worker	}{}
491*333d2b36SAndroid Build Coastguard Worker
492*333d2b36SAndroid Build Coastguard Worker	err = decoder.Decode(&manifestData)
493*333d2b36SAndroid Build Coastguard Worker	if err != nil {
494*333d2b36SAndroid Build Coastguard Worker		return err
495*333d2b36SAndroid Build Coastguard Worker	}
496*333d2b36SAndroid Build Coastguard Worker
497*333d2b36SAndroid Build Coastguard Worker	p.MinSdkVersion = manifestData.Uses_sdk.MinSdkVersion
498*333d2b36SAndroid Build Coastguard Worker	if p.MinSdkVersion == "" {
499*333d2b36SAndroid Build Coastguard Worker		p.MinSdkVersion = "current"
500*333d2b36SAndroid Build Coastguard Worker	}
501*333d2b36SAndroid Build Coastguard Worker
502*333d2b36SAndroid Build Coastguard Worker	return nil
503*333d2b36SAndroid Build Coastguard Worker}
504*333d2b36SAndroid Build Coastguard Worker
505*333d2b36SAndroid Build Coastguard Workervar bpTemplate = template.Must(template.New("bp").Parse(`
506*333d2b36SAndroid Build Coastguard Worker{{.ImportModuleType}} {
507*333d2b36SAndroid Build Coastguard Worker    name: "{{.BpName}}",
508*333d2b36SAndroid Build Coastguard Worker    {{- if .IsApk}}
509*333d2b36SAndroid Build Coastguard Worker    {{.ImportProperty}}: "{{.ArtifactFile}}",
510*333d2b36SAndroid Build Coastguard Worker    {{- else}}
511*333d2b36SAndroid Build Coastguard Worker    {{.ImportProperty}}: ["{{.ArtifactFile}}"],
512*333d2b36SAndroid Build Coastguard Worker    sdk_version: "{{.SdkVersion}}",
513*333d2b36SAndroid Build Coastguard Worker    {{- end}}
514*333d2b36SAndroid Build Coastguard Worker    {{- if .Jetifier}}
515*333d2b36SAndroid Build Coastguard Worker    jetifier: true,
516*333d2b36SAndroid Build Coastguard Worker    {{- end}}
517*333d2b36SAndroid Build Coastguard Worker    {{- if .IsHostAndDeviceModule}}
518*333d2b36SAndroid Build Coastguard Worker    host_supported: true,
519*333d2b36SAndroid Build Coastguard Worker    {{- end}}
520*333d2b36SAndroid Build Coastguard Worker    {{- if not .IsHostOnly}}
521*333d2b36SAndroid Build Coastguard Worker    apex_available: [
522*333d2b36SAndroid Build Coastguard Worker        "//apex_available:platform",
523*333d2b36SAndroid Build Coastguard Worker        "//apex_available:anyapex",
524*333d2b36SAndroid Build Coastguard Worker    ],
525*333d2b36SAndroid Build Coastguard Worker    {{- end}}
526*333d2b36SAndroid Build Coastguard Worker    {{- if .IsAar}}
527*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.MinSdkVersion}}",
528*333d2b36SAndroid Build Coastguard Worker    static_libs: [
529*333d2b36SAndroid Build Coastguard Worker        {{- range .BpJarDeps}}
530*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
531*333d2b36SAndroid Build Coastguard Worker        {{- end}}
532*333d2b36SAndroid Build Coastguard Worker        {{- range .BpAarDeps}}
533*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
534*333d2b36SAndroid Build Coastguard Worker        {{- end}}
535*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraStaticLibs}}
536*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
537*333d2b36SAndroid Build Coastguard Worker        {{- end}}
538*333d2b36SAndroid Build Coastguard Worker    ],
539*333d2b36SAndroid Build Coastguard Worker    {{- if .BpExtraLibs}}
540*333d2b36SAndroid Build Coastguard Worker    libs: [
541*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraLibs}}
542*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
543*333d2b36SAndroid Build Coastguard Worker        {{- end}}
544*333d2b36SAndroid Build Coastguard Worker    ],
545*333d2b36SAndroid Build Coastguard Worker    {{- end}}
546*333d2b36SAndroid Build Coastguard Worker    {{- if .BpOptionalUsesLibs}}
547*333d2b36SAndroid Build Coastguard Worker    optional_uses_libs: [
548*333d2b36SAndroid Build Coastguard Worker        {{- range .BpOptionalUsesLibs}}
549*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
550*333d2b36SAndroid Build Coastguard Worker        {{- end}}
551*333d2b36SAndroid Build Coastguard Worker    ],
552*333d2b36SAndroid Build Coastguard Worker    {{- end}}
553*333d2b36SAndroid Build Coastguard Worker    {{- else if not .IsHostOnly}}
554*333d2b36SAndroid Build Coastguard Worker    {{- if not .IsApk}}
555*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.DefaultMinSdkVersion}}",
556*333d2b36SAndroid Build Coastguard Worker    {{- end}}
557*333d2b36SAndroid Build Coastguard Worker    {{- end}}
558*333d2b36SAndroid Build Coastguard Worker    {{- if .IsApk}}
559*333d2b36SAndroid Build Coastguard Worker    preprocessed: true,
560*333d2b36SAndroid Build Coastguard Worker    presigned: true,
561*333d2b36SAndroid Build Coastguard Worker    {{- end}}
562*333d2b36SAndroid Build Coastguard Worker
563*333d2b36SAndroid Build Coastguard Worker}
564*333d2b36SAndroid Build Coastguard Worker`))
565*333d2b36SAndroid Build Coastguard Worker
566*333d2b36SAndroid Build Coastguard Workervar bpDepsTemplate = template.Must(template.New("bp").Parse(`
567*333d2b36SAndroid Build Coastguard Worker{{.ImportModuleType}} {
568*333d2b36SAndroid Build Coastguard Worker    name: "{{.BpName}}-nodeps",
569*333d2b36SAndroid Build Coastguard Worker    {{.ImportProperty}}: ["{{.ArtifactFile}}"],
570*333d2b36SAndroid Build Coastguard Worker    sdk_version: "{{.SdkVersion}}",
571*333d2b36SAndroid Build Coastguard Worker    {{- if .Jetifier}}
572*333d2b36SAndroid Build Coastguard Worker    jetifier: true,
573*333d2b36SAndroid Build Coastguard Worker    {{- end}}
574*333d2b36SAndroid Build Coastguard Worker    {{- if .IsHostAndDeviceModule}}
575*333d2b36SAndroid Build Coastguard Worker    host_supported: true,
576*333d2b36SAndroid Build Coastguard Worker    {{- end}}
577*333d2b36SAndroid Build Coastguard Worker    {{- if not .IsHostOnly}}
578*333d2b36SAndroid Build Coastguard Worker    apex_available: [
579*333d2b36SAndroid Build Coastguard Worker        "//apex_available:platform",
580*333d2b36SAndroid Build Coastguard Worker        "//apex_available:anyapex",
581*333d2b36SAndroid Build Coastguard Worker    ],
582*333d2b36SAndroid Build Coastguard Worker    {{- end}}
583*333d2b36SAndroid Build Coastguard Worker    {{- if .IsAar}}
584*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.MinSdkVersion}}",
585*333d2b36SAndroid Build Coastguard Worker    static_libs: [
586*333d2b36SAndroid Build Coastguard Worker        {{- range .BpJarDeps}}
587*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
588*333d2b36SAndroid Build Coastguard Worker        {{- end}}
589*333d2b36SAndroid Build Coastguard Worker        {{- range .BpAarDeps}}
590*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
591*333d2b36SAndroid Build Coastguard Worker        {{- end}}
592*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraStaticLibs}}
593*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
594*333d2b36SAndroid Build Coastguard Worker        {{- end}}
595*333d2b36SAndroid Build Coastguard Worker    ],
596*333d2b36SAndroid Build Coastguard Worker    {{- if .BpExtraLibs}}
597*333d2b36SAndroid Build Coastguard Worker    libs: [
598*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraLibs}}
599*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
600*333d2b36SAndroid Build Coastguard Worker        {{- end}}
601*333d2b36SAndroid Build Coastguard Worker    ],
602*333d2b36SAndroid Build Coastguard Worker    {{- end}}
603*333d2b36SAndroid Build Coastguard Worker    {{- else if not .IsHostOnly}}
604*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.DefaultMinSdkVersion}}",
605*333d2b36SAndroid Build Coastguard Worker    {{- end}}
606*333d2b36SAndroid Build Coastguard Worker}
607*333d2b36SAndroid Build Coastguard Worker
608*333d2b36SAndroid Build Coastguard Worker{{.ModuleType}} {
609*333d2b36SAndroid Build Coastguard Worker    name: "{{.BpName}}",
610*333d2b36SAndroid Build Coastguard Worker    {{- if .IsDeviceModule}}
611*333d2b36SAndroid Build Coastguard Worker    sdk_version: "{{.SdkVersion}}",
612*333d2b36SAndroid Build Coastguard Worker    {{- if .IsHostAndDeviceModule}}
613*333d2b36SAndroid Build Coastguard Worker    host_supported: true,
614*333d2b36SAndroid Build Coastguard Worker    {{- end}}
615*333d2b36SAndroid Build Coastguard Worker    {{- if not .IsHostOnly}}
616*333d2b36SAndroid Build Coastguard Worker    apex_available: [
617*333d2b36SAndroid Build Coastguard Worker        "//apex_available:platform",
618*333d2b36SAndroid Build Coastguard Worker        "//apex_available:anyapex",
619*333d2b36SAndroid Build Coastguard Worker    ],
620*333d2b36SAndroid Build Coastguard Worker    {{- end}}
621*333d2b36SAndroid Build Coastguard Worker    {{- if .IsAar}}
622*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.MinSdkVersion}}",
623*333d2b36SAndroid Build Coastguard Worker    manifest: "manifests/{{.BpName}}/AndroidManifest.xml",
624*333d2b36SAndroid Build Coastguard Worker    {{- else if not .IsHostOnly}}
625*333d2b36SAndroid Build Coastguard Worker    min_sdk_version: "{{.DefaultMinSdkVersion}}",
626*333d2b36SAndroid Build Coastguard Worker    {{- end}}
627*333d2b36SAndroid Build Coastguard Worker    {{- end}}
628*333d2b36SAndroid Build Coastguard Worker    static_libs: [
629*333d2b36SAndroid Build Coastguard Worker        "{{.BpName}}-nodeps",
630*333d2b36SAndroid Build Coastguard Worker        {{- range .BpJarDeps}}
631*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
632*333d2b36SAndroid Build Coastguard Worker        {{- end}}
633*333d2b36SAndroid Build Coastguard Worker        {{- range .BpAarDeps}}
634*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
635*333d2b36SAndroid Build Coastguard Worker        {{- end}}
636*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraStaticLibs}}
637*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
638*333d2b36SAndroid Build Coastguard Worker        {{- end}}
639*333d2b36SAndroid Build Coastguard Worker    ],
640*333d2b36SAndroid Build Coastguard Worker    {{- if .BpExtraLibs}}
641*333d2b36SAndroid Build Coastguard Worker    libs: [
642*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraLibs}}
643*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
644*333d2b36SAndroid Build Coastguard Worker        {{- end}}
645*333d2b36SAndroid Build Coastguard Worker    ],
646*333d2b36SAndroid Build Coastguard Worker    {{- end}}
647*333d2b36SAndroid Build Coastguard Worker    {{- if .BpOptionalUsesLibs}}
648*333d2b36SAndroid Build Coastguard Worker    optional_uses_libs: [
649*333d2b36SAndroid Build Coastguard Worker        {{- range .BpOptionalUsesLibs}}
650*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
651*333d2b36SAndroid Build Coastguard Worker        {{- end}}
652*333d2b36SAndroid Build Coastguard Worker    ],
653*333d2b36SAndroid Build Coastguard Worker    {{- end}}
654*333d2b36SAndroid Build Coastguard Worker    java_version: "1.8",
655*333d2b36SAndroid Build Coastguard Worker}
656*333d2b36SAndroid Build Coastguard Worker`))
657*333d2b36SAndroid Build Coastguard Worker
658*333d2b36SAndroid Build Coastguard Workervar bazelTemplate = template.Must(template.New("bp").Parse(`
659*333d2b36SAndroid Build Coastguard Worker{{.BazelImportTargetType}} (
660*333d2b36SAndroid Build Coastguard Worker    name = "{{.BpName}}",
661*333d2b36SAndroid Build Coastguard Worker    {{.BazelImportProperty}}: {{- if not .IsAar}}[{{- end}}"{{.ArtifactFile}}"{{- if not .IsAar}}]{{- end}},
662*333d2b36SAndroid Build Coastguard Worker    visibility = ["//visibility:public"],
663*333d2b36SAndroid Build Coastguard Worker    {{- if .IsAar}}
664*333d2b36SAndroid Build Coastguard Worker    deps = [
665*333d2b36SAndroid Build Coastguard Worker        {{- range .BazelJarDeps}}
666*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
667*333d2b36SAndroid Build Coastguard Worker        {{- end}}
668*333d2b36SAndroid Build Coastguard Worker        {{- range .BazelAarDeps}}
669*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
670*333d2b36SAndroid Build Coastguard Worker        {{- end}}
671*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraStaticLibs}}
672*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
673*333d2b36SAndroid Build Coastguard Worker        {{- end}}
674*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraLibs}}
675*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
676*333d2b36SAndroid Build Coastguard Worker        {{- end}}
677*333d2b36SAndroid Build Coastguard Worker        {{- range .BpOptionalUsesLibs}}
678*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
679*333d2b36SAndroid Build Coastguard Worker        {{- end}}
680*333d2b36SAndroid Build Coastguard Worker    ],
681*333d2b36SAndroid Build Coastguard Worker    {{- end}}
682*333d2b36SAndroid Build Coastguard Worker)
683*333d2b36SAndroid Build Coastguard Worker`))
684*333d2b36SAndroid Build Coastguard Worker
685*333d2b36SAndroid Build Coastguard Workervar bazelDepsTemplate = template.Must(template.New("bp").Parse(`
686*333d2b36SAndroid Build Coastguard Worker{{.BazelImportTargetType}} (
687*333d2b36SAndroid Build Coastguard Worker    name = "{{.BpName}}",
688*333d2b36SAndroid Build Coastguard Worker    {{.BazelImportProperty}} = {{- if not .IsAar}}[{{- end}}"{{.ArtifactFile}}"{{- if not .IsAar}}]{{- end}},
689*333d2b36SAndroid Build Coastguard Worker    visibility = ["//visibility:public"],
690*333d2b36SAndroid Build Coastguard Worker    exports = [
691*333d2b36SAndroid Build Coastguard Worker        {{- range .BazelJarDeps}}
692*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
693*333d2b36SAndroid Build Coastguard Worker        {{- end}}
694*333d2b36SAndroid Build Coastguard Worker        {{- range .BazelAarDeps}}
695*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
696*333d2b36SAndroid Build Coastguard Worker        {{- end}}
697*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraStaticLibs}}
698*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
699*333d2b36SAndroid Build Coastguard Worker        {{- end}}
700*333d2b36SAndroid Build Coastguard Worker        {{- range .BpExtraLibs}}
701*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
702*333d2b36SAndroid Build Coastguard Worker        {{- end}}
703*333d2b36SAndroid Build Coastguard Worker        {{- range .BpOptionalUsesLibs}}
704*333d2b36SAndroid Build Coastguard Worker        "{{.}}",
705*333d2b36SAndroid Build Coastguard Worker        {{- end}}
706*333d2b36SAndroid Build Coastguard Worker    ],
707*333d2b36SAndroid Build Coastguard Worker)
708*333d2b36SAndroid Build Coastguard Worker`))
709*333d2b36SAndroid Build Coastguard Worker
710*333d2b36SAndroid Build Coastguard Workerfunc parse(filename string) (*Pom, error) {
711*333d2b36SAndroid Build Coastguard Worker	data, err := ioutil.ReadFile(filename)
712*333d2b36SAndroid Build Coastguard Worker	if err != nil {
713*333d2b36SAndroid Build Coastguard Worker		return nil, err
714*333d2b36SAndroid Build Coastguard Worker	}
715*333d2b36SAndroid Build Coastguard Worker
716*333d2b36SAndroid Build Coastguard Worker	var pom Pom
717*333d2b36SAndroid Build Coastguard Worker	err = xml.Unmarshal(data, &pom)
718*333d2b36SAndroid Build Coastguard Worker	if err != nil {
719*333d2b36SAndroid Build Coastguard Worker		return nil, err
720*333d2b36SAndroid Build Coastguard Worker	}
721*333d2b36SAndroid Build Coastguard Worker
722*333d2b36SAndroid Build Coastguard Worker	if useVersion != "" && pom.Version != useVersion {
723*333d2b36SAndroid Build Coastguard Worker		return nil, nil
724*333d2b36SAndroid Build Coastguard Worker	}
725*333d2b36SAndroid Build Coastguard Worker
726*333d2b36SAndroid Build Coastguard Worker	if pom.Packaging == "" {
727*333d2b36SAndroid Build Coastguard Worker		pom.Packaging = "jar"
728*333d2b36SAndroid Build Coastguard Worker	}
729*333d2b36SAndroid Build Coastguard Worker
730*333d2b36SAndroid Build Coastguard Worker	pom.PomFile = filename
731*333d2b36SAndroid Build Coastguard Worker	pom.ArtifactFile = strings.TrimSuffix(filename, ".pom") + "." + pom.Packaging
732*333d2b36SAndroid Build Coastguard Worker
733*333d2b36SAndroid Build Coastguard Worker	return &pom, nil
734*333d2b36SAndroid Build Coastguard Worker}
735*333d2b36SAndroid Build Coastguard Worker
736*333d2b36SAndroid Build Coastguard Workerfunc rerunForRegen(filename string) error {
737*333d2b36SAndroid Build Coastguard Worker	buf, err := ioutil.ReadFile(filename)
738*333d2b36SAndroid Build Coastguard Worker	if err != nil {
739*333d2b36SAndroid Build Coastguard Worker		return err
740*333d2b36SAndroid Build Coastguard Worker	}
741*333d2b36SAndroid Build Coastguard Worker
742*333d2b36SAndroid Build Coastguard Worker	scanner := bufio.NewScanner(bytes.NewBuffer(buf))
743*333d2b36SAndroid Build Coastguard Worker
744*333d2b36SAndroid Build Coastguard Worker	// Skip the first line in the file
745*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < 2; i++ {
746*333d2b36SAndroid Build Coastguard Worker		if !scanner.Scan() {
747*333d2b36SAndroid Build Coastguard Worker			if scanner.Err() != nil {
748*333d2b36SAndroid Build Coastguard Worker				return scanner.Err()
749*333d2b36SAndroid Build Coastguard Worker			} else {
750*333d2b36SAndroid Build Coastguard Worker				return fmt.Errorf("unexpected EOF")
751*333d2b36SAndroid Build Coastguard Worker			}
752*333d2b36SAndroid Build Coastguard Worker		}
753*333d2b36SAndroid Build Coastguard Worker	}
754*333d2b36SAndroid Build Coastguard Worker
755*333d2b36SAndroid Build Coastguard Worker	// Extract the old args from the file
756*333d2b36SAndroid Build Coastguard Worker	line := scanner.Text()
757*333d2b36SAndroid Build Coastguard Worker	if strings.HasPrefix(line, "// pom2bp ") { // .bp file
758*333d2b36SAndroid Build Coastguard Worker		line = strings.TrimPrefix(line, "// pom2bp ")
759*333d2b36SAndroid Build Coastguard Worker	} else if strings.HasPrefix(line, "// pom2mk ") { // .bp file converted from .mk file
760*333d2b36SAndroid Build Coastguard Worker		line = strings.TrimPrefix(line, "// pom2mk ")
761*333d2b36SAndroid Build Coastguard Worker	} else if strings.HasPrefix(line, "# pom2mk ") { // .mk file
762*333d2b36SAndroid Build Coastguard Worker		line = strings.TrimPrefix(line, "# pom2mk ")
763*333d2b36SAndroid Build Coastguard Worker	} else if strings.HasPrefix(line, "# pom2bp ") { // Bazel BUILD file
764*333d2b36SAndroid Build Coastguard Worker		line = strings.TrimPrefix(line, "# pom2bp ")
765*333d2b36SAndroid Build Coastguard Worker	} else {
766*333d2b36SAndroid Build Coastguard Worker		return fmt.Errorf("unexpected second line: %q", line)
767*333d2b36SAndroid Build Coastguard Worker	}
768*333d2b36SAndroid Build Coastguard Worker	args := strings.Split(line, " ")
769*333d2b36SAndroid Build Coastguard Worker	lastArg := args[len(args)-1]
770*333d2b36SAndroid Build Coastguard Worker	args = args[:len(args)-1]
771*333d2b36SAndroid Build Coastguard Worker
772*333d2b36SAndroid Build Coastguard Worker	// Append all current command line args except -regen <file> to the ones from the file
773*333d2b36SAndroid Build Coastguard Worker	for i := 1; i < len(os.Args); i++ {
774*333d2b36SAndroid Build Coastguard Worker		if os.Args[i] == "-regen" || os.Args[i] == "--regen" {
775*333d2b36SAndroid Build Coastguard Worker			i++
776*333d2b36SAndroid Build Coastguard Worker		} else {
777*333d2b36SAndroid Build Coastguard Worker			args = append(args, os.Args[i])
778*333d2b36SAndroid Build Coastguard Worker		}
779*333d2b36SAndroid Build Coastguard Worker	}
780*333d2b36SAndroid Build Coastguard Worker	args = append(args, lastArg)
781*333d2b36SAndroid Build Coastguard Worker
782*333d2b36SAndroid Build Coastguard Worker	cmd := os.Args[0] + " " + strings.Join(args, " ")
783*333d2b36SAndroid Build Coastguard Worker	// Re-exec pom2bp with the new arguments
784*333d2b36SAndroid Build Coastguard Worker	output, err := exec.Command("/bin/sh", "-c", cmd).Output()
785*333d2b36SAndroid Build Coastguard Worker	if exitErr, _ := err.(*exec.ExitError); exitErr != nil {
786*333d2b36SAndroid Build Coastguard Worker		return fmt.Errorf("failed to run %s\n%s", cmd, string(exitErr.Stderr))
787*333d2b36SAndroid Build Coastguard Worker	} else if err != nil {
788*333d2b36SAndroid Build Coastguard Worker		return err
789*333d2b36SAndroid Build Coastguard Worker	}
790*333d2b36SAndroid Build Coastguard Worker
791*333d2b36SAndroid Build Coastguard Worker	// If the old file was a .mk file, replace it with a .bp file
792*333d2b36SAndroid Build Coastguard Worker	if filepath.Ext(filename) == ".mk" {
793*333d2b36SAndroid Build Coastguard Worker		os.Remove(filename)
794*333d2b36SAndroid Build Coastguard Worker		filename = strings.TrimSuffix(filename, ".mk") + ".bp"
795*333d2b36SAndroid Build Coastguard Worker	}
796*333d2b36SAndroid Build Coastguard Worker
797*333d2b36SAndroid Build Coastguard Worker	return ioutil.WriteFile(filename, output, 0666)
798*333d2b36SAndroid Build Coastguard Worker}
799*333d2b36SAndroid Build Coastguard Worker
800*333d2b36SAndroid Build Coastguard Workerfunc main() {
801*333d2b36SAndroid Build Coastguard Worker	flag.Usage = func() {
802*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(os.Stderr, `pom2bp, a tool to create Android.bp files from maven repos
803*333d2b36SAndroid Build Coastguard Worker
804*333d2b36SAndroid Build Coastguard WorkerThe tool will extract the necessary information from *.pom files to create an Android.bp whose
805*333d2b36SAndroid Build Coastguard Workeraar libraries can be linked against when using AAPT2.
806*333d2b36SAndroid Build Coastguard Worker
807*333d2b36SAndroid Build Coastguard WorkerUsage: %s [--rewrite <regex>=<replace>] [--exclude <module>] [--extra-static-libs <module>=<module>[,<module>]] [--extra-libs <module>=<module>[,<module>]] [--optional-uses-libs <module>=<module>[,<module>]] [<dir>] [-regen <file>]
808*333d2b36SAndroid Build Coastguard Worker
809*333d2b36SAndroid Build Coastguard Worker  -rewrite <regex>=<replace>
810*333d2b36SAndroid Build Coastguard Worker     rewrite can be used to specify mappings between Maven projects and Android.bp modules. The -rewrite
811*333d2b36SAndroid Build Coastguard Worker     option can be specified multiple times. When determining the Android.bp module for a given Maven
812*333d2b36SAndroid Build Coastguard Worker     project, mappings are searched in the order they were specified. The first <regex> matching
813*333d2b36SAndroid Build Coastguard Worker     either the Maven project's <groupId>:<artifactId> or <artifactId> will be used to generate
814*333d2b36SAndroid Build Coastguard Worker     the Android.bp module name using <replace>. If no matches are found, <artifactId> is used.
815*333d2b36SAndroid Build Coastguard Worker  -exclude <module>
816*333d2b36SAndroid Build Coastguard Worker     Don't put the specified module in the Android.bp file.
817*333d2b36SAndroid Build Coastguard Worker  -extra-static-libs <module>=<module>[,<module>]
818*333d2b36SAndroid Build Coastguard Worker     Some Android.bp modules have transitive static dependencies that must be specified when they
819*333d2b36SAndroid Build Coastguard Worker     are depended upon (like android-support-v7-mediarouter requires android-support-v7-appcompat).
820*333d2b36SAndroid Build Coastguard Worker     This may be specified multiple times to declare these dependencies.
821*333d2b36SAndroid Build Coastguard Worker  -extra-libs <module>=<module>[,<module>]
822*333d2b36SAndroid Build Coastguard Worker     Some Android.bp modules have transitive runtime dependencies that must be specified when they
823*333d2b36SAndroid Build Coastguard Worker     are depended upon (like androidx.test.rules requires android.test.base).
824*333d2b36SAndroid Build Coastguard Worker     This may be specified multiple times to declare these dependencies.
825*333d2b36SAndroid Build Coastguard Worker  -optional-uses-libs <module>=<module>[,<module>]
826*333d2b36SAndroid Build Coastguard Worker     Some Android.bp modules have optional dependencies (typically specified with <uses-library> in
827*333d2b36SAndroid Build Coastguard Worker     the module's AndroidManifest.xml) that must be specified when they are depended upon (like
828*333d2b36SAndroid Build Coastguard Worker     androidx.window:window optionally requires androidx.window:window-extensions).
829*333d2b36SAndroid Build Coastguard Worker     This may be specified multiple times to declare these dependencies.
830*333d2b36SAndroid Build Coastguard Worker  -sdk-version <version>
831*333d2b36SAndroid Build Coastguard Worker     Sets sdk_version: "<version>" for all modules.
832*333d2b36SAndroid Build Coastguard Worker  -default-min-sdk-version
833*333d2b36SAndroid Build Coastguard Worker     The default min_sdk_version to use for a module if one cannot be mined from AndroidManifest.xml
834*333d2b36SAndroid Build Coastguard Worker  -use-version <version>
835*333d2b36SAndroid Build Coastguard Worker     If the maven directory contains multiple versions of artifacts and their pom files,
836*333d2b36SAndroid Build Coastguard Worker     -use-version can be used to only write Android.bp files for a specific version of those artifacts.
837*333d2b36SAndroid Build Coastguard Worker  -write-cmd
838*333d2b36SAndroid Build Coastguard Worker     Whether to write the command line arguments used to generate the build file as a comment at
839*333d2b36SAndroid Build Coastguard Worker     the top of the build file itself.
840*333d2b36SAndroid Build Coastguard Worker  -jetifier
841*333d2b36SAndroid Build Coastguard Worker     Sets jetifier: true for all modules.
842*333d2b36SAndroid Build Coastguard Worker  <dir>
843*333d2b36SAndroid Build Coastguard Worker     The directory to search for *.pom files under.
844*333d2b36SAndroid Build Coastguard Worker     The contents are written to stdout, to be put in the current directory (often as Android.bp)
845*333d2b36SAndroid Build Coastguard Worker  -regen <file>
846*333d2b36SAndroid Build Coastguard Worker     Read arguments from <file> and overwrite it (if it ends with .bp) or move it to .bp (if it
847*333d2b36SAndroid Build Coastguard Worker     ends with .mk).
848*333d2b36SAndroid Build Coastguard Worker
849*333d2b36SAndroid Build Coastguard Worker`, os.Args[0])
850*333d2b36SAndroid Build Coastguard Worker	}
851*333d2b36SAndroid Build Coastguard Worker
852*333d2b36SAndroid Build Coastguard Worker	var regen string
853*333d2b36SAndroid Build Coastguard Worker	var pom2build bool
854*333d2b36SAndroid Build Coastguard Worker	var prepend string
855*333d2b36SAndroid Build Coastguard Worker
856*333d2b36SAndroid Build Coastguard Worker	flag.Var(&excludes, "exclude", "Exclude module")
857*333d2b36SAndroid Build Coastguard Worker	flag.Var(&extraStaticLibs, "extra-static-libs", "Extra static dependencies needed when depending on a module")
858*333d2b36SAndroid Build Coastguard Worker	flag.Var(&extraLibs, "extra-libs", "Extra runtime dependencies needed when depending on a module")
859*333d2b36SAndroid Build Coastguard Worker	flag.Var(&optionalUsesLibs, "optional-uses-libs", "Extra optional dependencies needed when depending on a module")
860*333d2b36SAndroid Build Coastguard Worker	flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
861*333d2b36SAndroid Build Coastguard Worker	flag.Var(&hostModuleNames, "host", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is a host module")
862*333d2b36SAndroid Build Coastguard Worker	flag.Var(&hostAndDeviceModuleNames, "host-and-device", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is both a host and device module.")
863*333d2b36SAndroid Build Coastguard Worker	flag.StringVar(&sdkVersion, "sdk-version", "", "What to write to sdk_version")
864*333d2b36SAndroid Build Coastguard Worker	flag.StringVar(&defaultMinSdkVersion, "default-min-sdk-version", "24", "Default min_sdk_version to use, if one is not available from AndroidManifest.xml. Default: 24")
865*333d2b36SAndroid Build Coastguard Worker	flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
866*333d2b36SAndroid Build Coastguard Worker	flag.BoolVar(&staticDeps, "static-deps", false, "Statically include direct dependencies")
867*333d2b36SAndroid Build Coastguard Worker	flag.BoolVar(&writeCmd, "write-cmd", true, "Write command line arguments as a comment")
868*333d2b36SAndroid Build Coastguard Worker	flag.BoolVar(&jetifier, "jetifier", false, "Sets jetifier: true on all modules")
869*333d2b36SAndroid Build Coastguard Worker	flag.StringVar(&regen, "regen", "", "Rewrite specified file")
870*333d2b36SAndroid Build Coastguard Worker	flag.BoolVar(&pom2build, "pom2build", false, "If true, will generate a Bazel BUILD file *instead* of a .bp file")
871*333d2b36SAndroid Build Coastguard Worker	flag.StringVar(&prepend, "prepend", "", "Path to a file containing text to insert at the beginning of the generated build file")
872*333d2b36SAndroid Build Coastguard Worker	flag.Parse()
873*333d2b36SAndroid Build Coastguard Worker
874*333d2b36SAndroid Build Coastguard Worker	if regen != "" {
875*333d2b36SAndroid Build Coastguard Worker		err := rerunForRegen(regen)
876*333d2b36SAndroid Build Coastguard Worker		if err != nil {
877*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, err)
878*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
879*333d2b36SAndroid Build Coastguard Worker		}
880*333d2b36SAndroid Build Coastguard Worker		os.Exit(0)
881*333d2b36SAndroid Build Coastguard Worker	}
882*333d2b36SAndroid Build Coastguard Worker
883*333d2b36SAndroid Build Coastguard Worker	if flag.NArg() == 0 {
884*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(os.Stderr, "Directory argument is required")
885*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
886*333d2b36SAndroid Build Coastguard Worker	} else if flag.NArg() > 1 {
887*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(os.Stderr, "Multiple directories provided:", strings.Join(flag.Args(), " "))
888*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
889*333d2b36SAndroid Build Coastguard Worker	}
890*333d2b36SAndroid Build Coastguard Worker
891*333d2b36SAndroid Build Coastguard Worker	dir := flag.Arg(0)
892*333d2b36SAndroid Build Coastguard Worker	absDir, err := filepath.Abs(dir)
893*333d2b36SAndroid Build Coastguard Worker	if err != nil {
894*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(os.Stderr, "Failed to get absolute directory:", err)
895*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
896*333d2b36SAndroid Build Coastguard Worker	}
897*333d2b36SAndroid Build Coastguard Worker
898*333d2b36SAndroid Build Coastguard Worker	var filenames []string
899*333d2b36SAndroid Build Coastguard Worker	err = filepath.Walk(absDir, func(path string, info os.FileInfo, err error) error {
900*333d2b36SAndroid Build Coastguard Worker		if err != nil {
901*333d2b36SAndroid Build Coastguard Worker			return err
902*333d2b36SAndroid Build Coastguard Worker		}
903*333d2b36SAndroid Build Coastguard Worker
904*333d2b36SAndroid Build Coastguard Worker		name := info.Name()
905*333d2b36SAndroid Build Coastguard Worker		if info.IsDir() {
906*333d2b36SAndroid Build Coastguard Worker			if strings.HasPrefix(name, ".") {
907*333d2b36SAndroid Build Coastguard Worker				return filepath.SkipDir
908*333d2b36SAndroid Build Coastguard Worker			}
909*333d2b36SAndroid Build Coastguard Worker			return nil
910*333d2b36SAndroid Build Coastguard Worker		}
911*333d2b36SAndroid Build Coastguard Worker
912*333d2b36SAndroid Build Coastguard Worker		if strings.HasPrefix(name, ".") {
913*333d2b36SAndroid Build Coastguard Worker			return nil
914*333d2b36SAndroid Build Coastguard Worker		}
915*333d2b36SAndroid Build Coastguard Worker
916*333d2b36SAndroid Build Coastguard Worker		if strings.HasSuffix(name, ".pom") {
917*333d2b36SAndroid Build Coastguard Worker			path, err = filepath.Rel(absDir, path)
918*333d2b36SAndroid Build Coastguard Worker			if err != nil {
919*333d2b36SAndroid Build Coastguard Worker				return err
920*333d2b36SAndroid Build Coastguard Worker			}
921*333d2b36SAndroid Build Coastguard Worker			filenames = append(filenames, filepath.Join(dir, path))
922*333d2b36SAndroid Build Coastguard Worker		}
923*333d2b36SAndroid Build Coastguard Worker		return nil
924*333d2b36SAndroid Build Coastguard Worker	})
925*333d2b36SAndroid Build Coastguard Worker	if err != nil {
926*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(os.Stderr, "Error walking files:", err)
927*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
928*333d2b36SAndroid Build Coastguard Worker	}
929*333d2b36SAndroid Build Coastguard Worker
930*333d2b36SAndroid Build Coastguard Worker	if len(filenames) == 0 {
931*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(os.Stderr, "Error: no *.pom files found under", dir)
932*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
933*333d2b36SAndroid Build Coastguard Worker	}
934*333d2b36SAndroid Build Coastguard Worker
935*333d2b36SAndroid Build Coastguard Worker	sort.Strings(filenames)
936*333d2b36SAndroid Build Coastguard Worker
937*333d2b36SAndroid Build Coastguard Worker	poms := []*Pom{}
938*333d2b36SAndroid Build Coastguard Worker	modules := make(map[string]*Pom)
939*333d2b36SAndroid Build Coastguard Worker	duplicate := false
940*333d2b36SAndroid Build Coastguard Worker	for _, filename := range filenames {
941*333d2b36SAndroid Build Coastguard Worker		pom, err := parse(filename)
942*333d2b36SAndroid Build Coastguard Worker		if err != nil {
943*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, "Error converting", filename, err)
944*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
945*333d2b36SAndroid Build Coastguard Worker		}
946*333d2b36SAndroid Build Coastguard Worker
947*333d2b36SAndroid Build Coastguard Worker		if pom != nil {
948*333d2b36SAndroid Build Coastguard Worker			key := pom.BpName()
949*333d2b36SAndroid Build Coastguard Worker			if excludes[key] {
950*333d2b36SAndroid Build Coastguard Worker				continue
951*333d2b36SAndroid Build Coastguard Worker			}
952*333d2b36SAndroid Build Coastguard Worker
953*333d2b36SAndroid Build Coastguard Worker			if old, ok := modules[key]; ok {
954*333d2b36SAndroid Build Coastguard Worker				fmt.Fprintln(os.Stderr, "Module", key, "defined twice:", old.PomFile, pom.PomFile)
955*333d2b36SAndroid Build Coastguard Worker				duplicate = true
956*333d2b36SAndroid Build Coastguard Worker			}
957*333d2b36SAndroid Build Coastguard Worker
958*333d2b36SAndroid Build Coastguard Worker			poms = append(poms, pom)
959*333d2b36SAndroid Build Coastguard Worker			modules[key] = pom
960*333d2b36SAndroid Build Coastguard Worker		}
961*333d2b36SAndroid Build Coastguard Worker	}
962*333d2b36SAndroid Build Coastguard Worker	if duplicate {
963*333d2b36SAndroid Build Coastguard Worker		os.Exit(1)
964*333d2b36SAndroid Build Coastguard Worker	}
965*333d2b36SAndroid Build Coastguard Worker
966*333d2b36SAndroid Build Coastguard Worker	if pom2build {
967*333d2b36SAndroid Build Coastguard Worker		if err := InitRefreshMod(poms); err != nil {
968*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(os.Stderr, "Error in refreshmod: %s", err)
969*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
970*333d2b36SAndroid Build Coastguard Worker		}
971*333d2b36SAndroid Build Coastguard Worker		BazelifyExtraDeps(extraStaticLibs, modules)
972*333d2b36SAndroid Build Coastguard Worker		BazelifyExtraDeps(extraLibs, modules)
973*333d2b36SAndroid Build Coastguard Worker		BazelifyExtraDeps(optionalUsesLibs, modules)
974*333d2b36SAndroid Build Coastguard Worker	}
975*333d2b36SAndroid Build Coastguard Worker
976*333d2b36SAndroid Build Coastguard Worker	for _, pom := range poms {
977*333d2b36SAndroid Build Coastguard Worker		if pom.IsAar() {
978*333d2b36SAndroid Build Coastguard Worker			err := pom.ExtractMinSdkVersion()
979*333d2b36SAndroid Build Coastguard Worker			if err != nil {
980*333d2b36SAndroid Build Coastguard Worker				fmt.Fprintf(os.Stderr, "Error reading manifest for %s: %s", pom.ArtifactFile, err)
981*333d2b36SAndroid Build Coastguard Worker				os.Exit(1)
982*333d2b36SAndroid Build Coastguard Worker			}
983*333d2b36SAndroid Build Coastguard Worker		}
984*333d2b36SAndroid Build Coastguard Worker		pom.FixDeps(modules)
985*333d2b36SAndroid Build Coastguard Worker		if pom2build {
986*333d2b36SAndroid Build Coastguard Worker			pom.GetBazelDepNames(modules)
987*333d2b36SAndroid Build Coastguard Worker		}
988*333d2b36SAndroid Build Coastguard Worker	}
989*333d2b36SAndroid Build Coastguard Worker
990*333d2b36SAndroid Build Coastguard Worker	buf := &bytes.Buffer{}
991*333d2b36SAndroid Build Coastguard Worker	commentString := "//"
992*333d2b36SAndroid Build Coastguard Worker	if pom2build {
993*333d2b36SAndroid Build Coastguard Worker		commentString = "#"
994*333d2b36SAndroid Build Coastguard Worker	}
995*333d2b36SAndroid Build Coastguard Worker
996*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintln(buf, commentString, "This is a generated file. Do not modify directly.")
997*333d2b36SAndroid Build Coastguard Worker
998*333d2b36SAndroid Build Coastguard Worker	if writeCmd {
999*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf, commentString, "Automatically generated with:")
1000*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf, commentString, "pom2bp", strings.Join(proptools.ShellEscapeList(os.Args[1:]), " "))
1001*333d2b36SAndroid Build Coastguard Worker	}
1002*333d2b36SAndroid Build Coastguard Worker
1003*333d2b36SAndroid Build Coastguard Worker	if prepend != "" {
1004*333d2b36SAndroid Build Coastguard Worker		contents, err := ioutil.ReadFile(prepend)
1005*333d2b36SAndroid Build Coastguard Worker		if err != nil {
1006*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, "Error reading", prepend, err)
1007*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
1008*333d2b36SAndroid Build Coastguard Worker		}
1009*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf, string(contents))
1010*333d2b36SAndroid Build Coastguard Worker	}
1011*333d2b36SAndroid Build Coastguard Worker
1012*333d2b36SAndroid Build Coastguard Worker	depsTemplate := bpDepsTemplate
1013*333d2b36SAndroid Build Coastguard Worker	template := bpTemplate
1014*333d2b36SAndroid Build Coastguard Worker	if pom2build {
1015*333d2b36SAndroid Build Coastguard Worker		depsTemplate = bazelDepsTemplate
1016*333d2b36SAndroid Build Coastguard Worker		template = bazelTemplate
1017*333d2b36SAndroid Build Coastguard Worker	}
1018*333d2b36SAndroid Build Coastguard Worker
1019*333d2b36SAndroid Build Coastguard Worker	for _, pom := range poms {
1020*333d2b36SAndroid Build Coastguard Worker		var err error
1021*333d2b36SAndroid Build Coastguard Worker		if staticDeps && !pom.IsApk() {
1022*333d2b36SAndroid Build Coastguard Worker			err = depsTemplate.Execute(buf, pom)
1023*333d2b36SAndroid Build Coastguard Worker		} else {
1024*333d2b36SAndroid Build Coastguard Worker			err = template.Execute(buf, pom)
1025*333d2b36SAndroid Build Coastguard Worker		}
1026*333d2b36SAndroid Build Coastguard Worker		if err != nil {
1027*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, "Error writing", pom.PomFile, pom.BpName(), err)
1028*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
1029*333d2b36SAndroid Build Coastguard Worker		}
1030*333d2b36SAndroid Build Coastguard Worker	}
1031*333d2b36SAndroid Build Coastguard Worker
1032*333d2b36SAndroid Build Coastguard Worker	if pom2build {
1033*333d2b36SAndroid Build Coastguard Worker		os.Stdout.WriteString(buf.String())
1034*333d2b36SAndroid Build Coastguard Worker	} else {
1035*333d2b36SAndroid Build Coastguard Worker		out, err := bpfix.Reformat(buf.String())
1036*333d2b36SAndroid Build Coastguard Worker		if err != nil {
1037*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintln(os.Stderr, "Error formatting output", err)
1038*333d2b36SAndroid Build Coastguard Worker			os.Exit(1)
1039*333d2b36SAndroid Build Coastguard Worker		}
1040*333d2b36SAndroid Build Coastguard Worker		os.Stdout.WriteString(out)
1041*333d2b36SAndroid Build Coastguard Worker	}
1042*333d2b36SAndroid Build Coastguard Worker
1043*333d2b36SAndroid Build Coastguard Worker}
1044