205 lines
7.5 KiB
Groovy
205 lines
7.5 KiB
Groovy
/*
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
*/
|
|
|
|
import java.util.regex.Pattern
|
|
import groovy.swing.SwingBuilder
|
|
|
|
String doEnsureValueExists(filePath, props, key) {
|
|
if (props.get(key) == null) {
|
|
throw new GradleException(filePath + ': Missing key required "' + key + '"')
|
|
}
|
|
return props.get(key)
|
|
}
|
|
|
|
String doGetProjectTarget() {
|
|
def props = new Properties()
|
|
def propertiesFile = 'project.properties';
|
|
if(!(file(propertiesFile).exists())) {
|
|
propertiesFile = '../project.properties';
|
|
}
|
|
file(propertiesFile).withReader { reader ->
|
|
props.load(reader)
|
|
}
|
|
return doEnsureValueExists('project.properties', props, 'target')
|
|
}
|
|
|
|
String[] getAvailableBuildTools() {
|
|
def buildToolsDir = new File(getAndroidSdkDir(), "build-tools")
|
|
buildToolsDir.list()
|
|
.findAll { it ==~ /[0-9.]+/ }
|
|
.sort { a, b -> compareVersions(b, a) }
|
|
}
|
|
|
|
String doFindLatestInstalledBuildTools(String minBuildToolsVersion) {
|
|
def availableBuildToolsVersions
|
|
try {
|
|
availableBuildToolsVersions = getAvailableBuildTools()
|
|
} catch (e) {
|
|
println "An exception occurred while trying to find the Android build tools."
|
|
throw e
|
|
}
|
|
if (availableBuildToolsVersions.length > 0) {
|
|
def highestBuildToolsVersion = availableBuildToolsVersions[0]
|
|
if (compareVersions(highestBuildToolsVersion, minBuildToolsVersion) < 0) {
|
|
throw new RuntimeException(
|
|
"No usable Android build tools found. Highest installed version is " +
|
|
highestBuildToolsVersion + "; minimum version required is " +
|
|
minBuildToolsVersion + ".")
|
|
}
|
|
highestBuildToolsVersion
|
|
} else {
|
|
throw new RuntimeException(
|
|
"No installed build tools found. Install the Android build tools version " +
|
|
minBuildToolsVersion + " or higher.")
|
|
}
|
|
}
|
|
|
|
// Return the first non-zero result of subtracting version list elements
|
|
// pairwise. If they are all identical, return the difference in length of
|
|
// the two lists.
|
|
int compareVersionList(Collection aParts, Collection bParts) {
|
|
def pairs = ([aParts, bParts]).transpose()
|
|
pairs.findResult(aParts.size()-bParts.size()) {it[0] - it[1] != 0 ? it[0] - it[1] : null}
|
|
}
|
|
|
|
// Compare two version strings, such as "19.0.0" and "18.1.1.0". If all matched
|
|
// elements are identical, the longer version is the largest by this method.
|
|
// Examples:
|
|
// "19.0.0" > "19"
|
|
// "19.0.1" > "19.0.0"
|
|
// "19.1.0" > "19.0.1"
|
|
// "19" > "18.999.999"
|
|
int compareVersions(String a, String b) {
|
|
def aParts = a.tokenize('.').collect {it.toInteger()}
|
|
def bParts = b.tokenize('.').collect {it.toInteger()}
|
|
compareVersionList(aParts, bParts)
|
|
}
|
|
|
|
String getAndroidSdkDir() {
|
|
def rootDir = project.rootDir
|
|
def androidSdkDir = null
|
|
String envVar = System.getenv("ANDROID_HOME")
|
|
def localProperties = new File(rootDir, 'local.properties')
|
|
String systemProperty = System.getProperty("android.home")
|
|
if (envVar != null) {
|
|
androidSdkDir = envVar
|
|
} else if (localProperties.exists()) {
|
|
Properties properties = new Properties()
|
|
localProperties.withInputStream { instr ->
|
|
properties.load(instr)
|
|
}
|
|
def sdkDirProp = properties.getProperty('sdk.dir')
|
|
if (sdkDirProp != null) {
|
|
androidSdkDir = sdkDirProp
|
|
} else {
|
|
sdkDirProp = properties.getProperty('android.dir')
|
|
if (sdkDirProp != null) {
|
|
androidSdkDir = (new File(rootDir, sdkDirProp)).getAbsolutePath()
|
|
}
|
|
}
|
|
}
|
|
if (androidSdkDir == null && systemProperty != null) {
|
|
androidSdkDir = systemProperty
|
|
}
|
|
if (androidSdkDir == null) {
|
|
throw new RuntimeException(
|
|
"Unable to determine Android SDK directory.")
|
|
}
|
|
androidSdkDir
|
|
}
|
|
|
|
def doExtractIntFromManifest(name) {
|
|
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
|
|
def pattern = Pattern.compile(name + "=\"(\\d+)\"")
|
|
def matcher = pattern.matcher(manifestFile.getText())
|
|
matcher.find()
|
|
return new BigInteger(matcher.group(1))
|
|
}
|
|
|
|
def doExtractStringFromManifest(name) {
|
|
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
|
|
def pattern = Pattern.compile(name + "=\"(\\S+)\"")
|
|
def matcher = pattern.matcher(manifestFile.getText())
|
|
matcher.find()
|
|
return matcher.group(1)
|
|
}
|
|
|
|
def doPromptForPassword(msg) {
|
|
if (System.console() == null) {
|
|
def ret = null
|
|
new SwingBuilder().edt {
|
|
dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
|
|
vbox {
|
|
label(text: msg)
|
|
def input = passwordField()
|
|
button(defaultButton: true, text: 'OK', actionPerformed: {
|
|
ret = input.password;
|
|
dispose();
|
|
})
|
|
}
|
|
}
|
|
}
|
|
if (!ret) {
|
|
throw new GradleException('User canceled build')
|
|
}
|
|
return new String(ret)
|
|
} else {
|
|
return System.console().readPassword('\n' + msg);
|
|
}
|
|
}
|
|
|
|
def doGetConfigXml() {
|
|
def xml = file("src/main/res/xml/config.xml").getText()
|
|
// Disable namespace awareness since Cordova doesn't use them properly
|
|
return new XmlParser(false, false).parseText(xml)
|
|
}
|
|
|
|
def doGetConfigPreference(name, defaultValue) {
|
|
name = name.toLowerCase()
|
|
def root = doGetConfigXml()
|
|
|
|
def ret = defaultValue
|
|
root.preference.each { it ->
|
|
def attrName = it.attribute("name")
|
|
if (attrName && attrName.toLowerCase() == name) {
|
|
ret = it.attribute("value")
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// Properties exported here are visible to all plugins.
|
|
ext {
|
|
// These helpers are shared, but are not guaranteed to be stable / unchanged.
|
|
privateHelpers = {}
|
|
privateHelpers.getProjectTarget = { doGetProjectTarget() }
|
|
privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
|
|
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
|
|
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
|
|
privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
|
|
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
|
|
|
|
// These helpers can be used by plugins / projects and will not change.
|
|
cdvHelpers = {}
|
|
// Returns a XmlParser for the config.xml. Added in 4.1.0.
|
|
cdvHelpers.getConfigXml = { doGetConfigXml() }
|
|
// Returns the value for the desired <preference>. Added in 4.1.0.
|
|
cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
|
|
}
|
|
|