-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathembedded_gradle.go
More file actions
227 lines (190 loc) · 8.01 KB
/
embedded_gradle.go
File metadata and controls
227 lines (190 loc) · 8.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY
package main
const gradleInitScript = `// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import groovy.json.*;
allprojects {
// Add the extract task only to the project in the current directory.
if (project.projectDir == gradle.startParameter.currentDir) {
task madbExtractVariantProperties << {
extract(project)
}
}
}
// Main driver of the property extraction script.
void extract(project) {
project = getApplicationModule(project)
if (project == null) {
def errMsg = 'The current project is not an Android application module, '
+ 'nor does it contain any application sub-modules. '
+ 'Please run the madb command from an Android application project directory.'
throw new GradleException(errMsg)
}
// Get the target variant.
def targetVariant = getTargetVariant(project)
// Collect the variant properties in a map, so that it can be printed out as a JSON.
def result = [
ProjectPath: project.path,
VariantName: targetVariant.name,
CleanTask: project.path + ":clean",
AssembleTask: targetVariant.assemble.path,
AppID: getApplicationId(project, targetVariant),
Activity: getMainActivity(project),
AbiFilters: getAbiFilters(targetVariant),
VariantOutputs: getVariantOutputs(targetVariant)
]
// Format the resulting map into JSON and print it.
def resultJson = JsonOutput.prettyPrint(JsonOutput.toJson(result))
printResult(project, resultJson)
}
// Prints the given result to the desired output stream.
// If the output file is specified, write the result to the file.
// Otherwise, print it out to the console.
void printResult(project, result) {
// An optional output file name can be specified by a Gradle command-line flag:
// -PmadbOutputFile=<file_name>
def output = project.properties.containsKey('madbOutputFile')
? new File(project.properties['madbOutputFile'])
: null
if (output != null) {
// Empty the file, and then print the result.
output.text = ''
output.append(result)
} else {
println result
}
}
// Returns an Android application module from the given project.
// The given project is returned immediately, if itself is an application module.
// Otherwise, the first available application sub-module is returned, if any.
// Returns null if no Android application modules were found from the given project.
Object getApplicationModule(project) {
if (isApplicationModule(project)) {
return project
}
def subApplicationModules = project.subprojects.findAll { isApplicationModule(it) }
if (subApplicationModules.isEmpty()) {
return null
}
def result = subApplicationModules.first()
if (subApplicationModules.size() > 1) {
print 'Multiple application sub-modules were detected. '
println 'The first application module "' + result.name + '" is chosen automatically.'
println '(NOTE: Application module can be explicitly specified using -module=<name> flag.)'
}
return result
}
// Returns true iff the given project is an Android application.
boolean isApplicationModule(project) {
return project.plugins.hasPlugin('com.android.application')
}
// Returns the target application variant for the project.
// If the 'madbVariant' property was explicitly set from the command line, the
// matching variant is returned.
// If there is no variant with the provided name, it throws an exception.
//
// If the 'madbVariant' property is not provided, the first available variant is
// returned. Usually the first available variant would be 'debug'.
Object getTargetVariant(project) {
def allVariants = project.android.applicationVariants
if (project.properties.containsKey('madbVariant')) {
def variantName = project.properties['madbVariant']
def targetVariant = allVariants.find { variantName.equalsIgnoreCase(it.name) }
if (targetVariant == null) {
throw new GradleException('Variant "' + variantName + '" is not found.')
}
return targetVariant
} else {
def targetVariant = allVariants.iterator().next()
print 'Build variant not specified. '
println 'The first variant "' + targetVariant.name + '" is chosen automatically.'
println '(NOTE: Variant can be explicitly specified using -variant=<name> flag.)'
return targetVariant
}
}
// Returns the application ID for the given variant.
String getApplicationId(project, variant) {
def suffix = variant.buildType.applicationIdSuffix
if (suffix == null) {
suffix = ""
}
def appId = variant.mergedFlavor.applicationId
// Fall back to AndroidManifest.xml if the applicationId is not explicitly defined.
// See the bottom notes at:
// http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename
if (appId == null) {
appId = getApplicationIdFromManifest(project)
}
return appId + suffix
}
// Returns the application ID extracted from the AndroidManifest.xml file.
String getApplicationIdFromManifest(project) {
def manifestFile = getAndroidManifestLocation(project)
// Parse the xml file and find the package name.
def manifest = new XmlSlurper().parse(manifestFile)
return manifest.'@package'.text()
}
String getMainActivity(project) {
def manifestFile = getAndroidManifestLocation(project)
// Parse the xml file and find the main activity.
def manifest = new XmlSlurper().parse(manifestFile)
def mainActivity = manifest.application.activity.find { isMainActivity(it) }
def name = mainActivity.'@android:name'.text()
// If the activity name is using the shorthand syntax starting with a dot,
// make it a fully-qualified name by prepending it with the package name.
if (name.startsWith('.')) {
return manifest.'@package'.text() + name
} else {
return name
}
}
// Returns the location of the "AndroidManifest.xml" file.
// TODO(youngseokyoon): investigate whether we can obtain the merged manifest.
File getAndroidManifestLocation(project) {
try {
return project.android.sourceSets.main.manifest.srcFile
} catch (all) {
return null
}
}
// Determines whether the given activity is the main activity or not.
boolean isMainActivity(activity) {
try {
def intentFilter = activity.'intent-filter'
return intentFilter.action.'@android:name'.text() == 'android.intent.action.MAIN' &&
intentFilter.category.'@android:name'.text() == 'android.intent.category.LAUNCHER'
} catch (all) {
return false
}
}
// Returns the list of supported ABIs for the given variant.
// Returns null if there are no ABI filters specified.
Object getAbiFilters(variant) {
return variant.variantData.variantConfiguration.supportedAbis
}
// Gets the outputs and their properties of the given variant.
// The returned object is a list of variant outputs, each of which is a map containing the
// properties of a variant output, such as the absolute path of the .apk file, and its filters.
Object getVariantOutputs(variant) {
def variantOutputs = []
for (def variantOutput : variant.outputs) {
def filters = []
for (def filter : variantOutput.mainOutputFile.filters) {
filters.add([FilterType: filter.filterType, Identifier: filter.identifier])
}
def result = [
Name: variantOutput.name,
OutputFilePath: variantOutput.mainOutputFile.outputFile.absolutePath,
VersionCode: variantOutput.versionCode,
Filters: filters
]
variantOutputs.add(result)
}
return variantOutputs
}
`