mirror of
https://github.com/apache/cordova-android.git
synced 2025-01-19 07:02:51 +08:00
CB-7579 Fix run script's ability to use non-arch-specific APKs
This commit is contained in:
parent
3f83fdbfc1
commit
879da03438
152
bin/templates/cordova/lib/build.js
vendored
152
bin/templates/cordova/lib/build.js
vendored
@ -32,23 +32,46 @@ var LOCAL_PROPERTIES_TEMPLATE =
|
||||
'# This file is automatically generated.\n' +
|
||||
'# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n';
|
||||
|
||||
function find_files(directory, predicate) {
|
||||
function findApks(directory) {
|
||||
var ret = [];
|
||||
if (fs.existsSync(directory)) {
|
||||
var candidates = fs.readdirSync(directory).filter(predicate).map(function(p) {
|
||||
p = path.join(directory, p);
|
||||
return { p: p, t: fs.statSync(p).mtime };
|
||||
}).sort(function(a,b) {
|
||||
var timeDiff = b.t - a.t;
|
||||
if (timeDiff === 0) {
|
||||
return a.p.length - b.p.length;
|
||||
fs.readdirSync(directory).forEach(function(p) {
|
||||
if (path.extname(p) == '.apk') {
|
||||
ret.push(path.join(directory, p));
|
||||
}
|
||||
return timeDiff;
|
||||
}).map(function(p) { return p.p; });
|
||||
return candidates;
|
||||
} else {
|
||||
console.error('ERROR : unable to find project ' + directory + ' directory, could not locate .apk');
|
||||
process.exit(2);
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function sortFilesByDate(files) {
|
||||
return files.map(function(p) {
|
||||
return { p: p, t: fs.statSync(p).mtime };
|
||||
}).sort(function(a, b) {
|
||||
var timeDiff = b.t - a.t;
|
||||
return timeDiff === 0 ? a.p.length - b.p.length : timeDiff;
|
||||
}).map(function(p) { return p.p; });
|
||||
}
|
||||
|
||||
function findOutputApksHelper(dir, build_type) {
|
||||
var ret = findApks(dir).filter(function(candidate) {
|
||||
// Need to choose between release and debug .apk.
|
||||
if (build_type === 'debug') {
|
||||
return /-debug/.exec(candidate) && !/-unaligned|-unsigned/.exec(candidate);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return /-release/.exec(candidate) && !/-unaligned/.exec(candidate);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
ret = sortFilesByDate(ret);
|
||||
if (ret.length === 0) {
|
||||
return ret;
|
||||
}
|
||||
var archSpecific = !!/-x86|-arm/.exec(ret[0]);
|
||||
return ret.filter(function(p) {
|
||||
return !!/-x86|-arm/.exec(p) == archSpecific;
|
||||
});
|
||||
}
|
||||
|
||||
function hasCustomRules() {
|
||||
@ -127,8 +150,6 @@ var builders = {
|
||||
return check_reqs.check_ant()
|
||||
.then(function() {
|
||||
return spawn('ant', args);
|
||||
}).then(function() {
|
||||
return builder.getOutputFiles();
|
||||
});
|
||||
},
|
||||
|
||||
@ -140,22 +161,9 @@ var builders = {
|
||||
});
|
||||
},
|
||||
|
||||
// Find the recently-generated output APK files
|
||||
// Ant only generates one output file; return it.
|
||||
getOutputFiles: function() {
|
||||
var binDir;
|
||||
if(hasCustomRules()) {
|
||||
binDir = path.join(ROOT, 'ant-build');
|
||||
} else {
|
||||
binDir = path.join(ROOT, 'bin');
|
||||
}
|
||||
var candidates = find_files(binDir, function(candidate) { return path.extname(candidate) == '.apk'; });
|
||||
if (candidates.length === 0) {
|
||||
console.error('ERROR : No .apk found in ' + binDir + ' directory');
|
||||
process.exit(2);
|
||||
}
|
||||
var ret = candidates[0];
|
||||
return [ret];
|
||||
findOutputApks: function(build_type) {
|
||||
var binDir = path.join(ROOT, hasCustomRules() ? 'ant-build' : 'bin');
|
||||
return findOutputApksHelper(binDir, build_type);
|
||||
}
|
||||
},
|
||||
gradle: {
|
||||
@ -227,8 +235,6 @@ var builders = {
|
||||
var args = this.getArgs(build_type == 'debug' ? 'debug' : 'release');
|
||||
return Q().then(function() {
|
||||
return spawn(wrapper, args);
|
||||
}).then(function() {
|
||||
return builder.getOutputFiles(build_type);
|
||||
});
|
||||
},
|
||||
|
||||
@ -241,21 +247,9 @@ var builders = {
|
||||
});
|
||||
},
|
||||
|
||||
// Find the recently-generated output APK files
|
||||
// Gradle can generate multiple output files; return all of them.
|
||||
getOutputFiles: function(build_type) {
|
||||
findOutputApks: function(build_type) {
|
||||
var binDir = path.join(ROOT, 'build', 'outputs', 'apk');
|
||||
var candidates = find_files(binDir, function(candidate) {
|
||||
// Need to choose between release and debug .apk.
|
||||
if (build_type === 'debug') {
|
||||
return (path.extname(candidate) == '.apk' && candidate.indexOf('-debug') >= 0);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return (path.extname(candidate) == '.apk' && candidate.indexOf('-release') >= 0);
|
||||
}
|
||||
return path.extname(candidate) == '.apk';
|
||||
});
|
||||
return candidates;
|
||||
return findOutputApksHelper(binDir, build_type);
|
||||
}
|
||||
},
|
||||
|
||||
@ -265,11 +259,14 @@ var builders = {
|
||||
},
|
||||
build: function() {
|
||||
console.log('Skipping build...');
|
||||
return Q();
|
||||
return Q(null);
|
||||
},
|
||||
clean: function() {
|
||||
return Q();
|
||||
},
|
||||
findOutputApks: function(build_type) {
|
||||
return sortFilesByDate(builders.ant.findOutputApks(build_type).concat(builders.gradle.findOutputApks(build_type)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -284,7 +281,7 @@ function parseOpts(options) {
|
||||
|
||||
// Iterate through command line options
|
||||
for (var i=0; options && (i < options.length); ++i) {
|
||||
if (options[i].substring && options[i].substring(0,2) == "--") {
|
||||
if (/^--/.exec(options[i])) {
|
||||
var option = options[i].substring(2);
|
||||
switch(option) {
|
||||
case 'debug':
|
||||
@ -334,20 +331,15 @@ module.exports.run = function(options) {
|
||||
return builder.prepEnv()
|
||||
.then(function() {
|
||||
return builder.build(opts.buildType);
|
||||
}).then(function(apkFiles) {
|
||||
// TODO: Rather than copy apks to out, it might be better to
|
||||
// just write out what the last .apk build was. These files
|
||||
// are used by get_apk().
|
||||
var outputDir = path.join(ROOT, 'out');
|
||||
shell.mkdir('-p', outputDir);
|
||||
var builtApks = [];
|
||||
for (var i=0; i < apkFiles.length; ++i) {
|
||||
var dst = path.join(outputDir, path.basename(apkFiles[i]));
|
||||
builtApks.push(dst);
|
||||
shell.cp('-f', apkFiles[i], dst);
|
||||
}
|
||||
console.log('Built the following APKs:\n' + builtApks.join('\n'));
|
||||
return builtApks;
|
||||
}).then(function() {
|
||||
var apkPaths = builder.findOutputApks(opts.buildType);
|
||||
console.log('Built the following apk(s):');
|
||||
console.log(' ' + apkPaths.join('\n '));
|
||||
return {
|
||||
apkPaths: apkPaths,
|
||||
buildType: opts.buildType,
|
||||
buildMethod: opts.buildMethod
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@ -365,21 +357,25 @@ module.exports.detectArchitecture = function(target) {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Gets the path to the apk file, if not such file exists then
|
||||
* the script will error out. (should we error or just return undefined?)
|
||||
* This is called by the run script to install the apk to the device
|
||||
*/
|
||||
module.exports.get_apk = function(build_type, architecture) {
|
||||
var outputDir = path.join(ROOT, 'out');
|
||||
var candidates = find_files(outputDir, function(filename) { return (!architecture) || filename.indexOf(architecture) >= 0; });
|
||||
if (candidates.length === 0) {
|
||||
console.error('ERROR : No .apk found in ' + outputDir + ' directory');
|
||||
process.exit(2);
|
||||
module.exports.findBestApkForArchitecture = function(buildResults, arch) {
|
||||
var paths = buildResults.apkPaths.filter(function(p) {
|
||||
if (buildResults.buildType == 'debug') {
|
||||
return /-debug/.exec(p);
|
||||
}
|
||||
return !/-debug/.exec(p);
|
||||
});
|
||||
var archPattern = new RegExp('-' + arch);
|
||||
var hasArchPattern = /-x86|-arm/;
|
||||
for (var i = 0; i < paths.length; ++i) {
|
||||
if (hasArchPattern.exec(paths[i])) {
|
||||
if (archPattern.exec(paths[i])) {
|
||||
return paths[i];
|
||||
}
|
||||
} else {
|
||||
return paths[i];
|
||||
}
|
||||
}
|
||||
// TODO: Use build_type here.
|
||||
console.log('Using apk: ' + candidates[0]);
|
||||
return candidates[0];
|
||||
throw new Error('Could not find apk architecture: ' + arch + ' build-type: ' + buildResults.buildType);
|
||||
};
|
||||
|
||||
module.exports.help = function() {
|
||||
|
5
bin/templates/cordova/lib/device.js
vendored
5
bin/templates/cordova/lib/device.js
vendored
@ -48,7 +48,7 @@ module.exports.list = function() {
|
||||
* and launches it.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.install = function(target) {
|
||||
module.exports.install = function(target, buildResults) {
|
||||
var launchName;
|
||||
return this.list()
|
||||
.then(function(device_list) {
|
||||
@ -64,8 +64,9 @@ module.exports.install = function(target) {
|
||||
|
||||
return build.detectArchitecture(target)
|
||||
.then(function(arch) {
|
||||
var apk_path = build.get_apk(null, arch);
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, arch);
|
||||
launchName = appinfo.getActivityName();
|
||||
console.log('Using apk: ' + apk_path);
|
||||
console.log('Installing app on device...');
|
||||
var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
|
||||
return exec(cmd);
|
||||
|
5
bin/templates/cordova/lib/emulator.js
vendored
5
bin/templates/cordova/lib/emulator.js
vendored
@ -279,7 +279,7 @@ module.exports.create_image = function(name, target) {
|
||||
* If no started emulators are found, error out.
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.install = function(target) {
|
||||
module.exports.install = function(target, buildResults) {
|
||||
var self = this;
|
||||
return this.list_started()
|
||||
.then(function(emulator_list) {
|
||||
@ -295,8 +295,9 @@ module.exports.install = function(target) {
|
||||
|
||||
return build.detectArchitecture(target)
|
||||
.then(function(arch) {
|
||||
var apk_path = build.get_apk(null, arch);
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, arch);
|
||||
console.log('Installing app on emulator...');
|
||||
console.log('Using apk: ' + apk_path);
|
||||
return exec('adb -s ' + target + ' install -r "' + apk_path + '"');
|
||||
});
|
||||
}).then(function(output) {
|
||||
|
26
bin/templates/cordova/lib/run.js
vendored
26
bin/templates/cordova/lib/run.js
vendored
@ -33,16 +33,16 @@ var path = require('path'),
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.run = function(args) {
|
||||
var build_type;
|
||||
var buildFlags = [];
|
||||
var install_target;
|
||||
|
||||
for (var i=2; i<args.length; i++) {
|
||||
if (args[i] == '--debug') {
|
||||
build_type = '--debug';
|
||||
buildFlags.push('--debug');
|
||||
} else if (args[i] == '--release') {
|
||||
build_type = '--release';
|
||||
buildFlags.push('--release');
|
||||
} else if (args[i] == '--nobuild') {
|
||||
build_type = '--nobuild';
|
||||
buildFlags.push('--nobuild');
|
||||
} else if (args[i] == '--device') {
|
||||
install_target = '--device';
|
||||
} else if (args[i] == '--emulator') {
|
||||
@ -55,13 +55,13 @@ var path = require('path'),
|
||||
}
|
||||
}
|
||||
|
||||
return build.run(build_type).then(function() {
|
||||
return build.run(buildFlags).then(function(buildResults) {
|
||||
if (install_target == '--device') {
|
||||
return device.install();
|
||||
return device.install(null, buildResults);
|
||||
} else if (install_target == '--emulator') {
|
||||
return emulator.list_started().then(function(started) {
|
||||
var p = started && started.length > 0 ? Q() : emulator.start();
|
||||
return p.then(function() { emulator.install(); });
|
||||
return p.then(function() { emulator.install(null, buildResults); });
|
||||
});
|
||||
} else if (install_target) {
|
||||
var devices, started_emulators, avds;
|
||||
@ -75,16 +75,16 @@ var path = require('path'),
|
||||
}).then(function(res) {
|
||||
avds = res;
|
||||
if (devices.indexOf(install_target) > -1) {
|
||||
return device.install(install_target);
|
||||
return device.install(install_target, buildResults);
|
||||
} else if (started_emulators.indexOf(install_target) > -1) {
|
||||
return emulator.install(install_target);
|
||||
return emulator.install(install_target, buildResults);
|
||||
} else {
|
||||
// if target emulator isn't started, then start it.
|
||||
var emulator_ID;
|
||||
for(avd in avds) {
|
||||
if(avds[avd].name == install_target) {
|
||||
return emulator.start(install_target)
|
||||
.then(function() { emulator.install(emulator_ID); });
|
||||
.then(function() { emulator.install(emulator_ID, buildResults); });
|
||||
}
|
||||
}
|
||||
return Q.reject('Target \'' + install_target + '\' not found, unable to run project');
|
||||
@ -96,13 +96,13 @@ var path = require('path'),
|
||||
.then(function(device_list) {
|
||||
if (device_list.length > 0) {
|
||||
console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
|
||||
return device.install(device_list[0]);
|
||||
return device.install(device_list[0], buildResults);
|
||||
} else {
|
||||
return emulator.list_started()
|
||||
.then(function(emulator_list) {
|
||||
if (emulator_list.length > 0) {
|
||||
console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
|
||||
return emulator.install(emulator_list[0]);
|
||||
return emulator.install(emulator_list[0], buildResults);
|
||||
} else {
|
||||
console.log('WARNING : No started emulators found, starting an emulator.');
|
||||
return emulator.best_image()
|
||||
@ -111,7 +111,7 @@ var path = require('path'),
|
||||
return emulator.start(best_avd.name)
|
||||
.then(function(emulator_ID) {
|
||||
console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
|
||||
return emulator.install(emulator_ID);
|
||||
return emulator.install(emulator_ID, buildResults);
|
||||
});
|
||||
} else {
|
||||
return emulator.start();
|
||||
|
Loading…
Reference in New Issue
Block a user