diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 020b1b3dcd..9d92d71969 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -2,6 +2,7 @@ import * as path from "path"; import * as semver from "semver"; import { EOL } from "os"; import { cache } from "./common/decorators"; +import { appendZeroesToVersion } from './common/helpers'; export class AndroidToolsInfo implements IAndroidToolsInfo { private static ANDROID_TARGET_PREFIX = "android"; @@ -10,6 +11,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; + private static MAX_JAVA_VERSION = "1.9.0"; private showWarningsAsErrors: boolean; private toolsInfo: IAndroidToolsInfoData; @@ -101,7 +103,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { return detectedErrors || !isAndroidHomeValid; } - public async validateJavacVersion(installedJavaVersion: string, options?: { showWarningsAsErrors: boolean }): Promise { + public validateJavacVersion(installedJavacVersion: string, options?: { showWarningsAsErrors: boolean }): boolean { let hasProblemWithJavaVersion = false; if (options) { this.showWarningsAsErrors = options.showWarningsAsErrors; @@ -110,11 +112,16 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { const additionalMessage = "You will not be able to build your projects for Android." + EOL + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + " described in " + this.$staticConfig.SYS_REQUIREMENTS_LINK; - const matchingVersion = (installedJavaVersion || "").match(AndroidToolsInfo.VERSION_REGEX); - if (matchingVersion && matchingVersion[1]) { - if (semver.lt(matchingVersion[1], AndroidToolsInfo.MIN_JAVA_VERSION)) { + + const matchingVersion = appendZeroesToVersion(installedJavacVersion || "", 3).match(AndroidToolsInfo.VERSION_REGEX); + const installedJavaCompilerVersion = matchingVersion && matchingVersion[1]; + if (installedJavaCompilerVersion) { + if (semver.lt(installedJavaCompilerVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { + hasProblemWithJavaVersion = true; + this.printMessage(`Javac version ${installedJavacVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, additionalMessage); + } else if (semver.gte(installedJavaCompilerVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { hasProblemWithJavaVersion = true; - this.printMessage(`Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, additionalMessage); + this.printMessage(`Javac version ${installedJavacVersion} is not supported. You have to install version ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, additionalMessage); } } else { hasProblemWithJavaVersion = true; diff --git a/lib/common b/lib/common index 0d981032ba..d3fa315437 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 0d981032bad65fcbf429ac1e81b89f99442ca2ff +Subproject commit d3fa31543765bbd6c95b96464c421659fc13d8aa diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index e302f966b9..dc8cab466c 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -490,7 +490,7 @@ interface IAndroidToolsInfo { * @param {any} options Defines if the warning messages should treated as error. * @return {boolean} True if there are detected issues, false otherwise. */ - validateJavacVersion(installedJavaVersion: string, options?: { showWarningsAsErrors: boolean }): Promise; + validateJavacVersion(installedJavaVersion: string, options?: { showWarningsAsErrors: boolean }): boolean; /** * Validates if ANDROID_HOME environment variable is set correctly. diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index 95d56fa403..73dfa4c7bd 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -138,7 +138,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject const javaCompilerVersion = await this.$sysInfo.getJavaCompilerVersion(); - await this.$androidToolsInfo.validateJavacVersion(javaCompilerVersion, { showWarningsAsErrors: true }); + this.$androidToolsInfo.validateJavacVersion(javaCompilerVersion, { showWarningsAsErrors: true }); await this.$androidToolsInfo.validateInfo({ showWarningsAsErrors: true, validateTargetSdk: true }); } diff --git a/lib/services/doctor-service.ts b/lib/services/doctor-service.ts index a03a52a888..e71a825a98 100644 --- a/lib/services/doctor-service.ts +++ b/lib/services/doctor-service.ts @@ -104,9 +104,9 @@ class DoctorService implements IDoctorService { } const androidToolsIssues = this.$androidToolsInfo.validateInfo(); - const javaVersionIssue = await this.$androidToolsInfo.validateJavacVersion(sysInfo.javacVersion); + const javaCompilerVersionIssue = this.$androidToolsInfo.validateJavacVersion(sysInfo.javacVersion); const pythonIssues = await this.validatePythonPackages(); - const doctorResult = result || androidToolsIssues || javaVersionIssue || pythonIssues; + const doctorResult = result || androidToolsIssues || javaCompilerVersionIssue || pythonIssues; if (!configOptions || configOptions.trackResult) { await this.$analyticsService.track("DoctorEnvironmentSetup", doctorResult ? "incorrect" : "correct"); diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts new file mode 100644 index 0000000000..f548462455 --- /dev/null +++ b/test/android-tools-info.ts @@ -0,0 +1,112 @@ +import { Yok } from "../lib/common/yok"; +import { AndroidToolsInfo } from "../lib/android-tools-info"; +import { EOL } from "os"; +import { format } from "util"; +import { assert } from "chai"; + +interface ITestData { + javacVersion: string; + expectedResult: boolean; + warnings?: string[]; +} + +describe("androidToolsInfo", () => { + let loggedWarnings: string[] = []; + let loggedMarkdownMessages: string[] = []; + const sysRequirementsLink = ""; + + const additionalMsg = "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + + " described in " + sysRequirementsLink; + + beforeEach(() => { + loggedWarnings = []; + loggedMarkdownMessages = []; + }); + + const createTestInjector = (): IInjector => { + const testInjector = new Yok(); + testInjector.register("childProcess", {}); + testInjector.register("errors", { + failWithoutHelp: (message: string, ...args: any[]): any => { + const loggedError = format(message, args); + throw new Error(loggedError); + } + }); + testInjector.register("fs", {}); + testInjector.register("hostInfo", {}); + testInjector.register("logger", { + warn: (...args: string[]): void => { + loggedWarnings.push(format.apply(null, args)); + }, + + printMarkdown: (...args: string[]): void => { + loggedMarkdownMessages.push(format.apply(null, args)); + } + }); + testInjector.register("options", {}); + testInjector.register("staticConfig", { + SYS_REQUIREMENTS_LINK: sysRequirementsLink + }); + return testInjector; + }; + + describe("validateJavacVersion", () => { + const testData: ITestData[] = [ + { + javacVersion: "1.8.0", + expectedResult: false + }, + { + javacVersion: "1.8.0_152", + expectedResult: false + }, + { + javacVersion: "9", + expectedResult: true, + warnings: ["Javac version 9 is not supported. You have to install version 1.8.0."] + }, + { + javacVersion: "9.0.1", + expectedResult: true, + warnings: ["Javac version 9.0.1 is not supported. You have to install version 1.8.0."] + }, + { + javacVersion: "1.7.0", + expectedResult: true, + warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."] + }, + { + javacVersion: "1.7.0_132", + expectedResult: true, + warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0."] + }, + { + javacVersion: null, + expectedResult: true, + warnings: ["Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."] + } + ]; + + _.each(testData, ({ javacVersion, expectedResult, warnings }) => { + it(`returns ${expectedResult} when version is ${javacVersion}`, () => { + const testInjector = createTestInjector(); + const androidToolsInfo = testInjector.resolve(AndroidToolsInfo); + assert.deepEqual(androidToolsInfo.validateJavacVersion(javacVersion), expectedResult); + if (warnings && warnings.length) { + assert.deepEqual(loggedWarnings, warnings); + assert.deepEqual(loggedMarkdownMessages, [additionalMsg]); + } else { + assert.equal(loggedWarnings.length, 0); + assert.equal(loggedMarkdownMessages.length, 0); + } + }); + }); + + it("throws error when passing showWarningsAsErrors to true and javac is not installed", () => { + const testInjector = createTestInjector(); + const androidToolsInfo = testInjector.resolve(AndroidToolsInfo); + assert.throws(() => androidToolsInfo.validateJavacVersion(null, { showWarningsAsErrors: true }), "Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."); + }); + }); +}); diff --git a/test/stubs.ts b/test/stubs.ts index 2f97a9f7f4..2e32020b30 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -532,7 +532,7 @@ export class AndroidToolsInfoStub implements IAndroidToolsInfo { return true; } - public async validateJavacVersion(installedJavaVersion: string, options?: { showWarningsAsErrors: boolean }): Promise { + public validateJavacVersion(installedJavaVersion: string, options?: { showWarningsAsErrors: boolean }): boolean { return true; }