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