mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-07 14:53:00 +08:00
refactor!: drop support for android
SDK tool (#1083)
* refactor(emulator)!: remove support for legacy `android` binary `emulator.list_images` now always uses the `avdmanager` binary. * refactor(android_sdk)!: remove support for legacy `android` binary `android_sdk.list_targets` now always uses the `avdmanager` binary. * refactor(check_reqs)!: do not look for legacy `android` binary * refactor: replace installation instructions involving `android` binary
This commit is contained in:
parent
2a92c77772
commit
9c3195c1ee
13
bin/templates/cordova/lib/android_sdk.js
vendored
13
bin/templates/cordova/lib/android_sdk.js
vendored
@ -76,23 +76,12 @@ function parse_targets (output) {
|
|||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.list_targets_with_android = function () {
|
|
||||||
return execa('android', ['list', 'target']).then(result => parse_targets(result.stdout));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.list_targets_with_avdmanager = function () {
|
module.exports.list_targets_with_avdmanager = function () {
|
||||||
return execa('avdmanager', ['list', 'target']).then(result => parse_targets(result.stdout));
|
return execa('avdmanager', ['list', 'target']).then(result => parse_targets(result.stdout));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets = function () {
|
module.exports.list_targets = function () {
|
||||||
return module.exports.list_targets_with_avdmanager().catch(function (err) {
|
return module.exports.list_targets_with_avdmanager().then(function (targets) {
|
||||||
// If there's an error, like avdmanager could not be found, we can try
|
|
||||||
// as a last resort, to run `android`, in case this is a super old
|
|
||||||
// SDK installation.
|
|
||||||
if (err && (err.code === 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
|
|
||||||
return module.exports.list_targets_with_android();
|
|
||||||
} else throw err;
|
|
||||||
}).then(function (targets) {
|
|
||||||
if (targets.length === 0) {
|
if (targets.length === 0) {
|
||||||
return Promise.reject(new Error('No android targets (SDKs) installed!'));
|
return Promise.reject(new Error('No android targets (SDKs) installed!'));
|
||||||
}
|
}
|
||||||
|
37
bin/templates/cordova/lib/check_reqs.js
vendored
37
bin/templates/cordova/lib/check_reqs.js
vendored
@ -161,7 +161,6 @@ module.exports.check_android = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var androidCmdPath = forgivingWhichSync('android');
|
|
||||||
var adbInPath = forgivingWhichSync('adb');
|
var adbInPath = forgivingWhichSync('adb');
|
||||||
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
||||||
var hasAndroidHome = false;
|
var hasAndroidHome = false;
|
||||||
@ -172,7 +171,7 @@ module.exports.check_android = function () {
|
|||||||
|
|
||||||
// First ensure ANDROID_HOME is set
|
// First ensure ANDROID_HOME is set
|
||||||
// If we have no hints (nothing in PATH), try a few default locations
|
// If we have no hints (nothing in PATH), try a few default locations
|
||||||
if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
|
if (!hasAndroidHome && !adbInPath && !avdmanagerInPath) {
|
||||||
if (process.env.ANDROID_HOME) {
|
if (process.env.ANDROID_HOME) {
|
||||||
// Fallback to deprecated `ANDROID_HOME` variable
|
// Fallback to deprecated `ANDROID_HOME` variable
|
||||||
maybeSetAndroidHome(path.join(process.env.ANDROID_HOME));
|
maybeSetAndroidHome(path.join(process.env.ANDROID_HOME));
|
||||||
@ -222,17 +221,6 @@ module.exports.check_android = function () {
|
|||||||
if (!hasAndroidHome) {
|
if (!hasAndroidHome) {
|
||||||
// If we dont have ANDROID_SDK_ROOT, but we do have some tools on the PATH, try to infer from the tooling PATH.
|
// If we dont have ANDROID_SDK_ROOT, but we do have some tools on the PATH, try to infer from the tooling PATH.
|
||||||
var parentDir, grandParentDir;
|
var parentDir, grandParentDir;
|
||||||
if (androidCmdPath) {
|
|
||||||
parentDir = path.dirname(androidCmdPath);
|
|
||||||
grandParentDir = path.dirname(parentDir);
|
|
||||||
if (path.basename(parentDir) === 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
|
||||||
maybeSetAndroidHome(grandParentDir);
|
|
||||||
} else {
|
|
||||||
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
|
|
||||||
'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
|
|
||||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (adbInPath) {
|
if (adbInPath) {
|
||||||
parentDir = path.dirname(adbInPath);
|
parentDir = path.dirname(adbInPath);
|
||||||
grandParentDir = path.dirname(parentDir);
|
grandParentDir = path.dirname(parentDir);
|
||||||
@ -265,9 +253,6 @@ module.exports.check_android = function () {
|
|||||||
'\nTry update it manually to point to valid SDK directory.');
|
'\nTry update it manually to point to valid SDK directory.');
|
||||||
}
|
}
|
||||||
// Next let's make sure relevant parts of the SDK tooling is in our PATH
|
// Next let's make sure relevant parts of the SDK tooling is in our PATH
|
||||||
if (hasAndroidHome && !androidCmdPath) {
|
|
||||||
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'tools');
|
|
||||||
}
|
|
||||||
if (hasAndroidHome && !adbInPath) {
|
if (hasAndroidHome && !adbInPath) {
|
||||||
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'platform-tools');
|
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'platform-tools');
|
||||||
}
|
}
|
||||||
@ -278,18 +263,6 @@ module.exports.check_android = function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: is this actually needed?
|
|
||||||
module.exports.getAbsoluteAndroidCmd = function () {
|
|
||||||
var cmd = forgivingWhichSync('android');
|
|
||||||
if (cmd.length === 0) {
|
|
||||||
cmd = forgivingWhichSync('sdkmanager');
|
|
||||||
}
|
|
||||||
if (module.exports.isWindows()) {
|
|
||||||
return '"' + cmd + '"';
|
|
||||||
}
|
|
||||||
return cmd.replace(/(\s)/g, '\\$1');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.check_android_target = function (originalError) {
|
module.exports.check_android_target = function (originalError) {
|
||||||
// valid_target can look like:
|
// valid_target can look like:
|
||||||
// android-19
|
// android-19
|
||||||
@ -301,13 +274,7 @@ module.exports.check_android_target = function (originalError) {
|
|||||||
if (targets.indexOf(desired_api_level) >= 0) {
|
if (targets.indexOf(desired_api_level) >= 0) {
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
var androidCmd = module.exports.getAbsoluteAndroidCmd();
|
var msg = `Please install the Android SDK Platform "platforms;${desired_api_level}"`;
|
||||||
var msg = 'Please install Android target / API level: "' + desired_api_level + '".\n\n' +
|
|
||||||
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
|
|
||||||
'You will require:\n' +
|
|
||||||
'1. "SDK Platform" for API level ' + desired_api_level + '\n' +
|
|
||||||
'2. "Android SDK Platform-tools (latest)\n' +
|
|
||||||
'3. "Android SDK Build-tools" (latest)';
|
|
||||||
if (originalError) {
|
if (originalError) {
|
||||||
msg = originalError + '\n' + msg;
|
msg = originalError + '\n' + msg;
|
||||||
}
|
}
|
||||||
|
52
bin/templates/cordova/lib/emulator.js
vendored
52
bin/templates/cordova/lib/emulator.js
vendored
@ -99,48 +99,6 @@ module.exports.list_images_using_avdmanager = function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_images_using_android = function () {
|
|
||||||
return execa('android', ['list', 'avd']).then(({ stdout: output }) => {
|
|
||||||
var response = output.split('\n');
|
|
||||||
var emulator_list = [];
|
|
||||||
for (var i = 1; i < response.length; i++) {
|
|
||||||
// To return more detailed information use img_obj
|
|
||||||
var img_obj = {};
|
|
||||||
if (response[i].match(/Name:\s/)) {
|
|
||||||
img_obj.name = response[i].split('Name: ')[1].replace('\r', '');
|
|
||||||
if (response[i + 1].match(/Device:\s/)) {
|
|
||||||
i++;
|
|
||||||
img_obj.device = response[i].split('Device: ')[1].replace('\r', '');
|
|
||||||
}
|
|
||||||
if (response[i + 1].match(/Path:\s/)) {
|
|
||||||
i++;
|
|
||||||
img_obj.path = response[i].split('Path: ')[1].replace('\r', '');
|
|
||||||
}
|
|
||||||
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
|
|
||||||
i++;
|
|
||||||
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
|
|
||||||
img_obj.target = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
|
|
||||||
}
|
|
||||||
if (response[i + 1].match(/ABI:\s/)) {
|
|
||||||
i++;
|
|
||||||
img_obj.abi = response[i].split('ABI: ')[1].replace('\r', '');
|
|
||||||
}
|
|
||||||
if (response[i + 1].match(/Skin:\s/)) {
|
|
||||||
i++;
|
|
||||||
img_obj.skin = response[i].split('Skin: ')[1].replace('\r', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
emulator_list.push(img_obj);
|
|
||||||
}
|
|
||||||
/* To just return a list of names use this
|
|
||||||
if (response[i].match(/Name:\s/)) {
|
|
||||||
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
return emulator_list;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Promise for a list of emulator images in the form of objects
|
* Returns a Promise for a list of emulator images in the form of objects
|
||||||
* {
|
* {
|
||||||
@ -156,10 +114,8 @@ module.exports.list_images = function () {
|
|||||||
return Promise.resolve().then(function () {
|
return Promise.resolve().then(function () {
|
||||||
if (forgivingWhichSync('avdmanager')) {
|
if (forgivingWhichSync('avdmanager')) {
|
||||||
return module.exports.list_images_using_avdmanager();
|
return module.exports.list_images_using_avdmanager();
|
||||||
} else if (forgivingWhichSync('android')) {
|
|
||||||
return module.exports.list_images_using_android();
|
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?'));
|
return Promise.reject(new CordovaError('Could not find `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?'));
|
||||||
}
|
}
|
||||||
}).then(function (avds) {
|
}).then(function (avds) {
|
||||||
// In case we're missing the Android OS version string from the target description, add it.
|
// In case we're missing the Android OS version string from the target description, add it.
|
||||||
@ -252,11 +208,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
|
|||||||
return best.name;
|
return best.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
|
return Promise.reject(new CordovaError('No emulator images (avds) found'));
|
||||||
return Promise.reject(new CordovaError('No emulator images (avds) found.\n' +
|
|
||||||
'1. Download desired System Image by running: ' + androidCmd + ' sdk\n' +
|
|
||||||
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
|
|
||||||
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
|
|
||||||
});
|
});
|
||||||
}).then(function (emulatorId) {
|
}).then(function (emulatorId) {
|
||||||
return self.get_available_port().then(function (port) {
|
return self.get_available_port().then(function (port) {
|
||||||
|
7
spec/fixtures/sdk25.2-android_list_avd.txt
vendored
7
spec/fixtures/sdk25.2-android_list_avd.txt
vendored
@ -1,7 +0,0 @@
|
|||||||
Available Android Virtual Devices:
|
|
||||||
Name: QWR
|
|
||||||
Device: Nexus 5 (Google)
|
|
||||||
Path: /Users/shazron/.android/avd/QWR.avd
|
|
||||||
Target: Android 7.1.1 (API level 25)
|
|
||||||
Tag/ABI: google_apis/x86_64
|
|
||||||
Skin: 1080x1920
|
|
116
spec/fixtures/sdk25.2-android_list_targets.txt
vendored
116
spec/fixtures/sdk25.2-android_list_targets.txt
vendored
@ -1,116 +0,0 @@
|
|||||||
Available Android targets:
|
|
||||||
----------
|
|
||||||
id: 1 or "android-20"
|
|
||||||
Name: Android 4.4W.2
|
|
||||||
Type: Platform
|
|
||||||
API level: 20
|
|
||||||
Revision: 2
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : no ABIs.
|
|
||||||
----------
|
|
||||||
id: 2 or "android-21"
|
|
||||||
Name: Android 5.0.1
|
|
||||||
Type: Platform
|
|
||||||
API level: 21
|
|
||||||
Revision: 2
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/armeabi-v7a, default/x86, default/x86_64
|
|
||||||
----------
|
|
||||||
id: 3 or "android-22"
|
|
||||||
Name: Android 5.1.1
|
|
||||||
Type: Platform
|
|
||||||
API level: 22
|
|
||||||
Revision: 2
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/armeabi-v7a, default/x86, default/x86_64
|
|
||||||
----------
|
|
||||||
id: 4 or "android-MNC"
|
|
||||||
Name: Android M (Preview)
|
|
||||||
Type: Platform
|
|
||||||
API level: MNC
|
|
||||||
Revision: 1
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : no ABIs.
|
|
||||||
----------
|
|
||||||
id: 5 or "android-23"
|
|
||||||
Name: Android 6.0
|
|
||||||
Type: Platform
|
|
||||||
API level: 23
|
|
||||||
Revision: 3
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : android-tv/armeabi-v7a, android-tv/x86, default/x86, default/x86_64
|
|
||||||
----------
|
|
||||||
id: 6 or "android-N"
|
|
||||||
Name: Android N (Preview)
|
|
||||||
Type: Platform
|
|
||||||
API level: N
|
|
||||||
Revision: 3
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : no ABIs.
|
|
||||||
----------
|
|
||||||
id: 7 or "android-24"
|
|
||||||
Name: Android 7.0
|
|
||||||
Type: Platform
|
|
||||||
API level: 24
|
|
||||||
Revision: 2
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : android-tv/x86, default/x86, default/x86_64
|
|
||||||
----------
|
|
||||||
id: 8 or "android-25"
|
|
||||||
Name: Android 7.1.1
|
|
||||||
Type: Platform
|
|
||||||
API level: 25
|
|
||||||
Revision: 3
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : android-tv/x86, google_apis/x86, google_apis/x86_64
|
|
||||||
----------
|
|
||||||
id: 9 or "Google Inc.:Google APIs:21"
|
|
||||||
Name: Google APIs
|
|
||||||
Type: Add-On
|
|
||||||
Vendor: Google Inc.
|
|
||||||
Revision: 1
|
|
||||||
Description: Android + Google APIs
|
|
||||||
Based on Android 5.0.1 (API level 21)
|
|
||||||
Libraries:
|
|
||||||
* com.android.future.usb.accessory (usb.jar)
|
|
||||||
API for USB Accessories
|
|
||||||
* com.google.android.media.effects (effects.jar)
|
|
||||||
Collection of video effects
|
|
||||||
* com.google.android.maps (maps.jar)
|
|
||||||
API for Google Maps
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
|
||||||
----------
|
|
||||||
id: 10 or "Google Inc.:Google APIs:22"
|
|
||||||
Name: Google APIs
|
|
||||||
Type: Add-On
|
|
||||||
Vendor: Google Inc.
|
|
||||||
Revision: 1
|
|
||||||
Description: Android + Google APIs
|
|
||||||
Based on Android 5.1.1 (API level 22)
|
|
||||||
Libraries:
|
|
||||||
* com.android.future.usb.accessory (usb.jar)
|
|
||||||
API for USB Accessories
|
|
||||||
* com.google.android.media.effects (effects.jar)
|
|
||||||
Collection of video effects
|
|
||||||
* com.google.android.maps (maps.jar)
|
|
||||||
API for Google Maps
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
|
||||||
----------
|
|
||||||
id: 11 or "Google Inc.:Google APIs:23"
|
|
||||||
Name: Google APIs
|
|
||||||
Type: Add-On
|
|
||||||
Vendor: Google Inc.
|
|
||||||
Revision: 1
|
|
||||||
Description: Android + Google APIs
|
|
||||||
Based on Android 6.0 (API level 23)
|
|
||||||
Libraries:
|
|
||||||
* com.android.future.usb.accessory (usb.jar)
|
|
||||||
API for USB Accessories
|
|
||||||
* com.google.android.media.effects (effects.jar)
|
|
||||||
Collection of video effects
|
|
||||||
* com.google.android.maps (maps.jar)
|
|
||||||
API for Google Maps
|
|
||||||
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
|
|
||||||
Tag/ABIs : google_apis/armeabi-v7a, google_apis/x86, google_apis/x86_64
|
|
@ -66,33 +66,6 @@ describe('android_sdk', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('list_targets_with_android', () => {
|
|
||||||
it('should invoke `android` with the `list target` command and _not_ the `list targets` command, as the plural form is not supported in some Android SDK Tools versions', () => {
|
|
||||||
execaSpy.and.returnValue(Promise.resolve({ stdout: '' }));
|
|
||||||
android_sdk.list_targets_with_android();
|
|
||||||
expect(execaSpy).toHaveBeenCalledWith('android', ['list', 'target']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse and return results from `android list targets` command', () => {
|
|
||||||
const testTargets = fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_targets.txt'), 'utf-8');
|
|
||||||
execaSpy.and.returnValue(Promise.resolve({ stdout: testTargets }));
|
|
||||||
|
|
||||||
return android_sdk.list_targets_with_android().then(list => {
|
|
||||||
['Google Inc.:Google APIs:23',
|
|
||||||
'Google Inc.:Google APIs:22',
|
|
||||||
'Google Inc.:Google APIs:21',
|
|
||||||
'android-25',
|
|
||||||
'android-24',
|
|
||||||
'android-N',
|
|
||||||
'android-23',
|
|
||||||
'android-MNC',
|
|
||||||
'android-22',
|
|
||||||
'android-21',
|
|
||||||
'android-20'].forEach((target) => expect(list).toContain(target));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('list_targets_with_avdmanager', () => {
|
describe('list_targets_with_avdmanager', () => {
|
||||||
it('should parse and return results from `avdmanager list target` command', () => {
|
it('should parse and return results from `avdmanager list target` command', () => {
|
||||||
const testTargets = fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_target.txt'), 'utf-8');
|
const testTargets = fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_target.txt'), 'utf-8');
|
||||||
@ -111,29 +84,6 @@ describe('android_sdk', () => {
|
|||||||
expect(avdmanager_spy).toHaveBeenCalled();
|
expect(avdmanager_spy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with ENOENT', () => {
|
|
||||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(Promise.reject({ code: 'ENOENT' }));
|
|
||||||
const avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(Promise.resolve(['target1']));
|
|
||||||
|
|
||||||
return android_sdk.list_targets().then(targets => {
|
|
||||||
expect(avdmanager_spy).toHaveBeenCalled();
|
|
||||||
expect(targets[0]).toEqual('target1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with not-recognized error (Windows)', () => {
|
|
||||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(Promise.reject({
|
|
||||||
code: 1,
|
|
||||||
stderr: "'avdmanager' is not recognized as an internal or external commmand,\r\noperable program or batch file.\r\n"
|
|
||||||
}));
|
|
||||||
|
|
||||||
const avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(Promise.resolve(['target1']));
|
|
||||||
return android_sdk.list_targets().then(targets => {
|
|
||||||
expect(avdmanager_spy).toHaveBeenCalled();
|
|
||||||
expect(targets[0]).toEqual('target1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if `avdmanager` command fails with an unknown error', () => {
|
it('should throw an error if `avdmanager` command fails with an unknown error', () => {
|
||||||
const errorMsg = 'Some random error';
|
const errorMsg = 'Some random error';
|
||||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(Promise.reject(errorMsg));
|
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(Promise.reject(errorMsg));
|
||||||
|
@ -100,34 +100,6 @@ describe('check_reqs', function () {
|
|||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should set ANDROID_SDK_ROOT based on `android` command if command exists in a SDK-like directory structure', () => {
|
|
||||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
|
||||||
spyOn(which, 'sync').and.callFake(function (cmd) {
|
|
||||||
if (cmd === 'android') {
|
|
||||||
return '/android/sdk/tools/android';
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return check_reqs.check_android().then(function () {
|
|
||||||
expect(process.env.ANDROID_SDK_ROOT).toEqual('/android/sdk');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('should error out if `android` command exists in a non-SDK-like directory structure', () => {
|
|
||||||
spyOn(which, 'sync').and.callFake(function (cmd) {
|
|
||||||
if (cmd === 'android') {
|
|
||||||
return '/just/some/random/path/android';
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return check_reqs.check_android().then(() => {
|
|
||||||
fail('Expected promise to be rejected');
|
|
||||||
}, err => {
|
|
||||||
expect(err).toEqual(jasmine.any(Error));
|
|
||||||
expect(err.message).toContain('update your PATH to include valid path');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('should set ANDROID_SDK_ROOT based on `adb` command if command exists in a SDK-like directory structure', () => {
|
it('should set ANDROID_SDK_ROOT based on `adb` command if command exists in a SDK-like directory structure', () => {
|
||||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||||
spyOn(which, 'sync').and.callFake(function (cmd) {
|
spyOn(which, 'sync').and.callFake(function (cmd) {
|
||||||
@ -398,7 +370,7 @@ describe('check_reqs', function () {
|
|||||||
fail('Expected promise to be rejected');
|
fail('Expected promise to be rejected');
|
||||||
}, err => {
|
}, err => {
|
||||||
expect(err).toEqual(jasmine.any(Error));
|
expect(err).toEqual(jasmine.any(Error));
|
||||||
expect(err.message).toContain('Please install Android target');
|
expect(err.message).toContain('Please install the Android SDK Platform');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -49,33 +49,6 @@ describe('emulator', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('list_images_using_android', () => {
|
|
||||||
it('should invoke `android` with the `list avd` command and _not_ the `list avds` command, as the plural form is not supported in some Android SDK Tools versions', () => {
|
|
||||||
const execaSpy = jasmine.createSpy('execa').and.returnValue(Promise.resolve({ stdout: '' }));
|
|
||||||
emu.__set__('execa', execaSpy);
|
|
||||||
|
|
||||||
emu.list_images_using_android();
|
|
||||||
expect(execaSpy).toHaveBeenCalledWith('android', ['list', 'avd']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should properly parse details of SDK Tools pre-25.3.1 `android list avd` output', () => {
|
|
||||||
const avdList = fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_avd.txt'), 'utf-8');
|
|
||||||
|
|
||||||
const execaSpy = jasmine.createSpy('execa').and.returnValue(Promise.resolve({ stdout: avdList }));
|
|
||||||
emu.__set__('execa', execaSpy);
|
|
||||||
|
|
||||||
return emu.list_images_using_android().then(list => {
|
|
||||||
expect(list).toBeDefined();
|
|
||||||
expect(list[0].name).toEqual('QWR');
|
|
||||||
expect(list[0].device).toEqual('Nexus 5 (Google)');
|
|
||||||
expect(list[0].path).toEqual('/Users/shazron/.android/avd/QWR.avd');
|
|
||||||
expect(list[0].target).toEqual('Android 7.1.1 (API level 25)');
|
|
||||||
expect(list[0].abi).toEqual('google_apis/x86_64');
|
|
||||||
expect(list[0].skin).toEqual('1080x1920');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('list_images', () => {
|
describe('list_images', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(fs, 'realpathSync').and.callFake(cmd => cmd);
|
spyOn(fs, 'realpathSync').and.callFake(cmd => cmd);
|
||||||
@ -91,16 +64,6 @@ describe('emulator', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delegate to `android` if `avdmanager` cant be found and `android` can', () => {
|
|
||||||
spyOn(which, 'sync').and.callFake(cmd => cmd !== 'avdmanager');
|
|
||||||
|
|
||||||
const android_spy = spyOn(emu, 'list_images_using_android').and.returnValue(Promise.resolve([]));
|
|
||||||
|
|
||||||
return emu.list_images().then(() => {
|
|
||||||
expect(android_spy).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correct api level information and fill in the blanks about api level if exists', () => {
|
it('should correct api level information and fill in the blanks about api level if exists', () => {
|
||||||
spyOn(which, 'sync').and.callFake(cmd => cmd === 'avdmanager');
|
spyOn(which, 'sync').and.callFake(cmd => cmd === 'avdmanager');
|
||||||
spyOn(emu, 'list_images_using_avdmanager').and.returnValue(Promise.resolve([
|
spyOn(emu, 'list_images_using_avdmanager').and.returnValue(Promise.resolve([
|
||||||
@ -132,7 +95,7 @@ describe('emulator', () => {
|
|||||||
() => fail('Unexpectedly resolved'),
|
() => fail('Unexpectedly resolved'),
|
||||||
err => {
|
err => {
|
||||||
expect(err).toBeDefined();
|
expect(err).toBeDefined();
|
||||||
expect(err.message).toContain('Could not find either `android` or `avdmanager`');
|
expect(err.message).toContain('Could not find `avdmanager`');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -252,7 +215,6 @@ describe('emulator', () => {
|
|||||||
const port = 5555;
|
const port = 5555;
|
||||||
let emulator;
|
let emulator;
|
||||||
let AdbSpy;
|
let AdbSpy;
|
||||||
let checkReqsSpy;
|
|
||||||
let execaSpy;
|
let execaSpy;
|
||||||
let whichSpy;
|
let whichSpy;
|
||||||
|
|
||||||
@ -269,9 +231,6 @@ describe('emulator', () => {
|
|||||||
AdbSpy.shell.and.returnValue(Promise.resolve());
|
AdbSpy.shell.and.returnValue(Promise.resolve());
|
||||||
emu.__set__('Adb', AdbSpy);
|
emu.__set__('Adb', AdbSpy);
|
||||||
|
|
||||||
checkReqsSpy = jasmine.createSpyObj('create_reqs', ['getAbsoluteAndroidCmd']);
|
|
||||||
emu.__set__('check_reqs', checkReqsSpy);
|
|
||||||
|
|
||||||
execaSpy = jasmine.createSpy('execa').and.returnValue(
|
execaSpy = jasmine.createSpy('execa').and.returnValue(
|
||||||
jasmine.createSpyObj('spawnFns', ['unref'])
|
jasmine.createSpyObj('spawnFns', ['unref'])
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user