mirror of
https://github.com/apache/cordova-android.git
synced 2025-01-31 17:32:51 +08:00
CB-12546: switch to superspawn for shelling out where possible. rework android sdk module to work with new sdk.
This commit is contained in:
parent
4a354bba86
commit
ebd4a02d2c
@ -19,10 +19,10 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var android_sdk_version = require('./templates/cordova/lib/android_sdk');
|
||||
var android_sdk = require('./templates/cordova/lib/android_sdk');
|
||||
|
||||
android_sdk_version.run().done(null, function(err) {
|
||||
console.log(err);
|
||||
android_sdk.print_newest_available_sdk_target.done(null, function(err) {
|
||||
console.error(err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
|
94
bin/templates/cordova/lib/android_sdk.js
vendored
94
bin/templates/cordova/lib/android_sdk.js
vendored
@ -19,47 +19,14 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var child_process = require('child_process'),
|
||||
Q = require('q');
|
||||
var Q = require('q'),
|
||||
superspawn = require('cordova-common').superspawn;
|
||||
|
||||
var get_highest_sdk = function(results){
|
||||
var reg = /\d+/;
|
||||
var apiLevels = [];
|
||||
for(var i=0;i<results.length;i++){
|
||||
apiLevels[i] = parseInt(results[i].match(reg)[0]);
|
||||
}
|
||||
apiLevels.sort(function(a,b){return b-a;});
|
||||
console.log(apiLevels[0]);
|
||||
};
|
||||
|
||||
var get_sdks = function() {
|
||||
var d = Q.defer();
|
||||
child_process.exec('android list targets', function(err, stdout, stderr) {
|
||||
if (err) d.reject(stderr);
|
||||
else d.resolve(stdout);
|
||||
module.exports.print_newest_available_sdk_target = function() {
|
||||
return module.exports.list_targets()
|
||||
.then(function(targets) {
|
||||
console.log(targets[0]);
|
||||
});
|
||||
|
||||
return d.promise.then(function(output) {
|
||||
var reg = /android-\d+/gi;
|
||||
var results = output.match(reg);
|
||||
if(results.length===0){
|
||||
return Q.reject(new Error('No android sdks installed.'));
|
||||
}else{
|
||||
get_highest_sdk(results);
|
||||
}
|
||||
|
||||
return Q();
|
||||
}, function(stderr) {
|
||||
if (stderr.match(/command\snot\sfound/) || stderr.match(/'android' is not recognized/)) {
|
||||
return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.'));
|
||||
} else {
|
||||
return Q.reject(new Error('An error occurred while listing Android targets'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.run = function() {
|
||||
return Q.all([get_sdks()]);
|
||||
};
|
||||
|
||||
module.exports.version_string_to_api_level = {
|
||||
@ -76,3 +43,52 @@ module.exports.version_string_to_api_level = {
|
||||
'7.0': 24,
|
||||
'7.1.1': 25
|
||||
};
|
||||
|
||||
module.exports.list_targets = function() {
|
||||
return superspawn.spawn('android', ['list', 'targets'])
|
||||
.then(function(stdout) {
|
||||
var target_out = stdout.split('\n');
|
||||
var targets = [];
|
||||
for (var i = target_out.length; i >= 0; i--) {
|
||||
if(target_out[i].match(/id:/)) {
|
||||
targets.push(targets[i].split(' ')[1]);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}).catch(function(err) {
|
||||
// there's a chance `android` no longer works.
|
||||
// lets see if `sdkmanager` is available and we can figure it out
|
||||
var avail_regex = /android command is no longer available/;
|
||||
if (err.code && (err.stdout.match(avail_regex) || err.stderr.match(avail_regex))) {
|
||||
return superspawn.spawn('sdkmanager', ['--list'], {capture: ['stdout', 'stderr']})
|
||||
.then(function(result) {
|
||||
var parsing_installed_packages = false;
|
||||
var lines = result.stdout.split('\n');
|
||||
var targets = [];
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
var line = lines[i];
|
||||
if (line.match(/Installed packages/)) {
|
||||
parsing_installed_packages = true;
|
||||
} else if (line.match(/Available Packages/) || line.match(/Available Updates/)) {
|
||||
// we are done working through installed packages, exit
|
||||
break;
|
||||
}
|
||||
if (parsing_installed_packages && line.match(/platforms;android-\d+/)) {
|
||||
targets.push(line.match(/android-\d+/)[0].split('-')[1]);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
} else throw err;
|
||||
}).then(function(targets) {
|
||||
if (targets.length === 0) {
|
||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||
} else {
|
||||
// Ensure we are working with integers
|
||||
targets = targets.map(function(t) { return parseInt(t); });
|
||||
// Sort them in descending order.
|
||||
targets.sort(function(a, b) { return b-a; });
|
||||
return targets;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
91
bin/templates/cordova/lib/check_reqs.js
vendored
91
bin/templates/cordova/lib/check_reqs.js
vendored
@ -30,6 +30,7 @@ var shelljs = require('shelljs'),
|
||||
REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'),
|
||||
PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
|
||||
|
||||
function forgivingWhichSync(cmd) {
|
||||
@ -83,10 +84,12 @@ module.exports.get_target = function() {
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_ant = function() {
|
||||
return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.')
|
||||
.then(function (output) {
|
||||
return superspawn.spawn('ant', ['-version'])
|
||||
.then(function(output) {
|
||||
// Parse Ant version from command output
|
||||
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
||||
}).catch(function(err) {
|
||||
throw new CordovaError("Failed to run `ant -version`. Make sure you have `ant` on your $PATH.");
|
||||
});
|
||||
};
|
||||
|
||||
@ -98,15 +101,14 @@ module.exports.get_gradle_wrapper = function() {
|
||||
androidStudioPath = path.join(process.env['ProgramFiles'],'Android', 'Android Studio', 'gradle');
|
||||
}
|
||||
|
||||
if(androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||
var dirs = fs.readdirSync(androidStudioPath);
|
||||
if(dirs[0].split('-')[0] == 'gradle')
|
||||
{
|
||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||
}
|
||||
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||
var dirs = fs.readdirSync(androidStudioPath);
|
||||
if(dirs[0].split('-')[0] == 'gradle') {
|
||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||
}
|
||||
} else {
|
||||
//OK, let's try to check for Gradle!
|
||||
return forgivingWhichSync('gradle');
|
||||
//OK, let's try to check for Gradle!
|
||||
return forgivingWhichSync('gradle');
|
||||
}
|
||||
};
|
||||
|
||||
@ -119,16 +121,15 @@ module.exports.check_gradle = function() {
|
||||
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
|
||||
|
||||
var gradlePath = module.exports.get_gradle_wrapper();
|
||||
if(gradlePath.length !== 0)
|
||||
d.resolve(gradlePath);
|
||||
if (gradlePath.length !== 0)
|
||||
d.resolve(gradlePath);
|
||||
else
|
||||
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
||||
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
||||
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
||||
'in your path, or install Android Studio'));
|
||||
return d.promise;
|
||||
};
|
||||
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.check_java = function() {
|
||||
var javacPath = forgivingWhichSync('javac');
|
||||
@ -141,12 +142,15 @@ module.exports.check_java = function() {
|
||||
}
|
||||
} else {
|
||||
if (javacPath) {
|
||||
var msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
|
||||
// OS X has a command for finding JAVA_HOME.
|
||||
if (fs.existsSync('/usr/libexec/java_home')) {
|
||||
return tryCommand('/usr/libexec/java_home', msg)
|
||||
var find_java = '/usr/libexec/java_home';
|
||||
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
|
||||
if (fs.existsSync(find_java)) {
|
||||
return superspawn.spawn(find_java)
|
||||
.then(function(stdout) {
|
||||
process.env['JAVA_HOME'] = stdout.trim();
|
||||
}).catch(function(err) {
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
});
|
||||
} else {
|
||||
// See if we can derive it from javac's location.
|
||||
@ -155,7 +159,7 @@ module.exports.check_java = function() {
|
||||
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||
process.env['JAVA_HOME'] = maybeJavaHome;
|
||||
} else {
|
||||
throw new CordovaError(msg);
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
}
|
||||
}
|
||||
} else if (module.exports.isWindows()) {
|
||||
@ -178,21 +182,21 @@ module.exports.check_java = function() {
|
||||
}
|
||||
}
|
||||
}).then(function() {
|
||||
var msg =
|
||||
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
||||
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
||||
if (process.env['JAVA_HOME']) {
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
||||
}
|
||||
// We use tryCommand with catchStderr = true, because
|
||||
// javac writes version info to stderr instead of stdout
|
||||
return tryCommand('javac -version', msg, true)
|
||||
.then(function (output) {
|
||||
//Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
||||
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
||||
return match && match[1];
|
||||
});
|
||||
var msg =
|
||||
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
||||
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
||||
if (process.env['JAVA_HOME']) {
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
||||
}
|
||||
// We use tryCommand with catchStderr = true, because
|
||||
// javac writes version info to stderr instead of stdout
|
||||
return tryCommand('javac -version', msg, true)
|
||||
.then(function (output) {
|
||||
//Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
||||
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
||||
return match && match[1];
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
@ -297,9 +301,11 @@ module.exports.check_android = function() {
|
||||
|
||||
module.exports.getAbsoluteAndroidCmd = function () {
|
||||
var cmd = forgivingWhichSync('android');
|
||||
if(cmd.length === 0)
|
||||
cmd = forgivingWhichSync('avdmanager');
|
||||
if (process.platform === 'win32') {
|
||||
// TODO: this probably needs to be `sdkmanager`, no?
|
||||
if (cmd.length === 0) {
|
||||
cmd = forgivingWhichSync('avdmanager');
|
||||
}
|
||||
if (module.exports.isWindows()) {
|
||||
return '"' + cmd + '"';
|
||||
}
|
||||
return cmd.replace(/(\s)/g, '\\$1');
|
||||
@ -314,13 +320,13 @@ module.exports.check_android_target = function(originalError) {
|
||||
var valid_target = module.exports.get_target();
|
||||
var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.';
|
||||
// Changing "targets" to "target" is stupid and makes more code. Thanks Google!
|
||||
var cmd = 'android list targets --compact';
|
||||
var cmd = 'android';
|
||||
// TODO: the following conditional needs fixing, probably should leverage `sdkmanager`
|
||||
// oh and tests
|
||||
if(forgivingWhichSync('avdmanager').length > 0)
|
||||
cmd = 'avdmanager list target --compact';
|
||||
return tryCommand(cmd, msg)
|
||||
.then(function(output) {
|
||||
if (forgivingWhichSync('avdmanager').length > 0)
|
||||
cmd = 'avdmanager';
|
||||
return superspawn.spawn(cmd, ['list', 'targets', '--compact'])
|
||||
.then(function(stdout) {
|
||||
var targets = output.split('\n');
|
||||
if (targets.indexOf(valid_target) >= 0) {
|
||||
return targets;
|
||||
@ -337,6 +343,11 @@ module.exports.check_android_target = function(originalError) {
|
||||
msg = originalError + '\n' + msg;
|
||||
}
|
||||
throw new CordovaError(msg);
|
||||
}).catch(function(err) {
|
||||
throw new CordovaError(msg);
|
||||
});
|
||||
return tryCommand(cmd, msg)
|
||||
.then(function(output) {
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user