commonroutesServer/www/platforms/android/CordovaLib/cordova.gradle
www/platforms/android/CordovaLib/cordova.gradleRaw
1/*
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18*/
19
20import java.util.regex.Pattern
21import groovy.swing.SwingBuilder
22
23String doEnsureValueExists(filePath, props, key) {
24 if (props.get(key) == null) {
25 throw new GradleException(filePath + ': Missing key required "' + key + '"')
26 }
27 return props.get(key)
28}
29
30String doGetProjectTarget() {
31 def props = new Properties()
32 file('project.properties').withReader { reader ->
33 props.load(reader)
34 }
35 return doEnsureValueExists('project.properties', props, 'target')
36}
37
38String[] getAvailableBuildTools() {
39 def buildToolsDir = new File(getAndroidSdkDir(), "build-tools")
40 buildToolsDir.list()
41 .findAll { it ==~ /[0-9.]+/ }
42 .sort { a, b -> compareVersions(b, a) }
43}
44
45String doFindLatestInstalledBuildTools(String minBuildToolsVersion) {
46 def availableBuildToolsVersions
47 try {
48 availableBuildToolsVersions = getAvailableBuildTools()
49 } catch (e) {
50 println "An exception occurred while trying to find the Android build tools."
51 throw e
52 }
53 if (availableBuildToolsVersions.length > 0) {
54 def highestBuildToolsVersion = availableBuildToolsVersions[0]
55 if (compareVersions(highestBuildToolsVersion, minBuildToolsVersion) < 0) {
56 throw new RuntimeException(
57 "No usable Android build tools found. Highest installed version is " +
58 highestBuildToolsVersion + "; minimum version required is " +
59 minBuildToolsVersion + ".")
60 }
61 highestBuildToolsVersion
62 } else {
63 throw new RuntimeException(
64 "No installed build tools found. Install the Android build tools version " +
65 minBuildToolsVersion + " or higher.")
66 }
67}
68
69// Return the first non-zero result of subtracting version list elements
70// pairwise. If they are all identical, return the difference in length of
71// the two lists.
72int compareVersionList(Collection aParts, Collection bParts) {
73 def pairs = ([aParts, bParts]).transpose()
74 pairs.findResult(aParts.size()-bParts.size()) {it[0] - it[1] != 0 ? it[0] - it[1] : null}
75}
76
77// Compare two version strings, such as "19.0.0" and "18.1.1.0". If all matched
78// elements are identical, the longer version is the largest by this method.
79// Examples:
80// "19.0.0" > "19"
81// "19.0.1" > "19.0.0"
82// "19.1.0" > "19.0.1"
83// "19" > "18.999.999"
84int compareVersions(String a, String b) {
85 def aParts = a.tokenize('.').collect {it.toInteger()}
86 def bParts = b.tokenize('.').collect {it.toInteger()}
87 compareVersionList(aParts, bParts)
88}
89
90String getAndroidSdkDir() {
91 def rootDir = project.rootDir
92 def androidSdkDir = null
93 String envVar = System.getenv("ANDROID_HOME")
94 def localProperties = new File(rootDir, 'local.properties')
95 String systemProperty = System.getProperty("android.home")
96 if (envVar != null) {
97 androidSdkDir = envVar
98 } else if (localProperties.exists()) {
99 Properties properties = new Properties()
100 localProperties.withInputStream { instr ->
101 properties.load(instr)
102 }
103 def sdkDirProp = properties.getProperty('sdk.dir')
104 if (sdkDirProp != null) {
105 androidSdkDir = sdkDirProp
106 } else {
107 sdkDirProp = properties.getProperty('android.dir')
108 if (sdkDirProp != null) {
109 androidSdkDir = (new File(rootDir, sdkDirProp)).getAbsolutePath()
110 }
111 }
112 }
113 if (androidSdkDir == null && systemProperty != null) {
114 androidSdkDir = systemProperty
115 }
116 if (androidSdkDir == null) {
117 throw new RuntimeException(
118 "Unable to determine Android SDK directory.")
119 }
120 androidSdkDir
121}
122
123def doExtractIntFromManifest(name) {
124 def manifestFile = file(android.sourceSets.main.manifest.srcFile)
125 def pattern = Pattern.compile(name + "=\"(\\d+)\"")
126 def matcher = pattern.matcher(manifestFile.getText())
127 matcher.find()
128 return Integer.parseInt(matcher.group(1))
129}
130
131def doExtractStringFromManifest(name) {
132 def manifestFile = file(android.sourceSets.main.manifest.srcFile)
133 def pattern = Pattern.compile(name + "=\"(\\S+)\"")
134 def matcher = pattern.matcher(manifestFile.getText())
135 matcher.find()
136 return matcher.group(1)
137}
138
139def doPromptForPassword(msg) {
140 if (System.console() == null) {
141 def ret = null
142 new SwingBuilder().edt {
143 dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
144 vbox {
145 label(text: msg)
146 def input = passwordField()
147 button(defaultButton: true, text: 'OK', actionPerformed: {
148 ret = input.password;
149 dispose();
150 })
151 }
152 }
153 }
154 if (!ret) {
155 throw new GradleException('User canceled build')
156 }
157 return new String(ret)
158 } else {
159 return System.console().readPassword('\n' + msg);
160 }
161}
162
163def doGetConfigXml() {
164 def xml = file("res/xml/config.xml").getText()
165 // Disable namespace awareness since Cordova doesn't use them properly
166 return new XmlParser(false, false).parseText(xml)
167}
168
169def doGetConfigPreference(name, defaultValue) {
170 name = name.toLowerCase()
171 def root = doGetConfigXml()
172
173 def ret = defaultValue
174 root.preference.each { it ->
175 def attrName = it.attribute("name")
176 if (attrName && attrName.toLowerCase() == name) {
177 ret = it.attribute("value")
178 }
179 }
180 return ret
181}
182
183// Properties exported here are visible to all plugins.
184ext {
185 // These helpers are shared, but are not guaranteed to be stable / unchanged.
186 privateHelpers = {}
187 privateHelpers.getProjectTarget = { doGetProjectTarget() }
188 privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') }
189 privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
190 privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
191 privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) }
192 privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
193
194 // These helpers can be used by plugins / projects and will not change.
195 cdvHelpers = {}
196 // Returns a XmlParser for the config.xml. Added in 4.1.0.
197 cdvHelpers.getConfigXml = { doGetConfigXml() }
198 // Returns the value for the desired <preference>. Added in 4.1.0.
199 cdvHelpers.getConfigPreference = { name, defaultValue -> doGetConfigPreference(name, defaultValue) }
200}
201