mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-01 01:42:58 +08:00
CB-12640: support for android sdk tools 26.0.1. simplified target parsing by using avdmanager instead of sdkmanager. flipped target parsing logic so that it always tries to use avdmanager to retrieve targets first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests.
This commit is contained in:
parent
a4103d8dc8
commit
765c4ee9f6
75
bin/templates/cordova/lib/android_sdk.js
vendored
75
bin/templates/cordova/lib/android_sdk.js
vendored
@ -68,65 +68,38 @@ module.exports.version_string_to_api_level = {
|
|||||||
'7.1.1': 25
|
'7.1.1': 25
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets_with_android = function() {
|
function parse_targets(output) {
|
||||||
return superspawn.spawn('android', ['list', 'targets'])
|
var target_out = output.split('\n');
|
||||||
.then(function(stdout) {
|
var targets = [];
|
||||||
var target_out = stdout.split('\n');
|
for (var i = target_out.length - 1; i >= 0; i--) {
|
||||||
var targets = [];
|
if(target_out[i].match(/id:/)) { // if "id:" is in the line...
|
||||||
for (var i = target_out.length - 1; i >= 0; i--) {
|
targets.push(target_out[i].match(/"(.+)"/)[1]); //.. match whatever is in quotes.
|
||||||
if(target_out[i].match(/id:/)) {
|
|
||||||
targets.push(target_out[i].match(/"(.+)"/)[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return targets;
|
}
|
||||||
});
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.list_targets_with_android = function() {
|
||||||
|
return superspawn.spawn('android', ['list', 'target'])
|
||||||
|
.then(parse_targets);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets_with_sdkmanager = function() {
|
module.exports.list_targets_with_avdmanager = function() {
|
||||||
return superspawn.spawn('sdkmanager', ['--list'])
|
return superspawn.spawn('avdmanager', ['list', 'target'])
|
||||||
.then(function(stdout) {
|
.then(parse_targets);
|
||||||
var parsing_installed_packages = false;
|
|
||||||
var lines = 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) {
|
|
||||||
// Match stock android platform
|
|
||||||
if (line.match(/platforms;android-\d+/)) {
|
|
||||||
targets.push(line.match(/(android-\d+)/)[1]);
|
|
||||||
}
|
|
||||||
// Match Google APIs
|
|
||||||
if (line.match(/addon-google_apis-google-\d+/)) {
|
|
||||||
var description = lines[i + 1];
|
|
||||||
// munge description to match output from old android sdk tooling
|
|
||||||
var api_level = description.match(/Android (\d+)/); //[1];
|
|
||||||
if (api_level) {
|
|
||||||
targets.push('Google Inc.:Google APIs:' + api_level[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: match anything else?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return targets;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets = function() {
|
module.exports.list_targets = function() {
|
||||||
return module.exports.list_targets_with_android()
|
return module.exports.list_targets_with_avdmanager()
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
// there's a chance `android` no longer works.
|
// If there's an error, like avdmanager could not be found, we can try
|
||||||
// lets see if `sdkmanager` is available and we can figure it out
|
// as a last resort, to run `android`, in case this is a super old
|
||||||
var avail_regex = /"?android"? command is no longer available/;
|
// SDK installation.
|
||||||
if (err.code && ((err.stdout && err.stdout.match(avail_regex)) || (err.stderr && err.stderr.match(avail_regex)))) {
|
if (err && err.code == 'ENOENT') {
|
||||||
return module.exports.list_targets_with_sdkmanager();
|
return module.exports.list_targets_with_android();
|
||||||
} else throw err;
|
} else throw err;
|
||||||
}).then(function(targets) {
|
})
|
||||||
|
.then(function(targets) {
|
||||||
if (targets.length === 0) {
|
if (targets.length === 0) {
|
||||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||||
}
|
}
|
||||||
|
7
spec/fixtures/sdk25.3-avdmanager_list_target.txt
vendored
Normal file
7
spec/fixtures/sdk25.3-avdmanager_list_target.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Available Android targets:
|
||||||
|
----------
|
||||||
|
id: 1 or "android-25"
|
||||||
|
Name: Android API 25
|
||||||
|
Type: Platform
|
||||||
|
API level: 25
|
||||||
|
Revision: 3
|
1137
spec/fixtures/sdkmanager_list.txt
vendored
1137
spec/fixtures/sdkmanager_list.txt
vendored
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ describe("android_sdk", function () {
|
|||||||
it("should parse and return results from `android list targets` command", function(done) {
|
it("should parse and return results from `android list targets` command", function(done) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "android_list_targets.txt"), "utf-8"));
|
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.2-android_list_targets.txt"), "utf-8"));
|
||||||
return android_sdk.list_targets_with_android()
|
return android_sdk.list_targets_with_android()
|
||||||
.then(function(list) {
|
.then(function(list) {
|
||||||
[ "Google Inc.:Google APIs:23",
|
[ "Google Inc.:Google APIs:23",
|
||||||
@ -53,26 +53,14 @@ describe("android_sdk", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("list_targets_with_sdkmanager", function() {
|
describe("list_targets_with_avdmanager", function() {
|
||||||
it("should parse and return results from `sdkmanager --list` command", function(done) {
|
it("should parse and return results from `avdmanager list target` command", function(done) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdkmanager_list.txt"), "utf-8"));
|
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.3-avdmanager_list_target.txt"), "utf-8"));
|
||||||
return android_sdk.list_targets_with_sdkmanager()
|
return android_sdk.list_targets_with_avdmanager()
|
||||||
.then(function(list) {
|
.then(function(list) {
|
||||||
[ "Google Inc.:Google APIs:19",
|
expect(list).toContain("android-25");
|
||||||
"Google Inc.:Google APIs:21",
|
|
||||||
"Google Inc.:Google APIs:22",
|
|
||||||
"Google Inc.:Google APIs:23",
|
|
||||||
"Google Inc.:Google APIs:24",
|
|
||||||
"android-19",
|
|
||||||
"android-21",
|
|
||||||
"android-22",
|
|
||||||
"android-23",
|
|
||||||
"android-24",
|
|
||||||
"android-25" ].forEach(function(target) {
|
|
||||||
expect(list).toContain(target);
|
|
||||||
});
|
|
||||||
}).fail(function(err) {
|
}).fail(function(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
expect(err).toBeUndefined();
|
expect(err).toBeUndefined();
|
||||||
@ -82,25 +70,24 @@ describe("android_sdk", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("list_targets", function() {
|
describe("list_targets", function() {
|
||||||
it("should parse Android SDK installed target information with `android` command first", function() {
|
it("should parse Android SDK installed target information with `avdmanager` command first", function() {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var android_spy = spyOn(android_sdk, "list_targets_with_android").and.returnValue(deferred.promise);
|
var avdmanager_spy = spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||||
android_sdk.list_targets();
|
android_sdk.list_targets();
|
||||||
expect(android_spy).toHaveBeenCalled();
|
expect(avdmanager_spy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
it("should parse Android SDK installed target information with `avdmanager` command if list_targets_with_android fails due to `android` command being obsolete", function(done) {
|
it("should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with ENOENT", function(done) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
spyOn(android_sdk, "list_targets_with_android").and.returnValue(deferred.promise);
|
spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||||
deferred.reject({
|
deferred.reject({
|
||||||
code: 1,
|
code: "ENOENT"
|
||||||
stdout: "The android command is no longer available."
|
|
||||||
});
|
});
|
||||||
var twoferred = Q.defer();
|
var twoferred = Q.defer();
|
||||||
twoferred.resolve(["target1"]);
|
twoferred.resolve(["target1"]);
|
||||||
var sdkmanager_spy = spyOn(android_sdk, "list_targets_with_sdkmanager").and.returnValue(twoferred.promise);
|
var avdmanager_spy = spyOn(android_sdk, "list_targets_with_android").and.returnValue(twoferred.promise);
|
||||||
return android_sdk.list_targets()
|
return android_sdk.list_targets()
|
||||||
.then(function(targets) {
|
.then(function(targets) {
|
||||||
expect(sdkmanager_spy).toHaveBeenCalled();
|
expect(avdmanager_spy).toHaveBeenCalled();
|
||||||
expect(targets[0]).toEqual("target1");
|
expect(targets[0]).toEqual("target1");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -28,7 +28,7 @@ describe("emulator", function () {
|
|||||||
it("should properly parse details of SDK Tools 25.3.1 `avdmanager` output", function(done) {
|
it("should properly parse details of SDK Tools 25.3.1 `avdmanager` output", function(done) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
spyOn(cc.superspawn, "spawn").and.returnValue(deferred.promise);
|
spyOn(cc.superspawn, "spawn").and.returnValue(deferred.promise);
|
||||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "avdmanager_list_avd.txt"), "utf-8"));
|
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.3-avdmanager_list_avd.txt"), "utf-8"));
|
||||||
return emu.list_images_using_avdmanager()
|
return emu.list_images_using_avdmanager()
|
||||||
.then(function(list) {
|
.then(function(list) {
|
||||||
expect(list).toBeDefined();
|
expect(list).toBeDefined();
|
||||||
@ -47,7 +47,7 @@ describe("emulator", function () {
|
|||||||
it("should properly parse details of SDK Tools pre-25.3.1 `android list avd` output", function(done) {
|
it("should properly parse details of SDK Tools pre-25.3.1 `android list avd` output", function(done) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
spyOn(cc.superspawn, "spawn").and.returnValue(deferred.promise);
|
spyOn(cc.superspawn, "spawn").and.returnValue(deferred.promise);
|
||||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "android_list_avd.txt"), "utf-8"));
|
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.2-android_list_avd.txt"), "utf-8"));
|
||||||
return emu.list_images_using_android()
|
return emu.list_images_using_android()
|
||||||
.then(function(list) {
|
.then(function(list) {
|
||||||
expect(list).toBeDefined();
|
expect(list).toBeDefined();
|
||||||
|
Loading…
Reference in New Issue
Block a user