123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- 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) }
- }
|