mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-07 23:03:11 +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.
|
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) {
|
android_sdk.print_newest_available_sdk_target.done(null, function(err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
process.exit(2);
|
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.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var child_process = require('child_process'),
|
var Q = require('q'),
|
||||||
Q = require('q');
|
superspawn = require('cordova-common').superspawn;
|
||||||
|
|
||||||
var get_highest_sdk = function(results){
|
module.exports.print_newest_available_sdk_target = function() {
|
||||||
var reg = /\d+/;
|
return module.exports.list_targets()
|
||||||
var apiLevels = [];
|
.then(function(targets) {
|
||||||
for(var i=0;i<results.length;i++){
|
console.log(targets[0]);
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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 = {
|
module.exports.version_string_to_api_level = {
|
||||||
@ -76,3 +43,52 @@ module.exports.version_string_to_api_level = {
|
|||||||
'7.0': 24,
|
'7.0': 24,
|
||||||
'7.1.1': 25
|
'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, '..', '..', '..', '..'),
|
REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'),
|
||||||
PROJECT_ROOT = path.join(__dirname, '..', '..');
|
PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
var superspawn = require('cordova-common').superspawn;
|
||||||
|
|
||||||
|
|
||||||
function forgivingWhichSync(cmd) {
|
function forgivingWhichSync(cmd) {
|
||||||
@ -83,10 +84,12 @@ module.exports.get_target = function() {
|
|||||||
|
|
||||||
// Returns a promise. Called only by build and clean commands.
|
// Returns a promise. Called only by build and clean commands.
|
||||||
module.exports.check_ant = function() {
|
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.')
|
return superspawn.spawn('ant', ['-version'])
|
||||||
.then(function (output) {
|
.then(function(output) {
|
||||||
// Parse Ant version from command output
|
// Parse Ant version from command output
|
||||||
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
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');
|
androidStudioPath = path.join(process.env['ProgramFiles'],'Android', 'Android Studio', 'gradle');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||||
var dirs = fs.readdirSync(androidStudioPath);
|
var dirs = fs.readdirSync(androidStudioPath);
|
||||||
if(dirs[0].split('-')[0] == 'gradle')
|
if(dirs[0].split('-')[0] == 'gradle') {
|
||||||
{
|
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//OK, let's try to check for Gradle!
|
//OK, let's try to check for Gradle!
|
||||||
return forgivingWhichSync('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.'));
|
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
|
||||||
|
|
||||||
var gradlePath = module.exports.get_gradle_wrapper();
|
var gradlePath = module.exports.get_gradle_wrapper();
|
||||||
if(gradlePath.length !== 0)
|
if (gradlePath.length !== 0)
|
||||||
d.resolve(gradlePath);
|
d.resolve(gradlePath);
|
||||||
else
|
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' +
|
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
||||||
'in your path, or install Android Studio'));
|
'in your path, or install Android Studio'));
|
||||||
return d.promise;
|
return d.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
module.exports.check_java = function() {
|
module.exports.check_java = function() {
|
||||||
var javacPath = forgivingWhichSync('javac');
|
var javacPath = forgivingWhichSync('javac');
|
||||||
@ -141,12 +142,15 @@ module.exports.check_java = function() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (javacPath) {
|
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.
|
// OS X has a command for finding JAVA_HOME.
|
||||||
if (fs.existsSync('/usr/libexec/java_home')) {
|
var find_java = '/usr/libexec/java_home';
|
||||||
return tryCommand('/usr/libexec/java_home', msg)
|
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) {
|
.then(function(stdout) {
|
||||||
process.env['JAVA_HOME'] = stdout.trim();
|
process.env['JAVA_HOME'] = stdout.trim();
|
||||||
|
}).catch(function(err) {
|
||||||
|
throw new CordovaError(default_java_error_msg);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// See if we can derive it from javac's location.
|
// 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'))) {
|
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||||
process.env['JAVA_HOME'] = maybeJavaHome;
|
process.env['JAVA_HOME'] = maybeJavaHome;
|
||||||
} else {
|
} else {
|
||||||
throw new CordovaError(msg);
|
throw new CordovaError(default_java_error_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (module.exports.isWindows()) {
|
} else if (module.exports.isWindows()) {
|
||||||
@ -178,21 +182,21 @@ module.exports.check_java = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
var msg =
|
var msg =
|
||||||
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
'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';
|
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
||||||
if (process.env['JAVA_HOME']) {
|
if (process.env['JAVA_HOME']) {
|
||||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
||||||
}
|
}
|
||||||
// We use tryCommand with catchStderr = true, because
|
// We use tryCommand with catchStderr = true, because
|
||||||
// javac writes version info to stderr instead of stdout
|
// javac writes version info to stderr instead of stdout
|
||||||
return tryCommand('javac -version', msg, true)
|
return tryCommand('javac -version', msg, true)
|
||||||
.then(function (output) {
|
.then(function (output) {
|
||||||
//Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
//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);
|
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
||||||
return match && match[1];
|
return match && match[1];
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
@ -297,9 +301,11 @@ module.exports.check_android = function() {
|
|||||||
|
|
||||||
module.exports.getAbsoluteAndroidCmd = function () {
|
module.exports.getAbsoluteAndroidCmd = function () {
|
||||||
var cmd = forgivingWhichSync('android');
|
var cmd = forgivingWhichSync('android');
|
||||||
if(cmd.length === 0)
|
// TODO: this probably needs to be `sdkmanager`, no?
|
||||||
cmd = forgivingWhichSync('avdmanager');
|
if (cmd.length === 0) {
|
||||||
if (process.platform === 'win32') {
|
cmd = forgivingWhichSync('avdmanager');
|
||||||
|
}
|
||||||
|
if (module.exports.isWindows()) {
|
||||||
return '"' + cmd + '"';
|
return '"' + cmd + '"';
|
||||||
}
|
}
|
||||||
return cmd.replace(/(\s)/g, '\\$1');
|
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 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.';
|
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!
|
// 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`
|
// TODO: the following conditional needs fixing, probably should leverage `sdkmanager`
|
||||||
// oh and tests
|
// oh and tests
|
||||||
if(forgivingWhichSync('avdmanager').length > 0)
|
if (forgivingWhichSync('avdmanager').length > 0)
|
||||||
cmd = 'avdmanager list target --compact';
|
cmd = 'avdmanager';
|
||||||
return tryCommand(cmd, msg)
|
return superspawn.spawn(cmd, ['list', 'targets', '--compact'])
|
||||||
.then(function(output) {
|
.then(function(stdout) {
|
||||||
var targets = output.split('\n');
|
var targets = output.split('\n');
|
||||||
if (targets.indexOf(valid_target) >= 0) {
|
if (targets.indexOf(valid_target) >= 0) {
|
||||||
return targets;
|
return targets;
|
||||||
@ -337,6 +343,11 @@ module.exports.check_android_target = function(originalError) {
|
|||||||
msg = originalError + '\n' + msg;
|
msg = originalError + '\n' + msg;
|
||||||
}
|
}
|
||||||
throw new CordovaError(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