Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: set & use ANDROID_HOME as default #1444

Merged
merged 8 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 15 additions & 15 deletions lib/check_reqs.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ module.exports.get_gradle_wrapper = function () {

// Returns a promise. Called only by build and clean commands.
module.exports.check_gradle = function () {
const sdkDir = process.env.ANDROID_SDK_ROOT || process.env.ANDROID_HOME;
const sdkDir = process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT;
if (!sdkDir) {
return Promise.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
'Might need to install Android SDK or set up \'ANDROID_SDK_ROOT\' env variable.'));
Expand Down Expand Up @@ -179,15 +179,15 @@ module.exports.check_android = function () {
function maybeSetAndroidHome (value) {
if (!hasAndroidHome && fs.existsSync(value)) {
hasAndroidHome = true;
process.env.ANDROID_SDK_ROOT = value;
process.env.ANDROID_HOME = value;
}
}

const adbInPath = forgivingWhichSync('adb');
const avdmanagerInPath = forgivingWhichSync('avdmanager');

if (process.env.ANDROID_SDK_ROOT) {
maybeSetAndroidHome(path.resolve(process.env.ANDROID_SDK_ROOT));
if (process.env.ANDROID_HOME) {
maybeSetAndroidHome(path.resolve(process.env.ANDROID_HOME));
}

// First ensure ANDROID_HOME is set
Expand Down Expand Up @@ -240,15 +240,15 @@ module.exports.check_android = function () {
}

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_HOME, but we do have some tools on the PATH, try to infer from the tooling PATH.
let parentDir, grandParentDir;
if (adbInPath) {
parentDir = path.dirname(adbInPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) === 'platform-tools') {
maybeSetAndroidHome(grandParentDir);
} else {
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
}
Expand All @@ -259,26 +259,26 @@ module.exports.check_android = function () {
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
maybeSetAndroidHome(path.dirname(grandParentDir));
} else {
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
}
}
}
if (!process.env.ANDROID_SDK_ROOT) {
throw new CordovaError('Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
if (!process.env.ANDROID_HOME) {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
}
if (!fs.existsSync(process.env.ANDROID_SDK_ROOT)) {
throw new CordovaError('\'ANDROID_SDK_ROOT\' environment variable is set to non-existent path: ' + process.env.ANDROID_SDK_ROOT +
if (!fs.existsSync(process.env.ANDROID_HOME)) {
throw new CordovaError('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env.ANDROID_SDK_ROOT +
'\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
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_HOME, 'platform-tools');
}
if (hasAndroidHome && !avdmanagerInPath) {
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_SDK_ROOT, 'tools', 'bin');
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_HOME, 'tools', 'bin');
}
return hasAndroidHome;
});
Expand All @@ -302,8 +302,8 @@ module.exports.check_android_target = function (projectRoot) {
// Returns a promise.
module.exports.run = function () {
console.log('Checking Java JDK and Android SDK versions');
console.log('ANDROID_SDK_ROOT=' + process.env.ANDROID_SDK_ROOT + ' (recommended setting)');
console.log('ANDROID_HOME=' + process.env.ANDROID_HOME + ' (DEPRECATED)');
console.log('ANDROID_HOME=' + process.env.ANDROID_HOME + ' (recommended setting)');
console.log('ANDROID_SDK_ROOT=' + process.env.ANDROID_SDK_ROOT + ' (DEPRECATED)');

return Promise.all([this.check_java(), this.check_android()]).then(function (values) {
console.log('Using Android SDK: ' + process.env.ANDROID_SDK_ROOT);
Expand Down
58 changes: 29 additions & 29 deletions spec/unit/check_reqs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,20 @@ describe('check_reqs', function () {
spyOn(which, 'sync').and.returnValue(null);
spyOn(fs, 'existsSync').and.returnValue(true);
});
it('it should set ANDROID_SDK_ROOT on Windows', () => {
it('it should set ANDROID_HOME on Windows', () => {
spyOn(check_reqs, 'isWindows').and.returnValue(true);
process.env.LOCALAPPDATA = 'windows-local-app-data';
process.env.ProgramFiles = 'windows-program-files';
return check_reqs.check_android().then(function () {
expect(process.env.ANDROID_SDK_ROOT).toContain('windows-local-app-data');
expect(process.env.ANDROID_HOME).toContain('windows-local-app-data');
});
});
it('it should set ANDROID_SDK_ROOT on Darwin', () => {
it('it should set ANDROID_HOME on Darwin', () => {
spyOn(check_reqs, 'isWindows').and.returnValue(false);
spyOn(check_reqs, 'isDarwin').and.returnValue(true);
process.env.HOME = 'home is where the heart is';
return check_reqs.check_android().then(function () {
expect(process.env.ANDROID_SDK_ROOT).toContain('home is where the heart is');
expect(process.env.ANDROID_HOME).toContain('home is where the heart is');
});
});
});
Expand All @@ -91,17 +91,17 @@ describe('check_reqs', function () {
return path;
});
});
it('should set ANDROID_SDK_ROOT based on `adb` command if command exists in a SDK-like directory structure', () => {
it('should set ANDROID_HOME based on `adb` 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 === 'adb') {
return '/android/sdk/platform-tools/adb';
return path.normalize('/android/sdk/platform-tools/adb');
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
expect(process.env.ANDROID_SDK_ROOT).toEqual('/android/sdk');
expect(process.env.ANDROID_HOME).toEqual(path.normalize('/android/sdk'));
});
});
it('should error out if `adb` command exists in a non-SDK-like directory structure', () => {
Expand All @@ -119,17 +119,17 @@ describe('check_reqs', function () {
expect(err.message).toContain('update your PATH to include valid path');
});
});
it('should set ANDROID_SDK_ROOT based on `avdmanager` command if command exists in a SDK-like directory structure', () => {
it('should set ANDROID_HOME based on `avdmanager` 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 === 'avdmanager') {
return '/android/sdk/tools/bin/avdmanager';
return path.normalize('/android/sdk/tools/bin/avdmanager');
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
expect(process.env.ANDROID_SDK_ROOT).toEqual('/android/sdk');
expect(process.env.ANDROID_HOME).toEqual(path.normalize('/android/sdk'));
});
});
it('should error out if `avdmanager` command exists in a non-SDK-like directory structure', () => {
Expand Down Expand Up @@ -169,41 +169,41 @@ describe('check_reqs', function () {

it('should use ANDROID_SDK_ROOT if defined', () => {
spyOn(fs, 'existsSync').and.returnValue(true);
process.env.ANDROID_SDK_ROOT = '/android/sdk';
process.env.ANDROID_SDK_ROOT = path.normalize('/android/sdk');
return check_reqs.check_android().then(() => {
expect(process.env.ANDROID_SDK_ROOT).toContain(expectedAndroidSdkPath);
});
});

it('should use ANDROID_HOME if defined and ANDROID_SDK_ROOT is not defined', () => {
spyOn(fs, 'existsSync').and.returnValue(true);
process.env.ANDROID_HOME = '/android/sdk';
process.env.ANDROID_HOME = path.normalize('/android/sdk');
return check_reqs.check_android().then(() => {
expect(process.env.ANDROID_SDK_ROOT).toContain(expectedAndroidSdkPath);
expect(process.env.ANDROID_HOME).toContain(expectedAndroidSdkPath);
});
});

it('should use ANDROID_SDK_ROOT if defined and ANDROID_HOME is defined', () => {
it('should use ANDROID_HOME if defined and ANDROID_SDK_ROOT is defined', () => {
spyOn(fs, 'existsSync').and.returnValue(true);
process.env.ANDROID_SDK_ROOT = '/android/sdk/root';
process.env.ANDROID_HOME = '/android/sdk';
process.env.ANDROID_SDK_ROOT = path.normalize('/android/sdk/root');
process.env.ANDROID_HOME = path.normalize('/android/sdk');
return check_reqs.check_android().then(() => {
expect(process.env.ANDROID_SDK_ROOT).toContain(expectedAndroidRootSdkPath);
});
});

it('should throw if ANDROID_SDK_ROOT points to an invalid path', () => {
process.env.ANDROID_SDK_ROOT = '/android/sdk';
it('should throw if ANDROID_HOME points to an invalid path', () => {
process.env.ANDROID_HOME = path.normalize('/android/sdk');
return check_reqs.check_android().catch((error) => {
expect(error.toString()).toContain('\'ANDROID_SDK_ROOT\' environment variable is set to non-existent path:');
expect(error.toString()).toContain('\'ANDROID_HOME\' environment variable is set to non-existent path:');
});
});
});

describe('set PATH for various Android binaries if not available', function () {
beforeEach(function () {
spyOn(which, 'sync').and.returnValue(null);
process.env.ANDROID_SDK_ROOT = 'let the children play';
process.env.ANDROID_HOME = 'let the children play';
spyOn(fs, 'existsSync').and.returnValue(true);
});
it('should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found', () => {
Expand All @@ -222,24 +222,24 @@ describe('check_reqs', function () {
delete process.env.ANDROID_SDK_ROOT;
delete process.env.ANDROID_HOME;
spyOn(check_reqs, 'get_gradle_wrapper').and.callFake(() => {
return (process.env.ANDROID_SDK_ROOT || process.env.ANDROID_HOME) + '/bin/gradle';
return path.normalize((process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT) + '/bin/gradle');
});
});

it('with ANDROID_SDK_ROOT / without ANDROID_HOME', async () => {
process.env.ANDROID_SDK_ROOT = '/android/sdk/root';
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo('/android/sdk/root/bin/gradle');
process.env.ANDROID_SDK_ROOT = path.normalize('/android/sdk/root');
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo(path.normalize('/android/sdk/root/bin/gradle'));
});

it('with ANDROID_SDK_ROOT / with ANDROID_HOME', async () => {
process.env.ANDROID_SDK_ROOT = '/android/sdk/root';
process.env.ANDROID_HOME = '/android/sdk/home';
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo('/android/sdk/root/bin/gradle');
process.env.ANDROID_SDK_ROOT = path.normalize('/android/sdk/root');
process.env.ANDROID_HOME = path.normalize('/android/sdk/home');
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo(path.normalize('/android/sdk/home/bin/gradle'));
});

it('without ANDROID_SDK_ROOT / with ANDROID_HOME', async () => {
process.env.ANDROID_HOME = '/android/sdk/home';
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo('/android/sdk/home/bin/gradle');
process.env.ANDROID_HOME = path.normalize('/android/sdk/home');
await expectAsync(check_reqs.check_gradle()).toBeResolvedTo(path.normalize('/android/sdk/home/bin/gradle'));
});

it('without ANDROID_SDK_ROOT / without ANDROID_HOME', () => {
Expand All @@ -250,7 +250,7 @@ describe('check_reqs', function () {
});

it('should error if sdk is installed but no gradle found', () => {
process.env.ANDROID_SDK_ROOT = '/android/sdk';
process.env.ANDROID_SDK_ROOT = path.normalize('/android/sdk');
spyOn(check_reqs, 'get_gradle_wrapper').and.callFake(() => {
return '';
});
Expand Down