diff --git a/messages/jreSetupManager.md b/messages/jreSetupManager.md index d0dd7a1b5..772d503ea 100644 --- a/messages/jreSetupManager.md +++ b/messages/jreSetupManager.md @@ -18,4 +18,8 @@ If the problem persists, please manually add a 'javaHome' property to your Confi # InvalidVersion -Java version %s isn't supported. Install Java 1.8 or later. \ No newline at end of file +Java version %s isn't supported. Install Java 1.8 or later. + +# warning.JavaV8Deprecated + +Code Analyzer requires Java v11 or later. Update to Java v11 and update the `javaHome` property in your `%s` file. diff --git a/src/lib/Display.ts b/src/lib/Display.ts index e12fe449f..27504d205 100644 --- a/src/lib/Display.ts +++ b/src/lib/Display.ts @@ -43,6 +43,11 @@ export interface Display { */ displayVerboseWarning(msg: string): void; + /** + * Display a message as a warning, unless it's been displayed using this method before. + */ + displayUniqueWarning(msg: string): void; + /** * Adds a spinner to the display. */ @@ -68,11 +73,13 @@ export class UxDisplay implements Display { private readonly displayable: Displayable; private readonly spinner: Spinner; private readonly isVerboseSet: boolean; + private uniqueMessageSet: Set; public constructor(displayable: Displayable, spinner: Spinner, isVerboseSet: boolean) { this.displayable = displayable; this.spinner = spinner; this.isVerboseSet = isVerboseSet; + this.uniqueMessageSet = new Set(); } public displayInfo(msg: string): void { @@ -111,6 +118,13 @@ export class UxDisplay implements Display { } } + public displayUniqueWarning(msg: string): void { + if (!this.uniqueMessageSet.has(msg)) { + this.uniqueMessageSet.add(msg); + this.displayWarning(msg); + } + } + public spinnerStart(msg: string, status?: string): void { this.spinner.start(msg, status); } diff --git a/src/lib/JreSetupManager.ts b/src/lib/JreSetupManager.ts index 378eb4980..f07eeacb0 100644 --- a/src/lib/JreSetupManager.ts +++ b/src/lib/JreSetupManager.ts @@ -8,7 +8,9 @@ import childProcess = require('child_process'); import path = require('path'); import {FileHandler} from './util/FileHandler'; import {Config} from './util/Config'; +import {CONFIG_FILE} from '../Constants'; import {BundleName, getMessage} from "../MessageCatalog"; +import {uxEvents, EVENTS} from './ScannerEvents'; const JAVA_HOME_SYSTEM_VARIABLES = ['JAVA_HOME', 'JRE_HOME', 'JDK_HOME']; @@ -142,6 +144,7 @@ class JreSetupManager extends AsyncCreatable { } else if (majorVersion === 1 && minorVersion === 8) { // Accommodating 1.8 version = `${majorVersion}.${minorVersion}`; + uxEvents.emit(EVENTS.WARNING_ALWAYS_UNIQUE, getMessage(BundleName.JreSetupManager, 'warning.JavaV8Deprecated', [path.join(Controller.getSfdxScannerPath(), CONFIG_FILE)])); } else { // Not matching what we are looking for const errName = 'InvalidVersion'; @@ -157,7 +160,7 @@ class JreSetupManager extends AsyncCreatable { private async fetchJavaVersion(javaHome: string): Promise { const javaWithFullPath = path.join(javaHome, 'bin', 'java'); // Run java -version and examine stderr for version - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { childProcess.execFile(javaWithFullPath, ['-version'], {}, (error, _stdout, stderr) => { if (error) { diff --git a/src/lib/ScannerCommand.ts b/src/lib/ScannerCommand.ts index e37acca0e..d1fc7b892 100644 --- a/src/lib/ScannerCommand.ts +++ b/src/lib/ScannerCommand.ts @@ -54,6 +54,7 @@ export abstract class ScannerCommand extends SfCommand implements Displ uxEvents.on(EVENTS.INFO_VERBOSE, (msg: string) => display.displayVerboseInfo(msg)); uxEvents.on(EVENTS.WARNING_ALWAYS, (msg: string) => display.displayWarning(msg)); uxEvents.on(EVENTS.WARNING_VERBOSE, (msg: string) => display.displayVerboseWarning(msg)); + uxEvents.on(EVENTS.WARNING_ALWAYS_UNIQUE, (msg: string) => display.displayUniqueWarning(msg)); uxEvents.on(EVENTS.START_SPINNER, (msg: string, status: string) => display.spinnerStart(msg, status)); uxEvents.on(EVENTS.UPDATE_SPINNER, (msg: string) => display.spinnerUpdate(msg)); uxEvents.on(EVENTS.WAIT_ON_SPINNER, (_msg: string) => display.spinnerWait()); // eslint-disable-line @typescript-eslint/no-unused-vars diff --git a/src/lib/ScannerEvents.ts b/src/lib/ScannerEvents.ts index 00226d8f5..ccd4e00cb 100644 --- a/src/lib/ScannerEvents.ts +++ b/src/lib/ScannerEvents.ts @@ -9,6 +9,7 @@ export enum EVENTS { INFO_VERBOSE = 'info-verbose', WARNING_ALWAYS = 'warning-always', WARNING_VERBOSE = 'warning-verbose', + WARNING_ALWAYS_UNIQUE = 'warning-always-unique', // NOTE: If, for some reason, we eventually need verbose-only spinners, we'll need to split START_SPINNER into // always/verbose variants, but the other two can be left alone. This is because they correspond to `ux.setSpinnerStatus()` // and `ux.stopSpinner()`, which are both no-ops if there's not an active spinner. diff --git a/test/lib/FakeDisplay.ts b/test/lib/FakeDisplay.ts index b9ab12444..6f91b685f 100644 --- a/test/lib/FakeDisplay.ts +++ b/test/lib/FakeDisplay.ts @@ -55,6 +55,10 @@ export class FakeDisplay implements Display { this.outputs.push("[VerboseWarning]: " + msg); } + displayUniqueWarning(msg: string): void { + this.outputs.push("[UniqueWarning]: " + msg); + } + displayStyledHeader(headerText: string): void { this.outputs.push("[StyledHeader]: " + headerText); } diff --git a/test/lib/JreSetupManager.test.ts b/test/lib/JreSetupManager.test.ts index 1bf09f536..1c0998b9f 100644 --- a/test/lib/JreSetupManager.test.ts +++ b/test/lib/JreSetupManager.test.ts @@ -1,10 +1,11 @@ -import {expect} from 'chai'; +import {assert, expect} from 'chai'; import {FileHandler} from '../../src/lib/util/FileHandler'; import {Config} from '../../src/lib/util/Config'; import Sinon = require('sinon'); import {verifyJreSetup, JreSetupManagerDependencies} from '../../src/lib/JreSetupManager'; import childProcess = require('child_process'); import * as TestOverrides from '../test-related-lib/TestOverrides'; +import {uxEvents, EVENTS} from '../../src/lib/ScannerEvents'; TestOverrides.initializeTestSetup(); @@ -18,6 +19,14 @@ describe('JreSetupManager #verifyJreSetup', () => { const validVersion8 = 'openjdk version "1.8.0_172"\nOpenJDK Runtime Environment (Zulu 8.30.0.2-macosx) (build 1.8.0_172-b01)\nOpenJDK 64-Bit Server VM (Zulu 8.30.0.2-macosx) (build 25.172-b01, mixed mode)\n'; const validVersion14Win = 'openjdk 14 2020-03-17\r\nOpenJDK Runtime Environment (build 14+36-1461)\r\nOpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)\r\n'; const invalidVersion = 'openjdk version "1.5.0_188"\nOpenJDK Runtime Environment'; + let uniqueWarningCounter = 0; + uxEvents.on(EVENTS.WARNING_ALWAYS_UNIQUE, (_msg) => { + uniqueWarningCounter += 1; + }); + + beforeEach(() => { + uniqueWarningCounter = 0; + }); describe('With valid javaHome path in Config and an accepted Java version', () => { @@ -48,6 +57,7 @@ describe('JreSetupManager #verifyJreSetup', () => { expect(javaHomeValue).equals(javaHomeValidPath); expect(setJavaHomeStub.calledOnce).to.be.true; expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(1); }); }); @@ -83,6 +93,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(1); }); it('should check JRE_HOME for path', async () => { @@ -93,6 +104,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(1); }); it('should check JDK_HOME for path', async () => { @@ -103,6 +115,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(1); }); }); @@ -140,6 +153,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(findJavaHomeStub.calledOnce).to.be.true; expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(1); findJavaHomeStub.restore(); @@ -156,6 +170,7 @@ describe('JreSetupManager #verifyJreSetup', () => { } expect(findJavaHomeStub.calledOnce).to.be.true; + expect(uniqueWarningCounter).to.equal(0); findJavaHomeStub.restore(); @@ -183,8 +198,10 @@ describe('JreSetupManager #verifyJreSetup', () => { // Execute and verify try { await verifyJreSetup(); + assert.fail('Should have failed'); } catch (err) { expect(err.name).equals('InvalidJavaHome'); + expect(uniqueWarningCounter).to.equal(0); } configGetJavaHomeStub.restore(); @@ -201,8 +218,10 @@ describe('JreSetupManager #verifyJreSetup', () => { // Execute and verify try { await verifyJreSetup(); + assert.fail('Should have failed'); } catch (err) { expect(err.name).equals('InvalidVersion'); + expect(uniqueWarningCounter).to.equal(0); } configGetJavaHomeStub.restore(); @@ -221,6 +240,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(0); configGetJavaHomeStub.restore(); statStub.restore(); @@ -238,6 +258,7 @@ describe('JreSetupManager #verifyJreSetup', () => { // Verify expect(javaHome).equals(javaHomeValidPath); + expect(uniqueWarningCounter).to.equal(0); configGetJavaHomeStub.restore(); statStub.restore();