mirror of
https://github.com/apache/cordova-android.git
synced 2025-03-04 00:13:20 +08:00
refactor: java checks (#1130)
Co-authored-by: エリス <erisu@users.noreply.github.com> Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update spec/unit/java.spec.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update spec/unit/java.spec.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update bin/templates/cordova/lib/utils.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update bin/templates/cordova/lib/check_reqs.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update spec/unit/check_reqs.spec.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Update spec/unit/check_reqs.spec.js Co-authored-by: Raphael von der Grün <raphinesse@gmail.com> Co-authored-by: Raphael von der Grün <raphinesse@gmail.com>
This commit is contained in:
parent
3081e5e6e9
commit
774de78691
105
bin/templates/cordova/lib/check_reqs.js
vendored
105
bin/templates/cordova/lib/check_reqs.js
vendored
@ -20,30 +20,20 @@
|
|||||||
const execa = require('execa');
|
const execa = require('execa');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require('fs-extra');
|
var fs = require('fs-extra');
|
||||||
var os = require('os');
|
const { forgivingWhichSync, isWindows, isDarwin } = require('./utils');
|
||||||
var which = require('which');
|
const java = require('./env/java');
|
||||||
const glob = require('fast-glob');
|
|
||||||
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
||||||
var PROJECT_ROOT = path.join(__dirname, '..', '..');
|
var PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||||
const { CordovaError, ConfigParser, events } = require('cordova-common');
|
const { CordovaError, ConfigParser, events } = require('cordova-common');
|
||||||
var android_sdk = require('./android_sdk');
|
var android_sdk = require('./android_sdk');
|
||||||
const { createEditor } = require('properties-parser');
|
const { createEditor } = require('properties-parser');
|
||||||
|
const semver = require('semver');
|
||||||
|
|
||||||
function forgivingWhichSync (cmd) {
|
const EXPECTED_JAVA_VERSION = '1.8.x';
|
||||||
const whichResult = which.sync(cmd, { nothrow: true });
|
|
||||||
|
|
||||||
// On null, returns empty string to maintain backwards compatibility
|
// Re-exporting these for backwards compatibility and for unit testing.
|
||||||
// realpathSync follows symlinks
|
// TODO: Remove uses and use the ./utils module directly.
|
||||||
return whichResult === null ? '' : fs.realpathSync(whichResult);
|
Object.assign(module.exports, { isWindows, isDarwin });
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.isWindows = function () {
|
|
||||||
return (os.platform() === 'win32');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.isDarwin = function () {
|
|
||||||
return (os.platform() === 'darwin');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Get valid target from framework/project.properties if run from this repo
|
* @description Get valid target from framework/project.properties if run from this repo
|
||||||
@ -143,72 +133,18 @@ module.exports.check_gradle = function () {
|
|||||||
'in your path, or install Android Studio'));
|
'in your path, or install Android Studio'));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
/**
|
||||||
module.exports.check_java = function () {
|
* Checks for the java installation and correct version
|
||||||
var javacPath = forgivingWhichSync('javac');
|
*/
|
||||||
var hasJavaHome = !!process.env.JAVA_HOME;
|
module.exports.check_java = async function () {
|
||||||
return Promise.resolve().then(function () {
|
const javaVersion = await java.getVersion();
|
||||||
if (hasJavaHome) {
|
|
||||||
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
|
||||||
if (!javacPath) {
|
|
||||||
process.env.PATH += path.delimiter + path.join(process.env.JAVA_HOME, 'bin');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (javacPath) {
|
|
||||||
// OS X has a command for finding JAVA_HOME.
|
|
||||||
var find_java = '/usr/libexec/java_home';
|
|
||||||
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.';
|
|
||||||
if (fs.existsSync(find_java)) {
|
|
||||||
return execa(find_java).then(({ stdout }) => {
|
|
||||||
process.env.JAVA_HOME = stdout;
|
|
||||||
}).catch(function (err) {
|
|
||||||
if (err) {
|
|
||||||
throw new CordovaError(default_java_error_msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// See if we can derive it from javac's location.
|
|
||||||
var maybeJavaHome = path.dirname(path.dirname(javacPath));
|
|
||||||
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
|
||||||
process.env.JAVA_HOME = maybeJavaHome;
|
|
||||||
} else {
|
|
||||||
throw new CordovaError(default_java_error_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (module.exports.isWindows()) {
|
|
||||||
const { env } = process;
|
|
||||||
const baseDirs = [env.ProgramFiles, env['ProgramFiles(x86)']];
|
|
||||||
const globOpts = { absolute: true, onlyDirectories: true };
|
|
||||||
const flatMap = (arr, f) => [].concat(...arr.map(f));
|
|
||||||
|
|
||||||
const jdkDir = flatMap(baseDirs, cwd =>
|
if (!semver.satisfies(javaVersion.version, EXPECTED_JAVA_VERSION)) {
|
||||||
glob.sync('java/jdk*', { cwd, ...globOpts })
|
throw new CordovaError(
|
||||||
)[0];
|
`Requirements check failed for JDK ${EXPECTED_JAVA_VERSION}! Detected version: ${javaVersion.version}\n` +
|
||||||
|
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
|
||||||
if (jdkDir) {
|
);
|
||||||
env.PATH += path.delimiter + path.join(jdkDir, 'bin');
|
|
||||||
env.JAVA_HOME = path.normalize(jdkDir);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}).then(function () {
|
|
||||||
return execa('javac', ['-version'], { all: true })
|
|
||||||
.then(({ all: output }) => {
|
|
||||||
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
|
|
||||||
const match = /javac\s+([\d.]+)/i.exec(output);
|
|
||||||
return match && match[1];
|
|
||||||
}, () => {
|
|
||||||
var msg =
|
|
||||||
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
|
|
||||||
'You can get it from the following location:\n' +
|
|
||||||
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
|
|
||||||
if (process.env.JAVA_HOME) {
|
|
||||||
msg += '\n\n';
|
|
||||||
msg += 'Your JAVA_HOME is invalid: ' + process.env.JAVA_HOME;
|
|
||||||
}
|
|
||||||
throw new CordovaError(msg);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
@ -384,13 +320,6 @@ module.exports.run = function () {
|
|||||||
return Promise.all([this.check_java(), this.check_android()]).then(function (values) {
|
return Promise.all([this.check_java(), this.check_android()]).then(function (values) {
|
||||||
console.log('Using Android SDK: ' + process.env.ANDROID_SDK_ROOT);
|
console.log('Using Android SDK: ' + process.env.ANDROID_SDK_ROOT);
|
||||||
|
|
||||||
if (!String(values[0]).startsWith('1.8.')) {
|
|
||||||
throw new CordovaError(
|
|
||||||
'Requirements check failed for JDK 8 (\'1.8.*\')! Detected version: ' + values[0] + '\n' +
|
|
||||||
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!values[1]) {
|
if (!values[1]) {
|
||||||
throw new CordovaError('Requirements check failed for Android SDK! Android SDK was not detected.');
|
throw new CordovaError('Requirements check failed for Android SDK! Android SDK was not detected.');
|
||||||
}
|
}
|
||||||
|
123
bin/templates/cordova/lib/env/java.js
vendored
Normal file
123
bin/templates/cordova/lib/env/java.js
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const execa = require('execa');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
const glob = require('fast-glob');
|
||||||
|
const { CordovaError, events } = require('cordova-common');
|
||||||
|
const utils = require('../utils');
|
||||||
|
const semver = require('semver');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will be set to true on successful ensureness.
|
||||||
|
* If true, skips the expensive java checks.
|
||||||
|
*/
|
||||||
|
let javaIsEnsured = false;
|
||||||
|
|
||||||
|
const java = {
|
||||||
|
/**
|
||||||
|
* Gets the version from the javac executable.
|
||||||
|
*
|
||||||
|
* @returns {semver.SemVer}
|
||||||
|
*/
|
||||||
|
getVersion: async () => {
|
||||||
|
await java._ensure(process.env);
|
||||||
|
|
||||||
|
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
|
||||||
|
let version = null;
|
||||||
|
try {
|
||||||
|
version = (await execa('javac', ['-version'], { all: true })).all;
|
||||||
|
} catch (ex) {
|
||||||
|
events.emit('verbose', ex.shortMessage);
|
||||||
|
|
||||||
|
let msg =
|
||||||
|
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
|
||||||
|
'You can get it from the following location:\n' +
|
||||||
|
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
|
||||||
|
if (process.env.JAVA_HOME) {
|
||||||
|
msg += '\n\n';
|
||||||
|
msg += 'Your JAVA_HOME is invalid: ' + process.env.JAVA_HOME;
|
||||||
|
}
|
||||||
|
throw new CordovaError(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return semver.coerce(version);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that Java is installed. Will throw exception if not.
|
||||||
|
* Will set JAVA_HOME and PATH environment variables.
|
||||||
|
*
|
||||||
|
* This function becomes a no-op if already ran previously.
|
||||||
|
*/
|
||||||
|
_ensure: async (environment) => {
|
||||||
|
if (javaIsEnsured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const javacPath = utils.forgivingWhichSync('javac');
|
||||||
|
const hasJavaHome = !!environment.JAVA_HOME;
|
||||||
|
if (hasJavaHome) {
|
||||||
|
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
||||||
|
if (!javacPath) {
|
||||||
|
environment.PATH += path.delimiter + path.join(environment.JAVA_HOME, 'bin');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (javacPath) {
|
||||||
|
// OS X has a command for finding JAVA_HOME.
|
||||||
|
const find_java = '/usr/libexec/java_home';
|
||||||
|
const default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.';
|
||||||
|
if (fs.existsSync(find_java)) {
|
||||||
|
try {
|
||||||
|
environment.JAVA_HOME = (await execa(find_java)).stdout;
|
||||||
|
} catch (ex) {
|
||||||
|
events.emit('verbose', ex.shortMessage);
|
||||||
|
throw new CordovaError(default_java_error_msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// See if we can derive it from javac's location.
|
||||||
|
var maybeJavaHome = path.dirname(path.dirname(javacPath));
|
||||||
|
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||||
|
environment.JAVA_HOME = maybeJavaHome;
|
||||||
|
} else {
|
||||||
|
throw new CordovaError(default_java_error_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (utils.isWindows()) {
|
||||||
|
const baseDirs = [environment.ProgramFiles, environment['ProgramFiles(x86)']];
|
||||||
|
const globOpts = { absolute: true, onlyDirectories: true };
|
||||||
|
const flatMap = (arr, f) => [].concat(...arr.map(f));
|
||||||
|
const jdkDir = flatMap(baseDirs, cwd => {
|
||||||
|
return glob.sync('java/jdk*', { cwd, ...globOpts });
|
||||||
|
}
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
if (jdkDir) {
|
||||||
|
environment.PATH += path.delimiter + path.join(jdkDir, 'bin');
|
||||||
|
environment.JAVA_HOME = path.normalize(jdkDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
javaIsEnsured = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = java;
|
13
bin/templates/cordova/lib/utils.js
vendored
13
bin/templates/cordova/lib/utils.js
vendored
@ -24,6 +24,8 @@
|
|||||||
// TODO: Perhaps this should live in cordova-common?
|
// TODO: Perhaps this should live in cordova-common?
|
||||||
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
const which = require('which');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads, searches, and replaces the found occurences with replacementString and then writes the file back out.
|
* Reads, searches, and replaces the found occurences with replacementString and then writes the file back out.
|
||||||
@ -53,3 +55,14 @@ exports.compareByAll = fns => {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.forgivingWhichSync = (cmd) => {
|
||||||
|
const whichResult = which.sync(cmd, { nothrow: true });
|
||||||
|
|
||||||
|
// On null, returns empty string to maintain backwards compatibility
|
||||||
|
// realpathSync follows symlinks
|
||||||
|
return whichResult === null ? '' : fs.realpathSync(whichResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isWindows = () => os.platform() === 'win32';
|
||||||
|
exports.isDarwin = () => os.platform() === 'darwin';
|
||||||
|
43
package-lock.json
generated
43
package-lock.json
generated
@ -62,6 +62,12 @@
|
|||||||
"chalk": "^2.0.0",
|
"chalk": "^2.0.0",
|
||||||
"js-tokens": "^4.0.0"
|
"js-tokens": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -481,6 +487,13 @@
|
|||||||
"integrity": "sha512-/GWUAqa2OJNlDF5VGSe3SR1QMHEPXxx54Ur56r0qQC0H9FlBr7kyBF2SgVEhzFCPbrW4UcYgVuWrq/2Ty3QvXg==",
|
"integrity": "sha512-/GWUAqa2OJNlDF5VGSe3SR1QMHEPXxx54Ur56r0qQC0H9FlBr7kyBF2SgVEhzFCPbrW4UcYgVuWrq/2Ty3QvXg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"semver": "^5.4.1"
|
"semver": "^5.4.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi": {
|
"ansi": {
|
||||||
@ -2122,6 +2135,14 @@
|
|||||||
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
|
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"make-dir": {
|
"make-dir": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
@ -2238,6 +2259,14 @@
|
|||||||
"resolve": "^1.10.0",
|
"resolve": "^1.10.0",
|
||||||
"semver": "2 || 3 || 4 || 5",
|
"semver": "2 || 3 || 4 || 5",
|
||||||
"validate-npm-package-license": "^3.0.1"
|
"validate-npm-package-license": "^3.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npm-run-path": {
|
"npm-run-path": {
|
||||||
@ -2771,9 +2800,12 @@
|
|||||||
"integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk="
|
"integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk="
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.1",
|
"version": "7.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@ -3271,6 +3303,11 @@
|
|||||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
},
|
||||||
"yargs": {
|
"yargs": {
|
||||||
"version": "15.3.1",
|
"version": "15.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"is-path-inside": "^3.0.2",
|
"is-path-inside": "^3.0.2",
|
||||||
"nopt": "^4.0.3",
|
"nopt": "^4.0.3",
|
||||||
"properties-parser": "^0.3.1",
|
"properties-parser": "^0.3.1",
|
||||||
|
"semver": "^7.3.4",
|
||||||
"which": "^2.0.2"
|
"which": "^2.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
var rewire = require('rewire');
|
var rewire = require('rewire');
|
||||||
var android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
|
var android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
|
||||||
var os = require('os');
|
|
||||||
var fs = require('fs-extra');
|
var fs = require('fs-extra');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
var which = require('which');
|
var which = require('which');
|
||||||
|
const { CordovaError } = require('cordova-common');
|
||||||
|
|
||||||
// This should match /bin/templates/project/build.gradle
|
// This should match /bin/templates/project/build.gradle
|
||||||
const DEFAULT_TARGET_API = 29;
|
const DEFAULT_TARGET_API = 29;
|
||||||
@ -48,33 +48,13 @@ describe('check_reqs', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('check_java', () => {
|
describe('check_java', () => {
|
||||||
let tmpDir;
|
it('detects if unexpected JDK version is installed', async () => {
|
||||||
beforeEach(() => {
|
|
||||||
const tmpDirTemplate = path.join(os.tmpdir(), 'cordova-android-test-');
|
|
||||||
tmpDir = fs.realpathSync(fs.mkdtempSync(tmpDirTemplate));
|
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
fs.removeSync(tmpDir);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('detects JDK in default location on windows', async () => {
|
|
||||||
check_reqs.isWindows = () => true;
|
|
||||||
check_reqs.__set__({
|
check_reqs.__set__({
|
||||||
execa: async () => ({}),
|
EXPECTED_JAVA_VERSION: '9999.9999.9999',
|
||||||
forgivingWhichSync: () => ''
|
java: { getVersion: async () => ({ version: '1.8.0' }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
delete process.env.JAVA_HOME;
|
await expectAsync(check_reqs.check_java()).toBeRejectedWithError(CordovaError, /Requirements check failed for JDK 9999.9999.9999! Detected version: 1.8.0/);
|
||||||
process.env.ProgramFiles = tmpDir;
|
|
||||||
|
|
||||||
const jdkDir = path.join(tmpDir, 'java/jdk1.6.0_02');
|
|
||||||
fs.ensureDirSync(jdkDir);
|
|
||||||
|
|
||||||
await check_reqs.check_java();
|
|
||||||
|
|
||||||
expect(process.env.JAVA_HOME).toBe(jdkDir);
|
|
||||||
expect(process.env.PATH.split(path.delimiter))
|
|
||||||
.toContain(path.join(jdkDir, 'bin'));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
177
spec/unit/java.spec.js
Normal file
177
spec/unit/java.spec.js
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/**
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const rewire = require('rewire');
|
||||||
|
const { CordovaError } = require('cordova-common');
|
||||||
|
const utils = require('../../bin/templates/cordova/lib/utils');
|
||||||
|
const glob = require('fast-glob');
|
||||||
|
|
||||||
|
describe('Java', () => {
|
||||||
|
const Java = rewire('../../bin/templates/cordova/lib/env/java');
|
||||||
|
|
||||||
|
describe('getVersion', () => {
|
||||||
|
let originalEnsureFunc = null;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
/*
|
||||||
|
This is to avoid changing/polluting the
|
||||||
|
process environment variables
|
||||||
|
as a result of running these java tests; which could produce
|
||||||
|
unexpected side effects to other tests.
|
||||||
|
*/
|
||||||
|
originalEnsureFunc = Java._ensure;
|
||||||
|
spyOn(Java, '_ensure').and.callFake(() => {
|
||||||
|
return originalEnsureFunc({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs', async () => {
|
||||||
|
Java.__set__('execa', () => Promise.resolve({
|
||||||
|
all: 'javac 1.8.0_275'
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('BEFORE', process.env.JAVA_HOME);
|
||||||
|
const result = await Java.getVersion();
|
||||||
|
console.log('AFTER', process.env.JAVA_HOME);
|
||||||
|
expect(result.major).toBe(1);
|
||||||
|
expect(result.minor).toBe(8);
|
||||||
|
expect(result.patch).toBe(0);
|
||||||
|
expect(result.version).toBe('1.8.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('produces a CordovaError on error', async () => {
|
||||||
|
Java.__set__('execa', () => Promise.reject({
|
||||||
|
shortMessage: 'test error'
|
||||||
|
}));
|
||||||
|
const emitSpy = jasmine.createSpy('events.emit');
|
||||||
|
Java.__set__('events', {
|
||||||
|
emit: emitSpy
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectAsync(Java.getVersion())
|
||||||
|
.toBeRejectedWithError(CordovaError, /Failed to run "javac -version"/);
|
||||||
|
expect(emitSpy).toHaveBeenCalledWith('verbose', 'test error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_ensure', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
Java.__set__('javaIsEnsured', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with JAVA_HOME / without javac', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('');
|
||||||
|
|
||||||
|
const env = {
|
||||||
|
JAVA_HOME: '/tmp/jdk'
|
||||||
|
};
|
||||||
|
|
||||||
|
await Java._ensure(env);
|
||||||
|
|
||||||
|
expect(env.PATH.split(path.delimiter))
|
||||||
|
.toContain(path.join(env.JAVA_HOME, 'bin'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects JDK in default location on windows', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('');
|
||||||
|
spyOn(utils, 'isWindows').and.returnValue(true);
|
||||||
|
|
||||||
|
const root = 'C:\\Program Files';
|
||||||
|
const env = {
|
||||||
|
ProgramFiles: root
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(glob, 'sync').and.returnValue(`${root}\\java\\jdk1.8.0_275`);
|
||||||
|
|
||||||
|
const jdkDir = `${root}\\java\\jdk1.8.0_275`;
|
||||||
|
|
||||||
|
await Java._ensure(env);
|
||||||
|
|
||||||
|
expect(env.JAVA_HOME).withContext('JAVA_HOME').toBe(jdkDir);
|
||||||
|
expect(env.PATH).toContain(jdkDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects JDK in default location on windows (x86)', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('');
|
||||||
|
spyOn(utils, 'isWindows').and.returnValue(true);
|
||||||
|
|
||||||
|
const root = 'C:\\Program Files (x86)';
|
||||||
|
const env = {
|
||||||
|
'ProgramFiles(x86)': root
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(glob, 'sync').and.returnValue(`${root}\\java\\jdk1.8.0_275`);
|
||||||
|
|
||||||
|
const jdkDir = `${root}\\java\\jdk1.8.0_275`;
|
||||||
|
|
||||||
|
await Java._ensure(env);
|
||||||
|
|
||||||
|
expect(env.JAVA_HOME).withContext('JAVA_HOME').toBe(jdkDir);
|
||||||
|
expect(env.PATH).toContain(jdkDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('without JAVA_HOME / with javac - Mac OS X - success', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('/tmp/jdk/bin');
|
||||||
|
const fsSpy = jasmine.createSpy('fs').and.returnValue(true);
|
||||||
|
Java.__set__('fs', {
|
||||||
|
existsSync: fsSpy
|
||||||
|
});
|
||||||
|
Java.__set__('execa', async () => ({ stdout: '/tmp/jdk' }));
|
||||||
|
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
await Java._ensure(env);
|
||||||
|
|
||||||
|
expect(fsSpy).toHaveBeenCalledWith('/usr/libexec/java_home');
|
||||||
|
expect(env.JAVA_HOME).toBe('/tmp/jdk');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('without JAVA_HOME / with javac - Mac OS X - error', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('/tmp/jdk/bin');
|
||||||
|
Java.__set__('fs', { existsSync: () => true });
|
||||||
|
Java.__set__('execa', jasmine.createSpy('execa').and.returnValue(Promise.reject({
|
||||||
|
shortMessage: 'test error'
|
||||||
|
})));
|
||||||
|
const emitSpy = jasmine.createSpy('events.emit');
|
||||||
|
Java.__set__('events', {
|
||||||
|
emit: emitSpy
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectAsync(Java._ensure({}))
|
||||||
|
.toBeRejectedWithError(CordovaError, /Failed to find 'JAVA_HOME' environment variable/);
|
||||||
|
|
||||||
|
expect(emitSpy).toHaveBeenCalledWith('verbose', 'test error');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('derive from javac location - success', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('/tmp/jdk/bin');
|
||||||
|
Java.__set__('fs', { existsSync: path => !/java_home$/.test(path) });
|
||||||
|
const env = {};
|
||||||
|
await Java._ensure(env);
|
||||||
|
expect(env.JAVA_HOME).toBe('/tmp');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('derive from javac location - error', async () => {
|
||||||
|
spyOn(utils, 'forgivingWhichSync').and.returnValue('/tmp/jdk/bin');
|
||||||
|
Java.__set__('fs', { existsSync: () => false });
|
||||||
|
await expectAsync(Java._ensure({})).toBeRejectedWithError(CordovaError, /Failed to find 'JAVA_HOME' environment variable/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user