mirror of
https://github.com/apache/cordova-android.git
synced 2025-04-22 08:36:25 +08:00
Merge pull request #389 from infil00p/StudioProjectCompat
CB-11244: Studio Project Compatibility: Now with merge commit
This commit is contained in:
commit
59018ab632
@ -26,9 +26,10 @@ var fs = require('fs');
|
|||||||
var check_reqs = require('./../templates/cordova/lib/check_reqs');
|
var check_reqs = require('./../templates/cordova/lib/check_reqs');
|
||||||
var ROOT = path.join(__dirname, '..', '..');
|
var ROOT = path.join(__dirname, '..', '..');
|
||||||
|
|
||||||
var MIN_SDK_VERSION = 16;
|
var MIN_SDK_VERSION = 19;
|
||||||
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
var AndroidStudio = require('../templates/cordova/lib/AndroidStudio');
|
||||||
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
||||||
|
|
||||||
// Export all helper functions, and make sure internally within this module, we
|
// Export all helper functions, and make sure internally within this module, we
|
||||||
@ -54,10 +55,16 @@ function getFrameworkDir (projectPath, shared) {
|
|||||||
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyJsAndLibrary (projectPath, shared, projectName) {
|
function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
|
||||||
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
||||||
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
|
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
|
||||||
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'assets', 'www', 'cordova.js'));
|
var app_path = path.join(projectPath, 'app', 'src', 'main');
|
||||||
|
|
||||||
|
if (isLegacy) {
|
||||||
|
app_path = projectPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell.cp('-f', srcCordovaJsPath, path.join(app_path, 'assets', 'www', 'cordova.js'));
|
||||||
|
|
||||||
// Copy the cordova.js file to platforms/<platform>/platform_www/
|
// Copy the cordova.js file to platforms/<platform>/platform_www/
|
||||||
// The www dir is nuked on each prepare so we keep cordova.js in platform_www
|
// The www dir is nuked on each prepare so we keep cordova.js in platform_www
|
||||||
@ -70,7 +77,7 @@ function copyJsAndLibrary (projectPath, shared, projectName) {
|
|||||||
|
|
||||||
// Don't fail if there are no old jars.
|
// Don't fail if there are no old jars.
|
||||||
exports.setShellFatal(false, function () {
|
exports.setShellFatal(false, function () {
|
||||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
shell.ls(path.join(app_path, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
||||||
console.log('Deleting ' + oldJar);
|
console.log('Deleting ' + oldJar);
|
||||||
shell.rm('-f', oldJar);
|
shell.rm('-f', oldJar);
|
||||||
});
|
});
|
||||||
@ -136,16 +143,24 @@ function writeProjectProperties (projectPath, target_api) {
|
|||||||
fs.writeFileSync(dstPath, data);
|
fs.writeFileSync(dstPath, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepBuildFiles (projectPath) {
|
// This makes no sense, what if you're building with a different build system?
|
||||||
|
function prepBuildFiles (projectPath, builder) {
|
||||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||||
buildModule.getBuilder('gradle').prepBuildFiles();
|
buildModule.getBuilder(builder).prepBuildFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyBuildRules (projectPath) {
|
function copyBuildRules (projectPath, isLegacy) {
|
||||||
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
||||||
|
|
||||||
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
if (isLegacy) {
|
||||||
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
// The project's build.gradle is identical to the earlier build.gradle, so it should still work
|
||||||
|
shell.cp('-f', path.join(srcDir, 'legacy', 'build.gradle'), projectPath);
|
||||||
|
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
||||||
|
} else {
|
||||||
|
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
||||||
|
shell.cp('-f', path.join(srcDir, 'app', 'build.gradle'), path.join(projectPath, 'app'));
|
||||||
|
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyScripts (projectPath) {
|
function copyScripts (projectPath) {
|
||||||
@ -271,25 +286,37 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
|
|
||||||
exports.setShellFatal(true, function () {
|
exports.setShellFatal(true, function () {
|
||||||
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
||||||
|
var app_path = path.join(project_path, 'app', 'src', 'main');
|
||||||
|
|
||||||
// copy project template
|
// copy project template
|
||||||
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
|
shell.mkdir('-p', app_path);
|
||||||
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
|
shell.cp('-r', path.join(project_template_dir, 'assets'), app_path);
|
||||||
|
shell.cp('-r', path.join(project_template_dir, 'res'), app_path);
|
||||||
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
||||||
|
|
||||||
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
||||||
shell.mkdir(path.join(project_path, 'libs'));
|
shell.mkdir(path.join(app_path, 'libs'));
|
||||||
|
|
||||||
// copy cordova.js, cordova.jar
|
// copy cordova.js, cordova.jar
|
||||||
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
||||||
|
|
||||||
|
// Set up ther Android Studio paths
|
||||||
|
var java_path = path.join(app_path, 'java');
|
||||||
|
var assets_path = path.join(app_path, 'assets');
|
||||||
|
var resource_path = path.join(app_path, 'res');
|
||||||
|
shell.mkdir('-p', java_path);
|
||||||
|
shell.mkdir('-p', assets_path);
|
||||||
|
shell.mkdir('-p', resource_path);
|
||||||
|
|
||||||
// interpolate the activity name and package
|
// interpolate the activity name and package
|
||||||
var packagePath = package_name.replace(/\./g, path.sep);
|
var packagePath = package_name.replace(/\./g, path.sep);
|
||||||
var activity_dir = path.join(project_path, 'src', packagePath);
|
var activity_dir = path.join(java_path, packagePath);
|
||||||
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
||||||
|
|
||||||
shell.mkdir('-p', activity_dir);
|
shell.mkdir('-p', activity_dir);
|
||||||
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
||||||
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
||||||
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
|
shell.sed('-i', /__NAME__/, project_name, path.join(app_path, 'res', 'values', 'strings.xml'));
|
||||||
shell.sed('-i', /__ID__/, package_name, activity_path);
|
shell.sed('-i', /__ID__/, package_name, activity_path);
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
||||||
@ -297,7 +324,7 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
.setTargetSdkVersion(target_api.split('-')[1])
|
.setTargetSdkVersion(target_api.split('-')[1])
|
||||||
.getActivity().setName(safe_activity_name);
|
.getActivity().setName(safe_activity_name);
|
||||||
|
|
||||||
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
|
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
|
||||||
manifest.write(manifest_path);
|
manifest.write(manifest_path);
|
||||||
|
|
||||||
exports.copyScripts(project_path);
|
exports.copyScripts(project_path);
|
||||||
@ -305,7 +332,7 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
});
|
});
|
||||||
// Link it to local android install.
|
// Link it to local android install.
|
||||||
exports.writeProjectProperties(project_path, target_api);
|
exports.writeProjectProperties(project_path, target_api);
|
||||||
exports.prepBuildFiles(project_path);
|
exports.prepBuildFiles(project_path, 'studio');
|
||||||
events.emit('log', generateDoneMessage('create', options.link));
|
events.emit('log', generateDoneMessage('create', options.link));
|
||||||
}).thenResolve(project_path);
|
}).thenResolve(project_path);
|
||||||
};
|
};
|
||||||
@ -326,7 +353,18 @@ exports.update = function (projectPath, options, events) {
|
|||||||
return Q()
|
return Q()
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
|
var isAndroidStudio = AndroidStudio.isAndroidStudioProject(projectPath);
|
||||||
|
var isLegacy = !isAndroidStudio;
|
||||||
|
var manifest = null;
|
||||||
|
var builder = 'gradle';
|
||||||
|
|
||||||
|
if (isAndroidStudio) {
|
||||||
|
manifest = new AndroidManifest(path.join(projectPath, 'app', 'main', 'AndroidManifest.xml'));
|
||||||
|
builder = 'studio';
|
||||||
|
} else {
|
||||||
|
manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
|
||||||
|
builder = 'gradle';
|
||||||
|
}
|
||||||
|
|
||||||
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
|
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
|
||||||
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
|
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
|
||||||
@ -338,11 +376,11 @@ exports.update = function (projectPath, options, events) {
|
|||||||
var projectName = manifest.getActivity().getName();
|
var projectName = manifest.getActivity().getName();
|
||||||
var target_api = check_reqs.get_target();
|
var target_api = check_reqs.get_target();
|
||||||
|
|
||||||
exports.copyJsAndLibrary(projectPath, options.link, projectName);
|
exports.copyJsAndLibrary(projectPath, options.link, projectName, isLegacy);
|
||||||
exports.copyScripts(projectPath);
|
exports.copyScripts(projectPath);
|
||||||
exports.copyBuildRules(projectPath);
|
exports.copyBuildRules(projectPath, isLegacy);
|
||||||
exports.writeProjectProperties(projectPath, target_api);
|
exports.writeProjectProperties(projectPath, target_api);
|
||||||
exports.prepBuildFiles(projectPath);
|
exports.prepBuildFiles(projectPath, builder);
|
||||||
events.emit('log', generateDoneMessage('update', options.link));
|
events.emit('log', generateDoneMessage('update', options.link));
|
||||||
}).thenResolve(projectPath);
|
}).thenResolve(projectPath);
|
||||||
};
|
};
|
||||||
|
25
bin/templates/cordova/Api.js
vendored
25
bin/templates/cordova/Api.js
vendored
@ -56,6 +56,7 @@ function setupEvents (externalEventEmitter) {
|
|||||||
function Api (platform, platformRootDir, events) {
|
function Api (platform, platformRootDir, events) {
|
||||||
this.platform = PLATFORM;
|
this.platform = PLATFORM;
|
||||||
this.root = path.resolve(__dirname, '..');
|
this.root = path.resolve(__dirname, '..');
|
||||||
|
this.builder = 'gradle';
|
||||||
|
|
||||||
setupEvents(events);
|
setupEvents(events);
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ function Api (platform, platformRootDir, events) {
|
|||||||
strings: path.join(self.root, 'res/values/strings.xml'),
|
strings: path.join(self.root, 'res/values/strings.xml'),
|
||||||
manifest: path.join(self.root, 'AndroidManifest.xml'),
|
manifest: path.join(self.root, 'AndroidManifest.xml'),
|
||||||
build: path.join(self.root, 'build'),
|
build: path.join(self.root, 'build'),
|
||||||
|
javaSrc: path.join(self.root, 'src'),
|
||||||
// NOTE: Due to platformApi spec we need to return relative paths here
|
// NOTE: Due to platformApi spec we need to return relative paths here
|
||||||
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
|
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
|
||||||
cordovaJsSrc: 'cordova-js-src'
|
cordovaJsSrc: 'cordova-js-src'
|
||||||
@ -79,10 +81,13 @@ function Api (platform, platformRootDir, events) {
|
|||||||
// XXX Override some locations for Android Studio projects
|
// XXX Override some locations for Android Studio projects
|
||||||
if (AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
if (AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
||||||
selfEvents.emit('log', 'Android Studio project detected');
|
selfEvents.emit('log', 'Android Studio project detected');
|
||||||
|
this.builder = 'studio';
|
||||||
this.android_studio = true;
|
this.android_studio = true;
|
||||||
this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml');
|
this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml');
|
||||||
this.locations.strings = path.join(self.root, 'app/src/main/res/xml/strings.xml');
|
this.locations.strings = path.join(self.root, 'app/src/main/res/values/strings.xml');
|
||||||
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
||||||
|
// We could have Java Source, we could have other languages
|
||||||
|
this.locations.javaSrc = path.join(self.root, 'app/src/main/java/');
|
||||||
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
||||||
this.locations.res = path.join(self.root, 'app/src/main/res');
|
this.locations.res = path.join(self.root, 'app/src/main/res');
|
||||||
}
|
}
|
||||||
@ -226,7 +231,6 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
|||||||
// CB-11964: Do a clean when installing the plugin code to get around
|
// CB-11964: Do a clean when installing the plugin code to get around
|
||||||
// the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
// the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
||||||
// TODO: Delete when the next version of Android Gradle plugin comes out
|
// TODO: Delete when the next version of Android Gradle plugin comes out
|
||||||
|
|
||||||
// Since clean doesn't just clean the build, it also wipes out www, we need
|
// Since clean doesn't just clean the build, it also wipes out www, we need
|
||||||
// to pass additional options.
|
// to pass additional options.
|
||||||
|
|
||||||
@ -243,9 +247,9 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
|||||||
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
// This should pick the correct builder, not just get gradle
|
||||||
|
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
.thenResolve(true);
|
.thenResolve(true);
|
||||||
@ -278,7 +282,7 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
.thenResolve(true);
|
.thenResolve(true);
|
||||||
@ -331,6 +335,9 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|||||||
*/
|
*/
|
||||||
Api.prototype.build = function (buildOptions) {
|
Api.prototype.build = function (buildOptions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
if (this.android_studio) {
|
||||||
|
buildOptions.studio = true;
|
||||||
|
}
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
return require('./lib/build').run.call(self, buildOptions);
|
return require('./lib/build').run.call(self, buildOptions);
|
||||||
}).then(function (buildResults) {
|
}).then(function (buildResults) {
|
||||||
@ -374,6 +381,14 @@ Api.prototype.run = function (runOptions) {
|
|||||||
*/
|
*/
|
||||||
Api.prototype.clean = function (cleanOptions) {
|
Api.prototype.clean = function (cleanOptions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
if (this.android_studio) {
|
||||||
|
// This will lint, checking for null won't
|
||||||
|
if (typeof cleanOptions === 'undefined') {
|
||||||
|
cleanOptions = {};
|
||||||
|
}
|
||||||
|
cleanOptions.studio = true;
|
||||||
|
}
|
||||||
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
return require('./lib/build').runClean.call(self, cleanOptions);
|
return require('./lib/build').runClean.call(self, cleanOptions);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
4
bin/templates/cordova/lib/AndroidStudio.js
vendored
4
bin/templates/cordova/lib/AndroidStudio.js
vendored
@ -11,8 +11,8 @@ var fs = require('fs');
|
|||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
|
||||||
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
|
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
|
||||||
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www'];
|
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res'];
|
||||||
var androidStudioFiles = ['app', 'gradle', 'app/src/main/res'];
|
var androidStudioFiles = ['app', 'app/src/main'];
|
||||||
|
|
||||||
// assume it is an AS project and not an Eclipse project
|
// assume it is an AS project and not an Eclipse project
|
||||||
var isEclipse = false;
|
var isEclipse = false;
|
||||||
|
14
bin/templates/cordova/lib/build.js
vendored
14
bin/templates/cordova/lib/build.js
vendored
@ -35,7 +35,7 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
|||||||
options = options || {};
|
options = options || {};
|
||||||
options.argv = nopt({
|
options.argv = nopt({
|
||||||
gradle: Boolean,
|
gradle: Boolean,
|
||||||
ant: Boolean,
|
studio: Boolean,
|
||||||
prepenv: Boolean,
|
prepenv: Boolean,
|
||||||
versionCode: String,
|
versionCode: String,
|
||||||
minSdkVersion: String,
|
minSdkVersion: String,
|
||||||
@ -47,15 +47,22 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
|||||||
keystoreType: String
|
keystoreType: String
|
||||||
}, {}, options.argv, 0);
|
}, {}, options.argv, 0);
|
||||||
|
|
||||||
|
// Android Studio Build method is the default
|
||||||
var ret = {
|
var ret = {
|
||||||
buildType: options.release ? 'release' : 'debug',
|
buildType: options.release ? 'release' : 'debug',
|
||||||
buildMethod: process.env.ANDROID_BUILD || 'gradle',
|
buildMethod: process.env.ANDROID_BUILD || 'studio',
|
||||||
prepEnv: options.argv.prepenv,
|
prepEnv: options.argv.prepenv,
|
||||||
arch: resolvedTarget && resolvedTarget.arch,
|
arch: resolvedTarget && resolvedTarget.arch,
|
||||||
extraArgs: []
|
extraArgs: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.argv.ant || options.argv.gradle) { ret.buildMethod = options.argv.ant ? 'ant' : 'gradle'; }
|
if (options.argv.gradle || options.argv.studio) {
|
||||||
|
ret.buildMethod = options.argv.studio ? 'studio' : 'gradle';
|
||||||
|
}
|
||||||
|
|
||||||
|
// This comes from cordova/run
|
||||||
|
if (options.studio) ret.buildMethod = 'studio';
|
||||||
|
if (options.gradle) ret.buildMethod = 'gradle';
|
||||||
|
|
||||||
if (options.nobuild) ret.buildMethod = 'none';
|
if (options.nobuild) ret.buildMethod = 'none';
|
||||||
|
|
||||||
@ -142,6 +149,7 @@ module.exports.runClean = function (options) {
|
|||||||
*/
|
*/
|
||||||
module.exports.run = function (options, optResolvedTarget) {
|
module.exports.run = function (options, optResolvedTarget) {
|
||||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||||
|
console.log(opts.buildMethod);
|
||||||
var builder = builders.getBuilder(opts.buildMethod);
|
var builder = builders.getBuilder(opts.buildMethod);
|
||||||
return builder.prepEnv(opts).then(function () {
|
return builder.prepEnv(opts).then(function () {
|
||||||
if (opts.prepEnv) {
|
if (opts.prepEnv) {
|
||||||
|
153
bin/templates/cordova/lib/builders/AntBuilder.js
vendored
153
bin/templates/cordova/lib/builders/AntBuilder.js
vendored
@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
/* eslint no-unused-vars: 0 */
|
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var util = require('util');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
var spawn = require('cordova-common').superspawn.spawn;
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var check_reqs = require('../check_reqs');
|
|
||||||
|
|
||||||
var SIGNING_PROPERTIES = '-signing.properties';
|
|
||||||
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
|
||||||
var TEMPLATE =
|
|
||||||
'# This file is automatically generated.\n' +
|
|
||||||
'# Do not modify this file -- ' + MARKER + '\n';
|
|
||||||
|
|
||||||
var GenericBuilder = require('./GenericBuilder');
|
|
||||||
|
|
||||||
function AntBuilder (projectRoot) {
|
|
||||||
GenericBuilder.call(this, projectRoot);
|
|
||||||
|
|
||||||
this.binDirs = {ant: this.binDirs.ant};
|
|
||||||
}
|
|
||||||
|
|
||||||
util.inherits(AntBuilder, GenericBuilder);
|
|
||||||
|
|
||||||
AntBuilder.prototype.getArgs = function (cmd, opts) {
|
|
||||||
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
|
|
||||||
// custom_rules.xml is required for incremental builds.
|
|
||||||
if (hasCustomRules(this.root)) {
|
|
||||||
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
|
|
||||||
}
|
|
||||||
if (opts.packageInfo) {
|
|
||||||
args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES));
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
};
|
|
||||||
|
|
||||||
AntBuilder.prototype.prepEnv = function (opts) {
|
|
||||||
var self = this;
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
// Copy in build.xml on each build so that:
|
|
||||||
// A) we don't require the Android SDK at project creation time, and
|
|
||||||
// B) we always use the SDK's latest version of it.
|
|
||||||
/* jshint -W069 */
|
|
||||||
var sdkDir = process.env['ANDROID_HOME'];
|
|
||||||
/* jshint +W069 */
|
|
||||||
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
|
|
||||||
function writeBuildXml (projectPath) {
|
|
||||||
var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest());
|
|
||||||
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
|
|
||||||
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
|
|
||||||
fs.writeFileSync(path.join(projectPath, 'local.properties'), TEMPLATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeBuildXml(self.root);
|
|
||||||
var propertiesObj = self.readProjectProperties();
|
|
||||||
var subProjects = propertiesObj.libs;
|
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
|
||||||
writeBuildXml(path.join(self.root, subProjects[i]));
|
|
||||||
}
|
|
||||||
if (propertiesObj.systemLibs.length > 0) {
|
|
||||||
throw new CordovaError('Project contains at least one plugin that requires a system library. This is not supported with ANT. Use gradle instead.');
|
|
||||||
}
|
|
||||||
|
|
||||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
|
||||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
|
||||||
if (opts.packageInfo) {
|
|
||||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
|
||||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Builds the project with ant.
|
|
||||||
* Returns a promise.
|
|
||||||
*/
|
|
||||||
AntBuilder.prototype.build = function (opts) {
|
|
||||||
// Without our custom_rules.xml, we need to clean before building.
|
|
||||||
var ret = Q();
|
|
||||||
if (!hasCustomRules(this.root)) {
|
|
||||||
// clean will call check_ant() for us.
|
|
||||||
ret = this.clean(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
return spawn('ant', args, {stdio: 'pipe'});
|
|
||||||
}).progress(function (stdio) {
|
|
||||||
if (stdio.stderr) {
|
|
||||||
process.stderr.write(stdio.stderr);
|
|
||||||
} else {
|
|
||||||
process.stdout.write(stdio.stdout);
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
if (error.toString().indexOf('Unable to resolve project target') >= 0) {
|
|
||||||
return check_reqs.check_android_target(error).then(function () {
|
|
||||||
// If due to some odd reason - check_android_target succeeds
|
|
||||||
// we should still fail here.
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
AntBuilder.prototype.clean = function (opts) {
|
|
||||||
var args = this.getArgs('clean', opts);
|
|
||||||
var self = this;
|
|
||||||
return check_reqs.check_ant().then(function () {
|
|
||||||
return spawn('ant', args, {stdio: 'inherit'});
|
|
||||||
}).then(function () {
|
|
||||||
shell.rm('-rf', path.join(self.root, 'out'));
|
|
||||||
|
|
||||||
['debug', 'release'].forEach(function (config) {
|
|
||||||
var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES);
|
|
||||||
if (isAutoGenerated(propertiesFilePath)) {
|
|
||||||
shell.rm('-f', propertiesFilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AntBuilder;
|
|
||||||
|
|
||||||
function hasCustomRules (projectRoot) {
|
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAutoGenerated (file) {
|
|
||||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
|
||||||
}
|
|
@ -24,20 +24,15 @@ var fs = require('fs');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var shell = require('shelljs');
|
var shell = require('shelljs');
|
||||||
var events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
|
|
||||||
function GenericBuilder (projectDir) {
|
function GenericBuilder (projectDir) {
|
||||||
this.root = projectDir || path.resolve(__dirname, '../../..');
|
this.root = projectDir || path.resolve(__dirname, '../../..');
|
||||||
this.binDirs = {
|
this.binDirs = {
|
||||||
ant: path.join(this.root, hasCustomRules(this.root) ? 'ant-build' : 'bin'),
|
studio: path.join(this.root, 'app', 'build', 'outputs', 'apk'),
|
||||||
gradle: path.join(this.root, 'build', 'outputs', 'apk')
|
gradle: path.join(this.root, 'build', 'outputs', 'apk')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasCustomRules (projectRoot) {
|
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericBuilder.prototype.prepEnv = function () {
|
GenericBuilder.prototype.prepEnv = function () {
|
||||||
return Q();
|
return Q();
|
||||||
};
|
};
|
||||||
@ -59,37 +54,6 @@ GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
|
|||||||
}, []).sort(apkSorter);
|
}, []).sort(apkSorter);
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericBuilder.prototype.readProjectProperties = function () {
|
|
||||||
function findAllUniq (data, r) {
|
|
||||||
var s = {};
|
|
||||||
var m;
|
|
||||||
while ((m = r.exec(data))) {
|
|
||||||
s[m[1]] = 1;
|
|
||||||
}
|
|
||||||
return Object.keys(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
|
||||||
return {
|
|
||||||
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
|
||||||
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
|
||||||
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
|
||||||
var manifestPath = path.join(this.root, 'AndroidManifest.xml');
|
|
||||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
|
||||||
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
|
||||||
if (!m) {
|
|
||||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
var packageName = m[1];
|
|
||||||
var lastDotIndex = packageName.lastIndexOf('.');
|
|
||||||
return packageName.substring(lastDotIndex + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = GenericBuilder;
|
module.exports = GenericBuilder;
|
||||||
|
|
||||||
function apkSorter (fileA, fileB) {
|
function apkSorter (fileA, fileB) {
|
||||||
|
@ -82,12 +82,50 @@ GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to kill this in a fire.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GradleBuilder.prototype.readProjectProperties = function () {
|
||||||
|
function findAllUniq (data, r) {
|
||||||
|
var s = {};
|
||||||
|
var m;
|
||||||
|
while ((m = r.exec(data))) {
|
||||||
|
s[m[1]] = 1;
|
||||||
|
}
|
||||||
|
return Object.keys(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||||
|
return {
|
||||||
|
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||||
|
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||||
|
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
GradleBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
||||||
|
var manifestPath = path.join(this.root, 'AndroidManifest.xml');
|
||||||
|
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||||
|
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||||
|
if (!m) {
|
||||||
|
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var packageName = m[1];
|
||||||
|
var lastDotIndex = packageName.lastIndexOf('.');
|
||||||
|
return packageName.substring(lastDotIndex + 1);
|
||||||
|
};
|
||||||
|
|
||||||
// Makes the project buildable, minus the gradle wrapper.
|
// Makes the project buildable, minus the gradle wrapper.
|
||||||
GradleBuilder.prototype.prepBuildFiles = function () {
|
GradleBuilder.prototype.prepBuildFiles = function () {
|
||||||
// Update the version of build.gradle in each dependent library.
|
// Update the version of build.gradle in each dependent library.
|
||||||
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||||
var propertiesObj = this.readProjectProperties();
|
var propertiesObj = this.readProjectProperties();
|
||||||
var subProjects = propertiesObj.libs;
|
var subProjects = propertiesObj.libs;
|
||||||
|
|
||||||
|
// Check and copy the gradle file into the subproject.
|
||||||
|
// Called by the loop below this function def.
|
||||||
var checkAndCopy = function (subProject, root) {
|
var checkAndCopy = function (subProject, root) {
|
||||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||||
// This is the future-proof way of checking if a file exists
|
// This is the future-proof way of checking if a file exists
|
||||||
@ -98,11 +136,15 @@ GradleBuilder.prototype.prepBuildFiles = function () {
|
|||||||
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Some dependencies on Android don't use gradle, or don't have default
|
||||||
|
// gradle files. This copies a dummy gradle file into them
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
for (var i = 0; i < subProjects.length; ++i) {
|
||||||
if (subProjects[i] !== 'CordovaLib') {
|
if (subProjects[i] !== 'CordovaLib' && subProjects[i] !== 'app') {
|
||||||
checkAndCopy(subProjects[i], this.root);
|
checkAndCopy(subProjects[i], this.root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = this.extractRealProjectNameFromManifest();
|
var name = this.extractRealProjectNameFromManifest();
|
||||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||||
var settingsGradlePaths = subProjects.map(function (p) {
|
var settingsGradlePaths = subProjects.map(function (p) {
|
||||||
@ -121,6 +163,10 @@ GradleBuilder.prototype.prepBuildFiles = function () {
|
|||||||
var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8');
|
var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8');
|
||||||
var depsList = '';
|
var depsList = '';
|
||||||
var root = this.root;
|
var root = this.root;
|
||||||
|
|
||||||
|
// Cordova Plugins can be written as library modules that would use Cordova as a
|
||||||
|
// dependency. Because we need to make sure that Cordova is compiled only once for
|
||||||
|
// dexing, we make sure to exclude CordovaLib from these modules
|
||||||
var insertExclude = function (p) {
|
var insertExclude = function (p) {
|
||||||
var gradlePath = path.join(root, p, 'build.gradle');
|
var gradlePath = path.join(root, p, 'build.gradle');
|
||||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||||
@ -130,12 +176,14 @@ GradleBuilder.prototype.prepBuildFiles = function () {
|
|||||||
depsList += '\n';
|
depsList += '\n';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
subProjects.forEach(function (p) {
|
subProjects.forEach(function (p) {
|
||||||
console.log('Subproject Path: ' + p);
|
console.log('Subproject Path: ' + p);
|
||||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||||
depsList += ' implementation(project(path: "' + libName + '"))';
|
depsList += ' implementation(project(path: "' + libName + '"))';
|
||||||
insertExclude(p);
|
insertExclude(p);
|
||||||
});
|
});
|
||||||
|
|
||||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||||
var SYSTEM_LIBRARY_MAPPINGS = [
|
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||||
@ -160,6 +208,9 @@ GradleBuilder.prototype.prepBuildFiles = function () {
|
|||||||
}
|
}
|
||||||
depsList += ' compile "' + mavenRef + '"\n';
|
depsList += ' compile "' + mavenRef + '"\n';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This code is dangerous and actually writes gradle declarations directly into the build.gradle
|
||||||
|
// Try not to mess with this if possible
|
||||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||||
var includeList = '';
|
var includeList = '';
|
||||||
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||||
|
302
bin/templates/cordova/lib/builders/StudioBuilder.js
vendored
Normal file
302
bin/templates/cordova/lib/builders/StudioBuilder.js
vendored
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Q = require('q');
|
||||||
|
var fs = require('fs');
|
||||||
|
var util = require('util');
|
||||||
|
var path = require('path');
|
||||||
|
var shell = require('shelljs');
|
||||||
|
var spawn = require('cordova-common').superspawn.spawn;
|
||||||
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
var check_reqs = require('../check_reqs');
|
||||||
|
|
||||||
|
var GenericBuilder = require('./GenericBuilder');
|
||||||
|
|
||||||
|
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||||
|
var SIGNING_PROPERTIES = '-signing.properties';
|
||||||
|
var TEMPLATE =
|
||||||
|
'# This file is automatically generated.\n' +
|
||||||
|
'# Do not modify this file -- ' + MARKER + '\n';
|
||||||
|
|
||||||
|
function StudioBuilder (projectRoot) {
|
||||||
|
GenericBuilder.call(this, projectRoot);
|
||||||
|
|
||||||
|
this.binDirs = {gradle: this.binDirs.studio};
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(StudioBuilder, GenericBuilder);
|
||||||
|
|
||||||
|
StudioBuilder.prototype.getArgs = function (cmd, opts) {
|
||||||
|
if (cmd === 'release') {
|
||||||
|
cmd = 'cdvBuildRelease';
|
||||||
|
} else if (cmd === 'debug') {
|
||||||
|
cmd = 'cdvBuildDebug';
|
||||||
|
}
|
||||||
|
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||||
|
if (opts.arch) {
|
||||||
|
args.push('-PcdvBuildArch=' + opts.arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10 seconds -> 6 seconds
|
||||||
|
args.push('-Dorg.gradle.daemon=true');
|
||||||
|
// to allow dex in process
|
||||||
|
args.push('-Dorg.gradle.jvmargs=-Xmx2048m');
|
||||||
|
// allow NDK to be used - required by Gradle 1.5 plugin
|
||||||
|
args.push('-Pandroid.useDeprecatedNdk=true');
|
||||||
|
args.push.apply(args, opts.extraArgs);
|
||||||
|
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
||||||
|
// args.push('-Dorg.gradle.parallel=true');
|
||||||
|
return args;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This returns a promise
|
||||||
|
*/
|
||||||
|
|
||||||
|
StudioBuilder.prototype.runGradleWrapper = function (gradle_cmd) {
|
||||||
|
var gradlePath = path.join(this.root, 'gradlew');
|
||||||
|
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
|
||||||
|
if (fs.existsSync(gradlePath)) {
|
||||||
|
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||||
|
} else {
|
||||||
|
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], {stdio: 'inherit'});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
StudioBuilder.prototype.readProjectProperties = function () {
|
||||||
|
|
||||||
|
function findAllUniq (data, r) {
|
||||||
|
var s = {};
|
||||||
|
var m;
|
||||||
|
while ((m = r.exec(data))) {
|
||||||
|
s[m[1]] = 1;
|
||||||
|
}
|
||||||
|
return Object.keys(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||||
|
return {
|
||||||
|
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||||
|
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||||
|
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
StudioBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
||||||
|
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||||
|
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||||
|
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||||
|
if (!m) {
|
||||||
|
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var packageName = m[1];
|
||||||
|
var lastDotIndex = packageName.lastIndexOf('.');
|
||||||
|
return packageName.substring(lastDotIndex + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Makes the project buildable, minus the gradle wrapper.
|
||||||
|
StudioBuilder.prototype.prepBuildFiles = function () {
|
||||||
|
// Update the version of build.gradle in each dependent library.
|
||||||
|
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||||
|
var propertiesObj = this.readProjectProperties();
|
||||||
|
var subProjects = propertiesObj.libs;
|
||||||
|
|
||||||
|
// Check and copy the gradle file into the subproject
|
||||||
|
// Called by the loop before this function def
|
||||||
|
|
||||||
|
var checkAndCopy = function (subProject, root) {
|
||||||
|
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||||
|
// This is the future-proof way of checking if a file exists
|
||||||
|
// This must be synchronous to satisfy a Travis test
|
||||||
|
try {
|
||||||
|
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||||
|
} catch (e) {
|
||||||
|
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < subProjects.length; ++i) {
|
||||||
|
if (subProjects[i] !== 'CordovaLib') {
|
||||||
|
checkAndCopy(subProjects[i], this.root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var name = this.extractRealProjectNameFromManifest();
|
||||||
|
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||||
|
var settingsGradlePaths = subProjects.map(function (p) {
|
||||||
|
var realDir = p.replace(/[/\\]/g, ':');
|
||||||
|
var libName = realDir.replace(name + '-', '');
|
||||||
|
var str = 'include ":' + libName + '"\n';
|
||||||
|
if (realDir.indexOf(name + '-') !== -1) {
|
||||||
|
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||||
|
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||||
|
'include ":"\n' + settingsGradlePaths.join(''));
|
||||||
|
|
||||||
|
// Update dependencies within build.gradle.
|
||||||
|
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
|
||||||
|
var depsList = '';
|
||||||
|
var root = this.root;
|
||||||
|
var insertExclude = function (p) {
|
||||||
|
var gradlePath = path.join(root, p, 'build.gradle');
|
||||||
|
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||||
|
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||||
|
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||||
|
} else {
|
||||||
|
depsList += '\n';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
subProjects.forEach(function (p) {
|
||||||
|
console.log('Subproject Path: ' + p);
|
||||||
|
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||||
|
if (libName !== 'app') {
|
||||||
|
depsList += ' implementation(project(path: ":' + libName + '"))';
|
||||||
|
insertExclude(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||||
|
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||||
|
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||||
|
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||||
|
];
|
||||||
|
|
||||||
|
propertiesObj.systemLibs.forEach(function (p) {
|
||||||
|
var mavenRef;
|
||||||
|
// It's already in gradle form if it has two ':'s
|
||||||
|
if (/:.*:/.exec(p)) {
|
||||||
|
mavenRef = p;
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
|
||||||
|
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
|
||||||
|
if (pair[0].exec(p)) {
|
||||||
|
mavenRef = p.replace(pair[0], pair[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mavenRef) {
|
||||||
|
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
depsList += ' compile "' + mavenRef + '"\n';
|
||||||
|
});
|
||||||
|
|
||||||
|
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||||
|
var includeList = '';
|
||||||
|
|
||||||
|
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||||
|
includeList += 'apply from: "../' + includePath + '"\n';
|
||||||
|
});
|
||||||
|
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
||||||
|
// This needs to be stored in the app gradle, not the root grade
|
||||||
|
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
|
||||||
|
};
|
||||||
|
|
||||||
|
StudioBuilder.prototype.prepEnv = function (opts) {
|
||||||
|
var self = this;
|
||||||
|
return check_reqs.check_gradle()
|
||||||
|
.then(function (gradlePath) {
|
||||||
|
return self.runGradleWrapper(gradlePath);
|
||||||
|
}).then(function () {
|
||||||
|
return self.prepBuildFiles();
|
||||||
|
}).then(function () {
|
||||||
|
// If the gradle distribution URL is set, make sure it points to version we want.
|
||||||
|
// If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with.
|
||||||
|
// For some reason, using ^ and $ don't work. This does the job, though.
|
||||||
|
var distributionUrlRegex = /distributionUrl.*zip/;
|
||||||
|
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
|
||||||
|
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
||||||
|
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
||||||
|
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
||||||
|
|
||||||
|
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
||||||
|
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||||
|
if (opts.packageInfo) {
|
||||||
|
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
||||||
|
} else if (isAutoGenerated(propertiesFilePath)) {
|
||||||
|
shell.rm('-f', propertiesFilePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds the project with gradle.
|
||||||
|
* Returns a promise.
|
||||||
|
*/
|
||||||
|
StudioBuilder.prototype.build = function (opts) {
|
||||||
|
var wrapper = path.join(this.root, 'gradlew');
|
||||||
|
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||||
|
|
||||||
|
return spawn(wrapper, args, {stdio: 'pipe'})
|
||||||
|
.progress(function (stdio) {
|
||||||
|
if (stdio.stderr) {
|
||||||
|
/*
|
||||||
|
* Workaround for the issue with Java printing some unwanted information to
|
||||||
|
* stderr instead of stdout.
|
||||||
|
* This function suppresses 'Picked up _JAVA_OPTIONS' message from being
|
||||||
|
* printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for
|
||||||
|
* explanation.
|
||||||
|
*/
|
||||||
|
var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString());
|
||||||
|
if (suppressThisLine) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
process.stderr.write(stdio.stderr);
|
||||||
|
} else {
|
||||||
|
process.stdout.write(stdio.stdout);
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
if (error.toString().indexOf('failed to find target with hash string') >= 0) {
|
||||||
|
return check_reqs.check_android_target(error).then(function () {
|
||||||
|
// If due to some odd reason - check_android_target succeeds
|
||||||
|
// we should still fail here.
|
||||||
|
return Q.reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Q.reject(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
StudioBuilder.prototype.clean = function (opts) {
|
||||||
|
var builder = this;
|
||||||
|
var wrapper = path.join(this.root, 'gradlew');
|
||||||
|
var args = builder.getArgs('clean', opts);
|
||||||
|
return Q().then(function () {
|
||||||
|
return spawn(wrapper, args, {stdio: 'inherit'});
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||||
|
|
||||||
|
['debug', 'release'].forEach(function (config) {
|
||||||
|
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
||||||
|
if (isAutoGenerated(propertiesFilePath)) {
|
||||||
|
shell.rm('-f', propertiesFilePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = StudioBuilder;
|
||||||
|
|
||||||
|
function isAutoGenerated (file) {
|
||||||
|
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||||
|
}
|
@ -20,8 +20,8 @@
|
|||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
|
||||||
var knownBuilders = {
|
var knownBuilders = {
|
||||||
ant: 'AntBuilder',
|
|
||||||
gradle: 'GradleBuilder',
|
gradle: 'GradleBuilder',
|
||||||
|
studio: 'StudioBuilder',
|
||||||
none: 'GenericBuilder'
|
none: 'GenericBuilder'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2
bin/templates/cordova/lib/device.js
vendored
2
bin/templates/cordova/lib/device.js
vendored
@ -81,7 +81,7 @@ module.exports.install = function (target, buildResults) {
|
|||||||
return module.exports.resolveTarget(target);
|
return module.exports.resolveTarget(target);
|
||||||
}).then(function (resolvedTarget) {
|
}).then(function (resolvedTarget) {
|
||||||
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
|
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
|
||||||
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(__dirname, '../../app/src/main/AndroidManifest.xml'));
|
||||||
var pkgName = manifest.getPackageId();
|
var pkgName = manifest.getPackageId();
|
||||||
var launchName = pkgName + '/.' + manifest.getActivity().getName();
|
var launchName = pkgName + '/.' + manifest.getActivity().getName();
|
||||||
events.emit('log', 'Using apk: ' + apk_path);
|
events.emit('log', 'Using apk: ' + apk_path);
|
||||||
|
7
bin/templates/cordova/lib/emulator.js
vendored
7
bin/templates/cordova/lib/emulator.js
vendored
@ -432,7 +432,12 @@ module.exports.resolveTarget = function (target) {
|
|||||||
module.exports.install = function (givenTarget, buildResults) {
|
module.exports.install = function (givenTarget, buildResults) {
|
||||||
|
|
||||||
var target;
|
var target;
|
||||||
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
// We need to find the proper path to the Android Manifest
|
||||||
|
var manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||||
|
if (buildResults.buildMethod === 'gradle') {
|
||||||
|
manifestPath = path.join(__dirname, '../../AndroidManifest.xml');
|
||||||
|
}
|
||||||
|
var manifest = new AndroidManifest(manifestPath);
|
||||||
var pkgName = manifest.getPackageId();
|
var pkgName = manifest.getPackageId();
|
||||||
|
|
||||||
// resolve the target emulator
|
// resolve the target emulator
|
||||||
|
28
bin/templates/cordova/lib/pluginHandlers.js
vendored
28
bin/templates/cordova/lib/pluginHandlers.js
vendored
@ -1,7 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
*
|
|
||||||
* Copyright 2013 Anis Kadri
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
@ -33,8 +30,19 @@ var handlers = {
|
|||||||
|
|
||||||
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
||||||
|
|
||||||
|
// TODO: This code needs to be replaced, since the core plugins need to be re-mapped to a different location in
|
||||||
|
// a later plugins release. This is for legacy plugins to work with Cordova.
|
||||||
|
|
||||||
if (options && options.android_studio === true) {
|
if (options && options.android_studio === true) {
|
||||||
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
// If a Java file is using the new directory structure, don't penalize it
|
||||||
|
if (!obj.targetDir.includes('app/src/main')) {
|
||||||
|
if (obj.src.endsWith('.java')) {
|
||||||
|
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
||||||
|
} else if (obj.src.endsWith('.xml')) {
|
||||||
|
// We are making a huge assumption here that XML files will be going to res/xml or values/xml
|
||||||
|
dest = path.join('app/src/main', obj.targetDir, path.basename(obj.src));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && options.force) {
|
if (options && options.force) {
|
||||||
@ -71,10 +79,18 @@ var handlers = {
|
|||||||
},
|
},
|
||||||
'resource-file': {
|
'resource-file': {
|
||||||
install: function (obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link));
|
var dest = path.normalize(obj.target);
|
||||||
|
if (options && options.android_studio === true) {
|
||||||
|
dest = path.join('app/src/main', dest);
|
||||||
|
}
|
||||||
|
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||||
},
|
},
|
||||||
uninstall: function (obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
removeFile(project.projectDir, path.normalize(obj.target));
|
var dest = path.normalize(obj.target);
|
||||||
|
if (options && options.android_studio === true) {
|
||||||
|
dest = path.join('app/src/main', dest);
|
||||||
|
}
|
||||||
|
removeFile(project.projectDir, dest);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'framework': {
|
'framework': {
|
||||||
|
5
bin/templates/cordova/lib/prepare.js
vendored
5
bin/templates/cordova/lib/prepare.js
vendored
@ -199,7 +199,8 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
|||||||
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
||||||
.write();
|
.write();
|
||||||
|
|
||||||
var javaPattern = path.join(locations.root, 'src', manifestId.replace(/\./g, '/'), '*.java');
|
// Java file paths shouldn't be hard coded
|
||||||
|
var javaPattern = path.join(locations.javaSrc, manifestId.replace(/\./g, '/'), '*.java');
|
||||||
var java_files = shell.ls(javaPattern).filter(function (f) {
|
var java_files = shell.ls(javaPattern).filter(function (f) {
|
||||||
return shell.grep(/extends\s+CordovaActivity/g, f);
|
return shell.grep(/extends\s+CordovaActivity/g, f);
|
||||||
});
|
});
|
||||||
@ -210,7 +211,7 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
|||||||
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
|
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var destFile = path.join(locations.root, 'src', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
|
var destFile = path.join(locations.root, 'app', 'src', 'main', 'java', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
|
||||||
shell.mkdir('-p', path.dirname(destFile));
|
shell.mkdir('-p', path.dirname(destFile));
|
||||||
shell.sed(/package [\w\.]*;/, 'package ' + androidPkgName + ';', java_files[0]).to(destFile);
|
shell.sed(/package [\w\.]*;/, 'package ' + androidPkgName + ';', java_files[0]).to(destFile);
|
||||||
events.emit('verbose', 'Wrote out Android package name "' + androidPkgName + '" to ' + destFile);
|
events.emit('verbose', 'Wrote out Android package name "' + androidPkgName + '" to ' + destFile);
|
||||||
|
324
bin/templates/project/app/build.gradle
Normal file
324
bin/templates/project/app/build.gradle
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenCentral();
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task wrapper(type: Wrapper) {
|
||||||
|
gradleVersion = '4.1.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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: '../CordovaLib/cordova.gradle'
|
||||||
|
// The value for android.compileSdkVersion.
|
||||||
|
if (!project.hasProperty('cdvCompileSdkVersion')) {
|
||||||
|
cdvCompileSdkVersion = null;
|
||||||
|
}
|
||||||
|
// The value for android.buildToolsVersion.
|
||||||
|
if (!project.hasProperty('cdvBuildToolsVersion')) {
|
||||||
|
cdvBuildToolsVersion = null;
|
||||||
|
}
|
||||||
|
// 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 = null
|
||||||
|
}
|
||||||
|
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
|
||||||
|
if (!project.hasProperty('cdvVersionCodeForceAbiDigit')) {
|
||||||
|
cdvVersionCodeForceAbiDigit = null
|
||||||
|
}
|
||||||
|
// .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
|
||||||
|
}
|
||||||
|
// Set by build.js script.
|
||||||
|
if (!project.hasProperty('cdvBuildArch')) {
|
||||||
|
cdvBuildArch = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugin gradle extensions can append to this to have code run at the end.
|
||||||
|
cdvPluginPostBuildExtras = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// PLUGIN GRADLE EXTENSIONS START
|
||||||
|
// PLUGIN GRADLE EXTENSIONS END
|
||||||
|
|
||||||
|
def hasBuildExtras = file('build-extras.gradle').exists()
|
||||||
|
if (hasBuildExtras) {
|
||||||
|
apply from: 'build-extras.gradle'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set property defaults after extension .gradle files.
|
||||||
|
if (ext.cdvCompileSdkVersion == null) {
|
||||||
|
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
||||||
|
//ext.cdvCompileSdkVersion = project.ext.defaultCompileSdkVersion
|
||||||
|
}
|
||||||
|
if (ext.cdvBuildToolsVersion == null) {
|
||||||
|
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
||||||
|
//ext.cdvBuildToolsVersion = project.ext.defaultBuildToolsVersion
|
||||||
|
}
|
||||||
|
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
|
||||||
|
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
|
||||||
|
}
|
||||||
|
if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) {
|
||||||
|
ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to appropriate types.
|
||||||
|
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||||
|
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
|
||||||
|
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : defaultMinSdkVersion
|
||||||
|
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||||
|
|
||||||
|
def computeBuildTargetName(debugBuild) {
|
||||||
|
def ret = 'assemble'
|
||||||
|
if (cdvBuildMultipleApks && cdvBuildArch) {
|
||||||
|
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
|
||||||
|
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
|
||||||
|
}
|
||||||
|
return ret + (debugBuild ? 'Debug' : 'Release')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
|
||||||
|
task cdvBuildDebug
|
||||||
|
cdvBuildDebug.dependsOn {
|
||||||
|
return computeBuildTargetName(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
task cdvBuildRelease
|
||||||
|
cdvBuildRelease.dependsOn {
|
||||||
|
return computeBuildTargetName(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
task cdvPrintProps << {
|
||||||
|
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
||||||
|
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||||
|
println('cdvVersionCode=' + cdvVersionCode)
|
||||||
|
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
||||||
|
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||||
|
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||||
|
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||||
|
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||||
|
println('cdvBuildArch=' + cdvBuildArch)
|
||||||
|
println('computedVersionCode=' + android.defaultConfig.versionCode)
|
||||||
|
android.productFlavors.each { flavor ->
|
||||||
|
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
|
||||||
|
applicationId privateHelpers.extractStringFromManifest("package")
|
||||||
|
|
||||||
|
if (cdvMinSdkVersion != null) {
|
||||||
|
minSdkVersion cdvMinSdkVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false;
|
||||||
|
}
|
||||||
|
|
||||||
|
compileSdkVersion cdvCompileSdkVersion
|
||||||
|
buildToolsVersion cdvBuildToolsVersion
|
||||||
|
|
||||||
|
//This code exists for Crosswalk and other Native APIs.
|
||||||
|
//By default, we multiply the existing version code in the Android Manifest by 10 and
|
||||||
|
//add a number for each architecture. If you are not using Crosswalk or SQLite, you can
|
||||||
|
//ignore this chunk of code, and your version codes will be respected.
|
||||||
|
|
||||||
|
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
||||||
|
flavorDimensions "default"
|
||||||
|
|
||||||
|
productFlavors {
|
||||||
|
armeabi {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 1
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["armeabi"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armv7 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 2
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["armeabi-v7a"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arm64 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 3
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["arm64-v8a"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x86 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 4
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["x86"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x86_64 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 5
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["x86_64"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Boolean.valueOf(cdvVersionCodeForceAbiDigit)) {
|
||||||
|
// This provides compatibility to the default logic for versionCode before cordova-android 5.2.0
|
||||||
|
defaultConfig {
|
||||||
|
versionCode defaultConfig.versionCode*10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdvReleaseSigningPropertiesFile) {
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
// These must be set or Gradle will complain (even if they are overridden).
|
||||||
|
keyAlias = ""
|
||||||
|
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
|
||||||
|
storeFile = null
|
||||||
|
storePassword = "__unset"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
|
||||||
|
}
|
||||||
|
if (cdvDebugSigningPropertiesFile) {
|
||||||
|
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: Cordova Lib and platform scripts do management inside of this code here,
|
||||||
|
* if you are adding the dependencies manually, do so outside the comments, otherwise
|
||||||
|
* the Cordova tools will overwrite them
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||||
|
// SUB-PROJECT DEPENDENCIES START
|
||||||
|
debugCompile(project(path: ":CordovaLib", configuration: "debug"))
|
||||||
|
releaseCompile(project(path: ":CordovaLib", configuration: "release"))
|
||||||
|
// SUB-PROJECT DEPENDENCIES END
|
||||||
|
}
|
||||||
|
|
||||||
|
def promptForReleaseKeyPassword() {
|
||||||
|
if (!cdvReleaseSigningPropertiesFile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
|
||||||
|
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
|
||||||
|
}
|
||||||
|
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
|
||||||
|
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gradle.taskGraph.whenReady { taskGraph ->
|
||||||
|
taskGraph.getAllTasks().each() { task ->
|
||||||
|
if(['validateReleaseSigning', 'validateSigningRelease', 'validateSigningArmv7Release', 'validateSigningX76Release'].contains(task.name)) {
|
||||||
|
promptForReleaseKeyPassword()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def addSigningProps(propsFilePath, signingConfig) {
|
||||||
|
def propsFile = file(propsFilePath)
|
||||||
|
def props = new Properties()
|
||||||
|
propsFile.withReader { reader ->
|
||||||
|
props.load(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
|
||||||
|
if (!storeFile.isAbsolute()) {
|
||||||
|
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
|
||||||
|
}
|
||||||
|
if (!storeFile.exists()) {
|
||||||
|
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
|
||||||
|
}
|
||||||
|
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
|
||||||
|
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
|
||||||
|
signingConfig.storeFile = storeFile
|
||||||
|
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
|
||||||
|
def storeType = props.get('storeType', props.get('key.store.type', ''))
|
||||||
|
if (!storeType) {
|
||||||
|
def filename = storeFile.getName().toLowerCase();
|
||||||
|
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
|
||||||
|
storeType = 'pkcs12'
|
||||||
|
} else {
|
||||||
|
storeType = signingConfig.storeType // "jks"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signingConfig.storeType = storeType
|
||||||
|
}
|
||||||
|
|
||||||
|
for (def func : cdvPluginPostBuildExtras) {
|
||||||
|
func()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be defined within build-extras.gradle as:
|
||||||
|
// ext.postBuildExtras = { ... code here ... }
|
||||||
|
if (hasProperty('postBuildExtras')) {
|
||||||
|
postBuildExtras()
|
||||||
|
}
|
@ -1,23 +1,22 @@
|
|||||||
/*
|
/* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
or more contributor license agreements. See the NOTICE file
|
||||||
or more contributor license agreements. See the NOTICE file
|
distributed with this work for additional information
|
||||||
distributed with this work for additional information
|
regarding copyright ownership. The ASF licenses this file
|
||||||
regarding copyright ownership. The ASF licenses this file
|
to you under the Apache License, Version 2.0 (the
|
||||||
to you under the Apache License, Version 2.0 (the
|
"License"); you may not use this file except in compliance
|
||||||
"License"); you may not use this file except in compliance
|
with the License. You may obtain a copy of the License at
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the License is distributed on an
|
software distributed under the License is distributed on an
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
KIND, either express or implied. See the License for the
|
KIND, either express or implied. See the License for the
|
||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@ -26,17 +25,14 @@ buildscript {
|
|||||||
url "https://maven.google.com"
|
url "https://maven.google.com"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch the Android Gradle plugin version requirement depending on the
|
|
||||||
// installed version of Gradle. This dependency is documented at
|
|
||||||
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
|
|
||||||
// and https://issues.apache.org/jira/browse/CB-8143
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0'
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
@ -44,298 +40,15 @@ allprojects {
|
|||||||
url "https://maven.google.com"
|
url "https://maven.google.com"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//This replaces project.properties w.r.t. build settings
|
||||||
|
project.ext {
|
||||||
task wrapper(type: Wrapper) {
|
defaultBuildToolsVersion="25.0.2" //String
|
||||||
gradleVersion = '4.1.0'
|
defaultMinSdkVersion=19 //Integer - Minimum requirement is Android 4.4
|
||||||
}
|
defaultTargetSdkVersion=26 //Integer - We ALWAYS target the latest by default
|
||||||
|
defaultCompileSdkVersion=26 //Integer - We ALWAYS compile with the latest by default
|
||||||
// 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: 'CordovaLib/cordova.gradle'
|
|
||||||
// The value for android.compileSdkVersion.
|
|
||||||
if (!project.hasProperty('cdvCompileSdkVersion')) {
|
|
||||||
cdvCompileSdkVersion = null;
|
|
||||||
}
|
|
||||||
// The value for android.buildToolsVersion.
|
|
||||||
if (!project.hasProperty('cdvBuildToolsVersion')) {
|
|
||||||
cdvBuildToolsVersion = null;
|
|
||||||
}
|
|
||||||
// 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 = null
|
|
||||||
}
|
|
||||||
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
|
|
||||||
if (!project.hasProperty('cdvVersionCodeForceAbiDigit')) {
|
|
||||||
cdvVersionCodeForceAbiDigit = null
|
|
||||||
}
|
|
||||||
// .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
|
|
||||||
}
|
|
||||||
// Set by build.js script.
|
|
||||||
if (!project.hasProperty('cdvBuildArch')) {
|
|
||||||
cdvBuildArch = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugin gradle extensions can append to this to have code run at the end.
|
|
||||||
cdvPluginPostBuildExtras = []
|
|
||||||
}
|
|
||||||
|
|
||||||
// PLUGIN GRADLE EXTENSIONS START
|
|
||||||
// PLUGIN GRADLE EXTENSIONS END
|
|
||||||
|
|
||||||
def hasBuildExtras = file('build-extras.gradle').exists()
|
|
||||||
if (hasBuildExtras) {
|
|
||||||
apply from: 'build-extras.gradle'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set property defaults after extension .gradle files.
|
|
||||||
if (ext.cdvCompileSdkVersion == null) {
|
|
||||||
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
|
||||||
}
|
|
||||||
if (ext.cdvBuildToolsVersion == null) {
|
|
||||||
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
|
||||||
}
|
|
||||||
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
|
|
||||||
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
|
|
||||||
}
|
|
||||||
if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) {
|
|
||||||
ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast to appropriate types.
|
|
||||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
|
||||||
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
|
|
||||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
|
||||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
|
||||||
|
|
||||||
def computeBuildTargetName(debugBuild) {
|
|
||||||
def ret = 'assemble'
|
|
||||||
if (cdvBuildMultipleApks && cdvBuildArch) {
|
|
||||||
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
|
|
||||||
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
|
|
||||||
}
|
|
||||||
return ret + (debugBuild ? 'Debug' : 'Release')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
|
|
||||||
task cdvBuildDebug
|
|
||||||
cdvBuildDebug.dependsOn {
|
|
||||||
return computeBuildTargetName(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
task cdvBuildRelease
|
|
||||||
cdvBuildRelease.dependsOn {
|
|
||||||
return computeBuildTargetName(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
task cdvPrintProps << {
|
|
||||||
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
|
||||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
|
||||||
println('cdvVersionCode=' + cdvVersionCode)
|
|
||||||
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
|
||||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
|
||||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
|
||||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
|
||||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
|
||||||
println('cdvBuildArch=' + cdvBuildArch)
|
|
||||||
println('computedVersionCode=' + android.defaultConfig.versionCode)
|
|
||||||
android.productFlavors.each { flavor ->
|
|
||||||
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
task clean(type: Delete) {
|
||||||
sourceSets {
|
delete rootProject.buildDir
|
||||||
main {
|
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
|
||||||
java.srcDirs = ['src']
|
|
||||||
resources.srcDirs = ['src']
|
|
||||||
aidl.srcDirs = ['src']
|
|
||||||
renderscript.srcDirs = ['src']
|
|
||||||
res.srcDirs = ['res']
|
|
||||||
assets.srcDirs = ['assets']
|
|
||||||
jniLibs.srcDirs = ['libs']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
|
|
||||||
applicationId privateHelpers.extractStringFromManifest("package")
|
|
||||||
|
|
||||||
if (cdvMinSdkVersion != null) {
|
|
||||||
minSdkVersion cdvMinSdkVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lintOptions {
|
|
||||||
abortOnError false;
|
|
||||||
}
|
|
||||||
|
|
||||||
compileSdkVersion cdvCompileSdkVersion
|
|
||||||
buildToolsVersion cdvBuildToolsVersion
|
|
||||||
|
|
||||||
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
|
||||||
flavorDimensions "default"
|
|
||||||
|
|
||||||
productFlavors {
|
|
||||||
armeabi {
|
|
||||||
versionCode defaultConfig.versionCode*10 + 1
|
|
||||||
ndk {
|
|
||||||
abiFilters = ["armeabi"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
armv7 {
|
|
||||||
versionCode defaultConfig.versionCode*10 + 2
|
|
||||||
ndk {
|
|
||||||
abiFilters = ["armeabi-v7a"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arm64 {
|
|
||||||
versionCode defaultConfig.versionCode*10 + 3
|
|
||||||
ndk {
|
|
||||||
abiFilters = ["arm64-v8a"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x86 {
|
|
||||||
versionCode defaultConfig.versionCode*10 + 4
|
|
||||||
ndk {
|
|
||||||
abiFilters = ["x86"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x86_64 {
|
|
||||||
versionCode defaultConfig.versionCode*10 + 5
|
|
||||||
ndk {
|
|
||||||
abiFilters = ["x86_64"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (Boolean.valueOf(cdvVersionCodeForceAbiDigit)) {
|
|
||||||
// This provides compatibility to the default logic for versionCode before cordova-android 5.2.0
|
|
||||||
defaultConfig {
|
|
||||||
versionCode defaultConfig.versionCode*10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
|
|
||||||
ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO!
|
|
||||||
|
|
||||||
else if (!cdvVersionCode) {
|
|
||||||
def minSdkVersion = cdvMinSdkVersion ?: 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.
|
|
||||||
if (minSdkVersion >= 20) {
|
|
||||||
defaultConfig.versionCode += 9
|
|
||||||
} else if (minSdkVersion >= 14) {
|
|
||||||
defaultConfig.versionCode += 8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_6
|
|
||||||
targetCompatibility JavaVersion.VERSION_1_6
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cdvReleaseSigningPropertiesFile) {
|
|
||||||
signingConfigs {
|
|
||||||
release {
|
|
||||||
// These must be set or Gradle will complain (even if they are overridden).
|
|
||||||
keyAlias = ""
|
|
||||||
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
|
|
||||||
storeFile = null
|
|
||||||
storePassword = "__unset"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
signingConfig signingConfigs.release
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
|
|
||||||
}
|
|
||||||
if (cdvDebugSigningPropertiesFile) {
|
|
||||||
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
|
||||||
// SUB-PROJECT DEPENDENCIES START
|
|
||||||
// SUB-PROJECT DEPENDENCIES END
|
|
||||||
}
|
|
||||||
|
|
||||||
def promptForReleaseKeyPassword() {
|
|
||||||
if (!cdvReleaseSigningPropertiesFile) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
|
|
||||||
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
|
|
||||||
}
|
|
||||||
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
|
|
||||||
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gradle.taskGraph.whenReady { taskGraph ->
|
|
||||||
taskGraph.getAllTasks().each() { task ->
|
|
||||||
if (['validateReleaseSigning', 'validateSigningRelease', 'validateSigningArmv7Release', 'validateSigningX86Release'].contains(task.name)) {
|
|
||||||
promptForReleaseKeyPassword()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def addSigningProps(propsFilePath, signingConfig) {
|
|
||||||
def propsFile = file(propsFilePath)
|
|
||||||
def props = new Properties()
|
|
||||||
propsFile.withReader { reader ->
|
|
||||||
props.load(reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
|
|
||||||
if (!storeFile.isAbsolute()) {
|
|
||||||
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
|
|
||||||
}
|
|
||||||
if (!storeFile.exists()) {
|
|
||||||
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
|
|
||||||
}
|
|
||||||
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
|
|
||||||
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
|
|
||||||
signingConfig.storeFile = storeFile
|
|
||||||
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
|
|
||||||
def storeType = props.get('storeType', props.get('key.store.type', ''))
|
|
||||||
if (!storeType) {
|
|
||||||
def filename = storeFile.getName().toLowerCase();
|
|
||||||
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
|
|
||||||
storeType = 'pkcs12'
|
|
||||||
} else {
|
|
||||||
storeType = signingConfig.storeType // "jks"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signingConfig.storeType = storeType
|
|
||||||
}
|
|
||||||
|
|
||||||
for (def func : cdvPluginPostBuildExtras) {
|
|
||||||
func()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can be defined within build-extras.gradle as:
|
|
||||||
// ext.postBuildExtras = { ... code here ... }
|
|
||||||
if (hasProperty('postBuildExtras')) {
|
|
||||||
postBuildExtras()
|
|
||||||
}
|
}
|
||||||
|
311
bin/templates/project/legacy/build.gradle
Normal file
311
bin/templates/project/legacy/build.gradle
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch the Android Gradle plugin version requirement depending on the
|
||||||
|
// installed version of Gradle. This dependency is documented at
|
||||||
|
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
|
||||||
|
// and https://issues.apache.org/jira/browse/CB-8143
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenCentral();
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task wrapper(type: Wrapper) {
|
||||||
|
gradleVersion = '2.14.1'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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: 'CordovaLib/cordova.gradle'
|
||||||
|
// The value for android.compileSdkVersion.
|
||||||
|
if (!project.hasProperty('cdvCompileSdkVersion')) {
|
||||||
|
cdvCompileSdkVersion = null;
|
||||||
|
}
|
||||||
|
// The value for android.buildToolsVersion.
|
||||||
|
if (!project.hasProperty('cdvBuildToolsVersion')) {
|
||||||
|
cdvBuildToolsVersion = null;
|
||||||
|
}
|
||||||
|
// 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 = null
|
||||||
|
}
|
||||||
|
// .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
|
||||||
|
}
|
||||||
|
// Set by build.js script.
|
||||||
|
if (!project.hasProperty('cdvBuildArch')) {
|
||||||
|
cdvBuildArch = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugin gradle extensions can append to this to have code run at the end.
|
||||||
|
cdvPluginPostBuildExtras = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// PLUGIN GRADLE EXTENSIONS START
|
||||||
|
// PLUGIN GRADLE EXTENSIONS END
|
||||||
|
|
||||||
|
def hasBuildExtras = file('build-extras.gradle').exists()
|
||||||
|
if (hasBuildExtras) {
|
||||||
|
apply from: 'build-extras.gradle'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set property defaults after extension .gradle files.
|
||||||
|
if (ext.cdvCompileSdkVersion == null) {
|
||||||
|
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
||||||
|
}
|
||||||
|
if (ext.cdvBuildToolsVersion == null) {
|
||||||
|
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
||||||
|
}
|
||||||
|
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
|
||||||
|
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
|
||||||
|
}
|
||||||
|
if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) {
|
||||||
|
ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to appropriate types.
|
||||||
|
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||||
|
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
||||||
|
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||||
|
|
||||||
|
def computeBuildTargetName(debugBuild) {
|
||||||
|
def ret = 'assemble'
|
||||||
|
if (cdvBuildMultipleApks && cdvBuildArch) {
|
||||||
|
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
|
||||||
|
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
|
||||||
|
}
|
||||||
|
return ret + (debugBuild ? 'Debug' : 'Release')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
|
||||||
|
task cdvBuildDebug
|
||||||
|
cdvBuildDebug.dependsOn {
|
||||||
|
return computeBuildTargetName(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
task cdvBuildRelease
|
||||||
|
cdvBuildRelease.dependsOn {
|
||||||
|
return computeBuildTargetName(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
task cdvPrintProps << {
|
||||||
|
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
||||||
|
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||||
|
println('cdvVersionCode=' + cdvVersionCode)
|
||||||
|
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||||
|
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||||
|
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||||
|
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||||
|
println('cdvBuildArch=' + cdvBuildArch)
|
||||||
|
println('computedVersionCode=' + android.defaultConfig.versionCode)
|
||||||
|
android.productFlavors.each { flavor ->
|
||||||
|
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
java.srcDirs = ['src']
|
||||||
|
resources.srcDirs = ['src']
|
||||||
|
aidl.srcDirs = ['src']
|
||||||
|
renderscript.srcDirs = ['src']
|
||||||
|
res.srcDirs = ['res']
|
||||||
|
assets.srcDirs = ['assets']
|
||||||
|
jniLibs.srcDirs = ['libs']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
|
||||||
|
applicationId privateHelpers.extractStringFromManifest("package")
|
||||||
|
|
||||||
|
if (cdvMinSdkVersion != null) {
|
||||||
|
minSdkVersion cdvMinSdkVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false;
|
||||||
|
}
|
||||||
|
|
||||||
|
compileSdkVersion cdvCompileSdkVersion
|
||||||
|
buildToolsVersion cdvBuildToolsVersion
|
||||||
|
|
||||||
|
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
||||||
|
productFlavors {
|
||||||
|
armv7 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 2
|
||||||
|
ndk {
|
||||||
|
abiFilters "armeabi-v7a", ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x86 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 4
|
||||||
|
ndk {
|
||||||
|
abiFilters "x86", ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
all {
|
||||||
|
ndk {
|
||||||
|
abiFilters "all", ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO!
|
||||||
|
|
||||||
|
else if (!cdvVersionCode) {
|
||||||
|
def minSdkVersion = cdvMinSdkVersion ?: 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.
|
||||||
|
if (minSdkVersion >= 20) {
|
||||||
|
defaultConfig.versionCode += 9
|
||||||
|
} else if (minSdkVersion >= 14) {
|
||||||
|
defaultConfig.versionCode += 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_6
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_6
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdvReleaseSigningPropertiesFile) {
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
// These must be set or Gradle will complain (even if they are overridden).
|
||||||
|
keyAlias = ""
|
||||||
|
keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph.
|
||||||
|
storeFile = null
|
||||||
|
storePassword = "__unset"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
|
||||||
|
}
|
||||||
|
if (cdvDebugSigningPropertiesFile) {
|
||||||
|
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: '*.jar')
|
||||||
|
// SUB-PROJECT DEPENDENCIES START
|
||||||
|
// SUB-PROJECT DEPENDENCIES END
|
||||||
|
}
|
||||||
|
|
||||||
|
def promptForReleaseKeyPassword() {
|
||||||
|
if (!cdvReleaseSigningPropertiesFile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
|
||||||
|
android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
|
||||||
|
}
|
||||||
|
if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
|
||||||
|
android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gradle.taskGraph.whenReady { taskGraph ->
|
||||||
|
taskGraph.getAllTasks().each() { task ->
|
||||||
|
if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') {
|
||||||
|
promptForReleaseKeyPassword()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def addSigningProps(propsFilePath, signingConfig) {
|
||||||
|
def propsFile = file(propsFilePath)
|
||||||
|
def props = new Properties()
|
||||||
|
propsFile.withReader { reader ->
|
||||||
|
props.load(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))
|
||||||
|
if (!storeFile.isAbsolute()) {
|
||||||
|
storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())
|
||||||
|
}
|
||||||
|
if (!storeFile.exists()) {
|
||||||
|
throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())
|
||||||
|
}
|
||||||
|
signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')
|
||||||
|
signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))
|
||||||
|
signingConfig.storeFile = storeFile
|
||||||
|
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
|
||||||
|
def storeType = props.get('storeType', props.get('key.store.type', ''))
|
||||||
|
if (!storeType) {
|
||||||
|
def filename = storeFile.getName().toLowerCase();
|
||||||
|
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
|
||||||
|
storeType = 'pkcs12'
|
||||||
|
} else {
|
||||||
|
storeType = signingConfig.storeType // "jks"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signingConfig.storeType = storeType
|
||||||
|
}
|
||||||
|
|
||||||
|
for (def func : cdvPluginPostBuildExtras) {
|
||||||
|
func()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be defined within build-extras.gradle as:
|
||||||
|
// ext.postBuildExtras = { ... code here ... }
|
||||||
|
if (hasProperty('postBuildExtras')) {
|
||||||
|
postBuildExtras()
|
||||||
|
}
|
@ -1,15 +1,13 @@
|
|||||||
# This file is automatically generated by Android Tools.
|
# This file was originally created by the Android Tools, but is now
|
||||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
# used by cordova-android to manage the state of the various third party
|
||||||
#
|
# libraries used in your application
|
||||||
# This file must be checked in Version Control Systems.
|
|
||||||
#
|
|
||||||
# To customize properties used by the Ant build system edit
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
#
|
|
||||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
|
||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
|
||||||
|
|
||||||
|
# This is the Library Module that contains the Cordova Library, this is not
|
||||||
|
# required when using an AAR
|
||||||
android.library.reference.1=CordovaLib
|
android.library.reference.1=CordovaLib
|
||||||
|
|
||||||
|
# This is the application project. This is only required for Android Studio Gradle projects
|
||||||
|
android.library.reference.2=app
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=This_gets_replaced
|
target=This_gets_replaced
|
||||||
|
@ -19,5 +19,5 @@
|
|||||||
-->
|
-->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
||||||
<uses-sdk android:minSdkVersion="14" />
|
<uses-sdk android:minSdkVersion="16" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -50,8 +50,8 @@ android {
|
|||||||
publishNonDefault true
|
publishNonDefault true
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_6
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_6
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -29,7 +29,11 @@ String doEnsureValueExists(filePath, props, key) {
|
|||||||
|
|
||||||
String doGetProjectTarget() {
|
String doGetProjectTarget() {
|
||||||
def props = new Properties()
|
def props = new Properties()
|
||||||
file('project.properties').withReader { reader ->
|
def propertiesFile = 'project.properties';
|
||||||
|
if(!(file(propertiesFile).exists())) {
|
||||||
|
propertiesFile = '../project.properties';
|
||||||
|
}
|
||||||
|
file(propertiesFile).withReader { reader ->
|
||||||
props.load(reader)
|
props.load(reader)
|
||||||
}
|
}
|
||||||
return doEnsureValueExists('project.properties', props, 'target')
|
return doEnsureValueExists('project.properties', props, 'target')
|
||||||
|
@ -319,6 +319,7 @@ public class CordovaActivity extends Activity {
|
|||||||
/**
|
/**
|
||||||
* Called when view focus is changed
|
* Called when view focus is changed
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("InlinedApi")
|
||||||
@Override
|
@Override
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
super.onWindowFocusChanged(hasFocus);
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
@ -110,6 +112,9 @@ public class CordovaBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Called by cordova.js to initialize the bridge. */
|
/** Called by cordova.js to initialize the bridge. */
|
||||||
|
//On old Androids SecureRandom isn't really secure, this is the least of your problems if
|
||||||
|
//you're running Android 4.3 and below in 2017
|
||||||
|
@SuppressLint("TrulyRandom")
|
||||||
int generateBridgeSecret() {
|
int generateBridgeSecret() {
|
||||||
SecureRandom randGen = new SecureRandom();
|
SecureRandom randGen = new SecureRandom();
|
||||||
expectedBridgeSecret = randGen.nextInt(Integer.MAX_VALUE);
|
expectedBridgeSecret = randGen.nextInt(Integer.MAX_VALUE);
|
||||||
|
@ -22,10 +22,12 @@ import java.security.Principal;
|
|||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.webkit.ClientCertRequest;
|
import android.webkit.ClientCertRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the ICordovaClientCertRequest for Android WebView.
|
* Implementation of the ICordovaClientCertRequest for Android WebView.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/**
|
/**
|
||||||
* Cancel this request
|
* Cancel this request
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public void cancel()
|
public void cancel()
|
||||||
{
|
{
|
||||||
request.cancel();
|
request.cancel();
|
||||||
@ -46,6 +49,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/*
|
/*
|
||||||
* Returns the host name of the server requesting the certificate.
|
* Returns the host name of the server requesting the certificate.
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public String getHost()
|
public String getHost()
|
||||||
{
|
{
|
||||||
return request.getHost();
|
return request.getHost();
|
||||||
@ -54,6 +58,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/*
|
/*
|
||||||
* Returns the acceptable types of asymmetric keys (can be null).
|
* Returns the acceptable types of asymmetric keys (can be null).
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public String[] getKeyTypes()
|
public String[] getKeyTypes()
|
||||||
{
|
{
|
||||||
return request.getKeyTypes();
|
return request.getKeyTypes();
|
||||||
@ -62,6 +67,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/*
|
/*
|
||||||
* Returns the port number of the server requesting the certificate.
|
* Returns the port number of the server requesting the certificate.
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public int getPort()
|
public int getPort()
|
||||||
{
|
{
|
||||||
return request.getPort();
|
return request.getPort();
|
||||||
@ -70,6 +76,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/*
|
/*
|
||||||
* Returns the acceptable certificate issuers for the certificate matching the private key (can be null).
|
* Returns the acceptable certificate issuers for the certificate matching the private key (can be null).
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public Principal[] getPrincipals()
|
public Principal[] getPrincipals()
|
||||||
{
|
{
|
||||||
return request.getPrincipals();
|
return request.getPrincipals();
|
||||||
@ -78,6 +85,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
/*
|
/*
|
||||||
* Ignore the request for now. Do not remember user's choice.
|
* Ignore the request for now. Do not remember user's choice.
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public void ignore()
|
public void ignore()
|
||||||
{
|
{
|
||||||
request.ignore();
|
request.ignore();
|
||||||
@ -89,6 +97,7 @@ public class CordovaClientCertRequest implements ICordovaClientCertRequest {
|
|||||||
* @param privateKey The privateKey
|
* @param privateKey The privateKey
|
||||||
* @param chain The certificate chain
|
* @param chain The certificate chain
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public void proceed(PrivateKey privateKey, X509Certificate[] chain)
|
public void proceed(PrivateKey privateKey, X509Certificate[] chain)
|
||||||
{
|
{
|
||||||
request.proceed(privateKey, chain);
|
request.proceed(privateKey, chain);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -227,6 +228,7 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
|||||||
requestPermissions(plugin, requestCode, permissions);
|
requestPermissions(plugin, requestCode, permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions) {
|
public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions) {
|
||||||
int mappedRequestCode = permissionResultCallbacks.registerCallback(plugin, requestCode);
|
int mappedRequestCode = permissionResultCallbacks.registerCallback(plugin, requestCode);
|
||||||
getActivity().requestPermissions(permissions, mappedRequestCode);
|
getActivity().requestPermissions(permissions, mappedRequestCode);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -91,6 +92,7 @@ public class CordovaWebViewImpl implements CordovaWebView {
|
|||||||
init(cordova, new ArrayList<PluginEntry>(), new CordovaPreferences());
|
init(cordova, new ArrayList<PluginEntry>(), new CordovaPreferences());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("Assert")
|
||||||
@Override
|
@Override
|
||||||
public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
|
public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
|
||||||
if (this.cordova != null) {
|
if (this.cordova != null) {
|
||||||
|
@ -254,6 +254,9 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Yeah, we know, which is why we makes ure that we don't do this if the bridge is
|
||||||
|
// below JELLYBEAN_MR1. It'd be great if lint was just a little smarter.
|
||||||
|
@SuppressLint("AddJavascriptInterface")
|
||||||
private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
|
private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
|
||||||
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
|
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
|
||||||
LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
|
LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"android-versions": "^1.2.1",
|
"android-versions": "^1.2.1",
|
||||||
"cordova-common": "^2.1.0",
|
"cordova-common": "^2.2.0",
|
||||||
"elementtree": "0.1.6",
|
"elementtree": "0.1.6",
|
||||||
"nopt": "^3.0.1",
|
"nopt": "^3.0.1",
|
||||||
"properties-parser": "^0.2.3",
|
"properties-parser": "^0.2.3",
|
||||||
|
@ -127,6 +127,7 @@ describe('create', function () {
|
|||||||
var Manifest_mock = function () {};
|
var Manifest_mock = function () {};
|
||||||
var revert_manifest_mock;
|
var revert_manifest_mock;
|
||||||
var project_path = path.join('some', 'path');
|
var project_path = path.join('some', 'path');
|
||||||
|
var app_path = path.join(project_path, 'app', 'src', 'main');
|
||||||
var default_templates = path.join(__dirname, '..', '..', 'bin', 'templates', 'project');
|
var default_templates = path.join(__dirname, '..', '..', 'bin', 'templates', 'project');
|
||||||
var fake_android_target = 'android-1337';
|
var fake_android_target = 'android-1337';
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@ -217,15 +218,15 @@ describe('create', function () {
|
|||||||
describe('happy path', function () {
|
describe('happy path', function () {
|
||||||
it('should copy project templates from a specified custom template', function (done) {
|
it('should copy project templates from a specified custom template', function (done) {
|
||||||
create.create(project_path, config_mock, {customTemplate: '/template/path'}, events_mock).then(function () {
|
create.create(project_path, config_mock, {customTemplate: '/template/path'}, events_mock).then(function () {
|
||||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'assets'), project_path);
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'assets'), app_path);
|
||||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'res'), project_path);
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'res'), app_path);
|
||||||
expect(shell.cp).toHaveBeenCalledWith(path.join('/template/path', 'gitignore'), path.join(project_path, '.gitignore'));
|
expect(shell.cp).toHaveBeenCalledWith(path.join('/template/path', 'gitignore'), path.join(project_path, '.gitignore'));
|
||||||
}).fail(fail).done(done);
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
it('should copy project templates from the default templates location if no custom template is provided', function (done) {
|
it('should copy project templates from the default templates location if no custom template is provided', function (done) {
|
||||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'assets'), project_path);
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'assets'), app_path);
|
||||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'res'), project_path);
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'res'), app_path);
|
||||||
expect(shell.cp).toHaveBeenCalledWith(path.join(default_templates, 'gitignore'), path.join(project_path, '.gitignore'));
|
expect(shell.cp).toHaveBeenCalledWith(path.join(default_templates, 'gitignore'), path.join(project_path, '.gitignore'));
|
||||||
}).fail(fail).done(done);
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
@ -237,13 +238,13 @@ describe('create', function () {
|
|||||||
it('should create a java src directory based on the provided project package name', function (done) {
|
it('should create a java src directory based on the provided project package name', function (done) {
|
||||||
config_mock.packageName.and.returnValue('org.apache.cordova');
|
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
expect(shell.mkdir).toHaveBeenCalledWith('-p', path.join(project_path, 'src', 'org', 'apache', 'cordova'));
|
expect(shell.mkdir).toHaveBeenCalledWith('-p', path.join(app_path, 'java', 'org', 'apache', 'cordova'));
|
||||||
}).fail(fail).done(done);
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
it('should copy, rename and interpolate the template Activity java class with the project-specific activity name and package name', function (done) {
|
it('should copy, rename and interpolate the template Activity java class with the project-specific activity name and package name', function (done) {
|
||||||
config_mock.packageName.and.returnValue('org.apache.cordova');
|
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||||
config_mock.android_activityName.and.returnValue('CEEDEEVEE');
|
config_mock.android_activityName.and.returnValue('CEEDEEVEE');
|
||||||
var activity_path = path.join(project_path, 'src', 'org', 'apache', 'cordova', 'CEEDEEVEE.java');
|
var activity_path = path.join(app_path, 'java', 'org', 'apache', 'cordova', 'CEEDEEVEE.java');
|
||||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
expect(shell.cp).toHaveBeenCalledWith('-f', path.join(default_templates, 'Activity.java'), activity_path);
|
expect(shell.cp).toHaveBeenCalledWith('-f', path.join(default_templates, 'Activity.java'), activity_path);
|
||||||
expect(shell.sed).toHaveBeenCalledWith('-i', /__ACTIVITY__/, 'CEEDEEVEE', activity_path);
|
expect(shell.sed).toHaveBeenCalledWith('-i', /__ACTIVITY__/, 'CEEDEEVEE', activity_path);
|
||||||
@ -253,7 +254,7 @@ describe('create', function () {
|
|||||||
it('should interpolate the project name into strings.xml', function (done) {
|
it('should interpolate the project name into strings.xml', function (done) {
|
||||||
config_mock.name.and.returnValue('IncredibleApp');
|
config_mock.name.and.returnValue('IncredibleApp');
|
||||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
expect(shell.sed).toHaveBeenCalledWith('-i', /__NAME__/, 'IncredibleApp', path.join(project_path, 'res', 'values', 'strings.xml'));
|
expect(shell.sed).toHaveBeenCalledWith('-i', /__NAME__/, 'IncredibleApp', path.join(app_path, 'res', 'values', 'strings.xml'));
|
||||||
}).fail(fail).done(done);
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
it('should copy template scripts into generated project', function (done) {
|
it('should copy template scripts into generated project', function (done) {
|
||||||
@ -273,7 +274,7 @@ describe('create', function () {
|
|||||||
});
|
});
|
||||||
it('should prepare build files', function (done) {
|
it('should prepare build files', function (done) {
|
||||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
expect(create.prepBuildFiles).toHaveBeenCalledWith(project_path);
|
expect(create.prepBuildFiles).toHaveBeenCalledWith(project_path, 'studio');
|
||||||
}).fail(fail).done(done);
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -71,7 +71,7 @@ describe('android project handler', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('of <resource-file> elements', function () {
|
describe('of <resource-file> elements', function () {
|
||||||
it('Test#003 : should copy files', function () {
|
it('Test#003 : should copy files to the correct location on a non-Android Studio project', function () {
|
||||||
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject);
|
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject);
|
||||||
expect(copyFileSpy).toHaveBeenCalledWith(dummyplugin, 'android-resource.xml', temp, path.join('res', 'xml', 'dummy.xml'), false);
|
expect(copyFileSpy).toHaveBeenCalledWith(dummyplugin, 'android-resource.xml', temp, path.join('res', 'xml', 'dummy.xml'), false);
|
||||||
});
|
});
|
||||||
@ -264,15 +264,20 @@ describe('android project handler', function () {
|
|||||||
android['resource-file'].uninstall(valid_resources[0], dummyPluginInfo, dummyProject);
|
android['resource-file'].uninstall(valid_resources[0], dummyPluginInfo, dummyProject);
|
||||||
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('res/xml/dummy.xml'));
|
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('res/xml/dummy.xml'));
|
||||||
});
|
});
|
||||||
|
it('Test#021 : should remove files for Android Studio projects', function () {
|
||||||
|
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
||||||
|
android['resource-file'].uninstall(valid_resources[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
||||||
|
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('app/src/main/res/xml/dummy.xml'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('of <source-file> elements', function () {
|
describe('of <source-file> elements', function () {
|
||||||
it('Test#021 : should remove stuff by calling common.deleteJava', function () {
|
it('Test#022 : should remove stuff by calling common.deleteJava', function () {
|
||||||
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject);
|
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject);
|
||||||
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject);
|
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject);
|
||||||
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('src/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
|
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('src/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
|
||||||
});
|
});
|
||||||
it('Test#022 : should remove stuff by calling common.deleteJava for Android Studio projects', function () {
|
it('Test#023 : should remove stuff by calling common.deleteJava for Android Studio projects', function () {
|
||||||
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
||||||
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
|
||||||
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('app/src/main/java/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
|
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('app/src/main/java/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
|
||||||
@ -291,30 +296,30 @@ describe('android project handler', function () {
|
|||||||
spyOn(dummyProject, 'removeGradleReference');
|
spyOn(dummyProject, 'removeGradleReference');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#023 : should throw if framework doesn\'t have "src" attribute', function () {
|
it('Test#024 : should throw if framework doesn\'t have "src" attribute', function () {
|
||||||
expect(function () { android.framework.uninstall({}, dummyPluginInfo, dummyProject); }).toThrow();
|
expect(function () { android.framework.uninstall({}, dummyPluginInfo, dummyProject); }).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#024 : should uninstall framework without "parent" attribute into project root', function () {
|
it('Test#025 : should uninstall framework without "parent" attribute into project root', function () {
|
||||||
var framework = {src: 'plugin-lib'};
|
var framework = {src: 'plugin-lib'};
|
||||||
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
||||||
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#025 : should uninstall framework with "parent" attribute into parent framework dir', function () {
|
it('Test#026 : should uninstall framework with "parent" attribute into parent framework dir', function () {
|
||||||
var childFramework = {src: 'plugin-lib2', parent: 'plugin-lib'};
|
var childFramework = {src: 'plugin-lib2', parent: 'plugin-lib'};
|
||||||
android.framework.uninstall(childFramework, dummyPluginInfo, dummyProject);
|
android.framework.uninstall(childFramework, dummyPluginInfo, dummyProject);
|
||||||
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(path.resolve(dummyProject.projectDir, childFramework.parent), someString);
|
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(path.resolve(dummyProject.projectDir, childFramework.parent), someString);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#026 : should remove framework sources if "custom" attribute is set', function () {
|
it('Test#027 : should remove framework sources if "custom" attribute is set', function () {
|
||||||
var framework = {src: 'plugin-lib', custom: true};
|
var framework = {src: 'plugin-lib', custom: true};
|
||||||
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
||||||
expect(dummyProject.removeSubProject).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
expect(dummyProject.removeSubProject).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
||||||
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#27 : should install gradleReference using project.removeGradleReference', function () {
|
it('Test#28 : should install gradleReference using project.removeGradleReference', function () {
|
||||||
var framework = {src: 'plugin-lib', custom: true, type: 'gradleReference'};
|
var framework = {src: 'plugin-lib', custom: true, type: 'gradleReference'};
|
||||||
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
|
||||||
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
|
||||||
@ -340,13 +345,13 @@ describe('android project handler', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#028 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
|
it('Test#029 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
|
||||||
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject, {usePlatformWww: true});
|
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject, {usePlatformWww: true});
|
||||||
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
|
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
|
||||||
expect(shell.rm).toHaveBeenCalledWith('-Rf', platformWwwDest);
|
expect(shell.rm).toHaveBeenCalledWith('-Rf', platformWwwDest);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#29 : should put module to www only when options.usePlatformWww flag is not specified', function () {
|
it('Test#030 : should put module to www only when options.usePlatformWww flag is not specified', function () {
|
||||||
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject);
|
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject);
|
||||||
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
|
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
|
||||||
expect(shell.rm).not.toHaveBeenCalledWith('-Rf', platformWwwDest);
|
expect(shell.rm).not.toHaveBeenCalledWith('-Rf', platformWwwDest);
|
||||||
@ -370,13 +375,13 @@ describe('android project handler', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#030 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
|
it('Test#031 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
|
||||||
android.asset.uninstall(asset, dummyPluginInfo, dummyProject, {usePlatformWww: true});
|
android.asset.uninstall(asset, dummyPluginInfo, dummyProject, {usePlatformWww: true});
|
||||||
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
|
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
|
||||||
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
|
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test#31 : should put module to www only when options.usePlatformWww flag is not specified', function () {
|
it('Test#032 : should put module to www only when options.usePlatformWww flag is not specified', function () {
|
||||||
android.asset.uninstall(asset, dummyPluginInfo, dummyProject);
|
android.asset.uninstall(asset, dummyPluginInfo, dummyProject);
|
||||||
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
|
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
|
||||||
expect(shell.rm).not.toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
|
expect(shell.rm).not.toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user