CB-8255 Use properties rather than environment variables for gradle settings

This commit is contained in:
Andrew Grieve 2015-01-06 15:56:09 -05:00
parent c1ac3aa483
commit c3610aa43c
6 changed files with 139 additions and 85 deletions

View File

@ -174,7 +174,7 @@ var builders = {
}
},
gradle: {
getArgs: function(cmd, arch) {
getArgs: function(cmd, arch, extraArgs) {
if (arch == 'arm' && cmd == 'debug') {
cmd = 'assembleArmv7Debug';
} else if (arch == 'arm' && cmd == 'release') {
@ -191,6 +191,7 @@ var builders = {
var args = [cmd, '-b', path.join(ROOT, 'build.gradle')];
// 10 seconds -> 6 seconds
args.push('-Dorg.gradle.daemon=true');
args.push.apply(args, extraArgs);
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
// args.push('-Dorg.gradle.parallel=true');
return args;
@ -254,20 +255,22 @@ var builders = {
* Builds the project with gradle.
* Returns a promise.
*/
build: function(build_type, arch) {
build: function(build_type, arch, extraArgs) {
var builder = this;
var wrapper = path.join(ROOT, 'gradlew');
var args = this.getArgs(build_type == 'debug' ? 'debug' : 'release', arch);
var args = this.getArgs(build_type == 'debug' ? 'debug' : 'release', arch, extraArgs);
return Q().then(function() {
console.log('Running: ' + wrapper + ' ' + extraArgs.join(' '));
return spawn(wrapper, args);
});
},
clean: function() {
clean: function(extraArgs) {
var builder = this;
var wrapper = path.join(ROOT, 'gradlew');
var args = builder.getArgs('clean');
var args = builder.getArgs('clean', null, extraArgs);
return Q().then(function() {
console.log('Running: ' + wrapper + ' ' + extraArgs.join(' '));
return spawn(wrapper, args);
});
},
@ -302,7 +305,14 @@ function parseOpts(options, resolvedTarget) {
var ret = {
buildType: 'debug',
buildMethod: process.env['ANDROID_BUILD'] || 'ant',
arch: null
arch: null,
extraArgs: []
};
var multiValueArgs = {
'versionCode': true,
'minSdkVersion': true,
'gradleArg': true
};
// Iterate through command line options
@ -311,7 +321,7 @@ function parseOpts(options, resolvedTarget) {
var keyValue = options[i].substring(2).split('=');
var flagName = keyValue[0];
var flagValue = keyValue[1];
if ((flagName == 'versionCode' || flagName == 'minSdkVersion') && !flagValue) {
if (multiValueArgs[flagName] && !flagValue) {
flagValue = options[i + 1];
++i;
}
@ -333,10 +343,13 @@ function parseOpts(options, resolvedTarget) {
ret.buildMethod = 'none';
break;
case 'versionCode':
process.env['ANDROID_VERSION_CODE'] = flagValue;
ret.extraArgs.push('-PcdvVersionCode=' + flagValue);
break;
case 'minSdkVersion':
process.env['ANDROID_MIN_SDK_VERSION'] = flagValue;
ret.extraArgs.push('-PcdvMinSdkVersion=' + flagValue);
break;
case 'gradleArg':
ret.extraArgs.push(flagValue);
break;
default :
console.warn('Build option --\'' + flagName + '\' not recognized (ignoring).');
@ -363,7 +376,7 @@ module.exports.runClean = function(options) {
var builder = builders[opts.buildMethod];
return builder.prepEnv()
.then(function() {
return builder.clean();
return builder.clean(opts.extraArgs);
}).then(function() {
shell.rm('-rf', path.join(ROOT, 'out'));
});
@ -378,7 +391,7 @@ module.exports.run = function(options, optResolvedTarget) {
var builder = builders[opts.buildMethod];
return builder.prepEnv()
.then(function() {
return builder.build(opts.buildType, opts.arch);
return builder.build(opts.buildType, opts.arch, opts.extraArgs);
}).then(function() {
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
console.log('Built the following apk(s):');
@ -468,5 +481,6 @@ module.exports.help = function() {
console.log(' \'--nobuild\': will skip build process (useful when using run command)');
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs. Requires --gradle.');
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build. Useful for uploading multiple APKs. Requires --gradle.');
console.log(' \'--gradleArg=<gradle command line arg>\': Extra args to pass to the gradle command. Use one flag per arg. Ex. --gradleArg=-PcdvBuildMultipleApks=true');
process.exit(0);
};

View File

@ -51,8 +51,8 @@ dependencies {
}
android {
compileSdkVersion cordova.cordovaSdkVersion
buildToolsVersion cordova.cordovaBuildToolsVersion
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
publishNonDefault true
compileOptions {

View File

@ -39,23 +39,18 @@ var path = require('path'),
var list = false;
for (var i=2; i<args.length; i++) {
if (args[i] == '--debug') {
buildFlags.push('--debug');
} else if (args[i] == '--release') {
buildFlags.push('--release');
} else if (args[i] == '--nobuild') {
buildFlags.push('--nobuild');
if (/^--(debug|release|nobuild|versionCode=|minSdkVersion=|gradleArg=)/.exec(args[i])) {
buildFlags.push(args[i]);
} else if (args[i] == '--device') {
install_target = '--device';
} else if (args[i] == '--emulator') {
install_target = '--emulator';
} else if (args[i].substring(0, 9) == '--target=') {
} else if (/^--target=/.exec(args[i])) {
install_target = args[i].substring(9, args[i].length);
} else if (args[i] == '--list') {
list = true;
} else {
console.error('ERROR : Run option \'' + args[i] + '\' not recognized.');
process.exit(2);
console.warn('Option \'' + options[i] + '\' not recognized (ignoring).');
}
}

View File

@ -19,11 +19,6 @@
// GENERATED FILE! DO NOT EDIT!
import java.util.regex.Pattern
import groovy.swing.SwingBuilder
ext.cordova = {}
apply from: 'cordova.gradle', to: ext.cordova
apply plugin: 'android'
buildscript {
@ -59,7 +54,44 @@ task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
ext.multiarch=false
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
// Refer to: http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html
ext {
apply from: 'cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
cdvCompileSdkVersion = privateHelpers.getProjectTarget('android-19')
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools('19.1.0')
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = false
}
// .properties files to use for release signing.
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
cdvReleaseSigningPropertiesFile = null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
}
def hasBuildExtras = file('build-extras.gradle').exists()
if (hasBuildExtras) {
apply from: 'build-extras.gradle'
}
// PLUGIN GRADLE EXTENSIONS START
// PLUGIN GRADLE EXTENSIONS END
@ -77,26 +109,29 @@ android {
}
}
def versionCodeOverride = cdvVersionCode ? Integer.parseInt(cdvVersionCode) : null
def minSdkVersionOverride = cdvMinSdkVersion ? Integer.parseInt(cdvMinSdkVersion) : null
defaultConfig {
versionCode Integer.parseInt(System.env.ANDROID_VERSION_CODE ?: ("" + getIntFromManifest("versionCode") + "0"))
if (System.env.ANDROID_MIN_SDK_VERSION) {
minSdkVersion Integer.parseInt(System.env.ANDROID_MIN_SDK_VERSION)
versionCode versionCodeOverride ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0")
if (minSdkVersionOverride != null) {
minSdkVersion minSdkVersionOverride
}
}
compileSdkVersion cordova.cordovaSdkVersion
buildToolsVersion cordova.cordovaBuildToolsVersion
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
if (multiarch || System.env.BUILD_MULTIPLE_APKS) {
if (Boolean.valueOf(cdvBuildMultipleApks)) {
productFlavors {
armv7 {
versionCode System.env.ANDROID_VERSION_CODE ?: defaultConfig.versionCode + 2
versionCode versionCodeOverride ?: defaultConfig.versionCode + 2
ndk {
abiFilters "armeabi-v7a", ""
}
}
x86 {
versionCode System.env.ANDROID_VERSION_CODE ?: defaultConfig.versionCode + 4
versionCode versionCodeOverride ?: defaultConfig.versionCode + 4
ndk {
abiFilters "x86", ""
}
@ -107,8 +142,8 @@ android {
}
}
}
} else if (!System.env.ANDROID_VERSION_CODE) {
def minSdkVersion = Integer.parseInt(System.env.ANDROID_MIN_SDK_VERSION ?: "" + getIntFromManifest("minSdkVersion"))
} else if (!versionCodeOverride) {
def minSdkVersion = minSdkVersionOverride ?: privateHelpers.extractIntFromManifest("minSdkVersion")
// Vary versionCode by the two most common API levels:
// 14 is ICS, which is the lowest API level for many apps.
// 20 is Lollipop, which is the lowest API level for the updatable system webview.
@ -124,7 +159,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_6
}
if (System.env.RELEASE_SIGNING_PROPERTIES_FILE) {
if (cdvReleaseSigningPropertiesFile) {
signingConfigs {
release {
// These must be set or Gradle will complain (even if they are overridden).
@ -139,10 +174,10 @@ android {
signingConfig signingConfigs.release
}
}
addSigningProps(System.env.RELEASE_SIGNING_PROPERTIES_FILE, signingConfigs.release)
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
}
if (System.env.DEBUG_SIGNING_PROPERTIES_FILE) {
addSigningProps(System.env.DEBUG_SIGNING_PROPERTIES_FILE, signingConfigs.debug)
if (cdvDebugSigningPropertiesFile) {
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
}
}
@ -152,40 +187,15 @@ dependencies {
// SUB-PROJECT DEPENDENCIES END
}
def promptForPassword(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 promptForReleaseKeyPassword() {
if (!System.env.RELEASE_SIGNING_PROPERTIES_FILE) {
if (!cdvReleaseSigningPropertiesFile) {
return;
}
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
android.signingConfigs.release.storePassword = promptForPassword('Enter key store password: ')
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
}
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
android.signingConfigs.release.keyPassword = promptForPassword('Enter key password: ');
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
}
}
@ -197,14 +207,6 @@ gradle.taskGraph.whenReady { taskGraph ->
}
}
def getIntFromManifest(name) {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile(name + "=\"(\\d+)\"")
def matcher = pattern.matcher(manifestFile.getText())
matcher.find()
return Integer.parseInt(matcher.group(1))
}
def ensureValueExists(filePath, props, key) {
if (props.get(key) == null) {
throw new GradleException(filePath + ': Missing key required "' + key + '"')
@ -241,6 +243,8 @@ def addSigningProps(propsFilePath, signingConfig) {
}
}
if (file('build-extras.gradle').exists()) {
apply from: 'build-extras.gradle'
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}

View File

@ -18,6 +18,8 @@
*/
import java.util.regex.Pattern
import groovy.swing.SwingBuilder
String getProjectTarget(String defaultTarget) {
def manifestFile = file("project.properties")
@ -37,7 +39,7 @@ String[] getAvailableBuildTools() {
.sort { a, b -> compareVersions(b, a) }
}
String latestBuildToolsAvailable(String minBuildToolsVersion) {
String findLatestInstalledBuildTools(String minBuildToolsVersion) {
def availableBuildToolsVersions
try {
availableBuildToolsVersions = getAvailableBuildTools()
@ -115,6 +117,45 @@ String getAndroidSdkDir() {
androidSdkDir
}
ext.cordovaSdkVersion = System.env.MIN_SDK_VERSION ?: getProjectTarget("android-19")
ext.cordovaBuildToolsVersion = latestBuildToolsAvailable("19.1.0")
def extractIntFromManifest(name) {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile(name + "=\"(\\d+)\"")
def matcher = pattern.matcher(manifestFile.getText())
matcher.find()
return Integer.parseInt(matcher.group(1))
}
def promptForPassword(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);
}
}
// Properties exported here are visible to all plugins.
ext {
// These helpers are shared, but are not guaranteed to be stable / unchanged.
privateHelpers = {}
privateHelpers.getProjectTarget = { defaultValue -> getProjectTarget(defaultValue) }
privateHelpers.findLatestInstalledBuildTools = { defaultValue -> findLatestInstalledBuildTools(defaultValue) }
privateHelpers.extractIntFromManifest = { name -> extractIntFromManifest(name) }
privateHelpers.promptForPassword = { msg -> promptForPassword(msg) }
}

View File

@ -47,8 +47,8 @@ buildscript {
apply plugin: 'android-library'
android {
compileSdkVersion cordova.cordovaSdkVersion
buildToolsVersion cordova.cordovaBuildToolsVersion
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
publishNonDefault true
compileOptions {