From b4b60c23c296d62f14c029c662d30fc562678dad Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 24 Oct 2023 09:17:24 -0400 Subject: [PATCH 01/52] feat: add structure for checking CLI version at activation of Core extension --- .../src/cli/checkCliVersion.ts | 35 +++++++++++++++++++ packages/salesforcedx-utils/src/cli/index.ts | 1 + .../salesforcedx-vscode-core/src/index.ts | 3 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 packages/salesforcedx-utils/src/cli/checkCliVersion.ts diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts new file mode 100644 index 0000000000..db9142d30f --- /dev/null +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +import { SfdxCommandBuilder } from './sfdxCommandBuilder'; +import { CliCommandExecutor } from './cliCommandExecutor'; +import { CommandOutput } from './commandOutput'; + +export class CheckCliVersion { + + // decide whether to make a new function here or reuse isCLIInstalled() from packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts + // public async isCliInstalled() { + // } + + public async getCliVersion(): Promise { + + const execution = new CliCommandExecutor( + new SfdxCommandBuilder() + .withArg('--version') + .withJson() + .build(), + {} + ).execute(); + + const cmdOutput = new CommandOutput(); + const result = await cmdOutput.getCmdResult(execution); + console.log('**** result = ' + result); + throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); + + } + +} \ No newline at end of file diff --git a/packages/salesforcedx-utils/src/cli/index.ts b/packages/salesforcedx-utils/src/cli/index.ts index 7a6adae97e..9a95b477e0 100644 --- a/packages/salesforcedx-utils/src/cli/index.ts +++ b/packages/salesforcedx-utils/src/cli/index.ts @@ -6,3 +6,4 @@ export { ForceConfigGet } from './forceConfigGet'; export { GlobalCliEnvironment } from './globalCliEnvironment'; export { OrgDisplay } from './orgDisplay'; export { SfdxCommandBuilder } from './sfdxCommandBuilder'; +export { CheckCliVersion } from './checkCliVersion'; diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 7677fdbf0e..174deee1ce 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -4,7 +4,7 @@ * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; +import { CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; import { ChannelService, getRootWorkspacePath, @@ -555,6 +555,7 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); + await new CheckCliVersion().getCliVersion(); await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); From 039da9041be2d46ee76973deccd44753a1bdf463 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 24 Oct 2023 12:44:47 -0400 Subject: [PATCH 02/52] feat: parse result of 'sfdx --version' to get just the cli version --- .../salesforcedx-utils/src/cli/checkCliVersion.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index db9142d30f..0a8bbceac6 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -28,7 +28,20 @@ export class CheckCliVersion { const cmdOutput = new CommandOutput(); const result = await cmdOutput.getCmdResult(execution); console.log('**** result = ' + result); - throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); + let version = ''; + for (let position = 0; position < result.length; position++) { + console.log('result[' + position + '] = {' + result[position] + '}'); + if (result[position] === ' ') { + console.log('HERE'); + break; + } + else if (Number.isInteger(+result[position]) || result[position] === '.') { + version += result[position]; + } + + } + console.log('**** version = ' + version); + // throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); } From 03e3f6cbdd8742ca2694a1e5ee82e6c9b25801c0 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 24 Oct 2023 14:59:38 -0400 Subject: [PATCH 03/52] feat: check for type of CLI (sfdx or sf) in addition to version number --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 0a8bbceac6..e824e8b767 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -28,6 +28,8 @@ export class CheckCliVersion { const cmdOutput = new CommandOutput(); const result = await cmdOutput.getCmdResult(execution); console.log('**** result = ' + result); + + // Get the version number of the CLI let version = ''; for (let position = 0; position < result.length; position++) { console.log('result[' + position + '] = {' + result[position] + '}'); @@ -41,6 +43,14 @@ export class CheckCliVersion { } console.log('**** version = ' + version); + + // Get the type of CLI (the old SFDX or the new SF) + let isSfdx = false; + if (result.includes('sfdx')) { + isSfdx = true; + } + console.log('**** isSfdx = ' + isSfdx); + // throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); } From 7626689f61ae7903242ef535b01b53224dfb429c Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 24 Oct 2023 22:39:46 -0400 Subject: [PATCH 04/52] feat: add checking to make sure SFDX CLI is installed + notification if CLI is not installed --- packages/salesforcedx-vscode-core/src/constants.ts | 2 +- packages/salesforcedx-vscode-core/src/index.ts | 9 +++++++-- packages/salesforcedx-vscode-core/src/messages/i18n.ts | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/constants.ts b/packages/salesforcedx-vscode-core/src/constants.ts index 9d486c344c..06fe257e2f 100644 --- a/packages/salesforcedx-vscode-core/src/constants.ts +++ b/packages/salesforcedx-vscode-core/src/constants.ts @@ -14,7 +14,7 @@ export const APEX_CODE_DEBUG_LEVEL = 'FINEST'; export const VISUALFORCE_DEBUG_LEVEL = 'FINER'; export const ENV_SF_DISABLE_TELEMETRY = 'SF_DISABLE_TELEMETRY'; export const SFDX_CLI_DOWNLOAD_LINK = - 'https://developer.salesforce.com/tools/sfdxcli'; + 'https://developer.salesforce.com/tools/salesforcecli'; export const TARGET_ORG_KEY = 'target-org'; export const PKG_ID_PREFIX = '04t'; diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 174deee1ce..bddaf7bf45 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -115,7 +115,7 @@ import { isSfdxProjectOpened } from './predicates'; import { registerPushOrDeployOnSave, sfdxCoreSettings } from './settings'; import { taskViewService } from './statuses'; import { showTelemetryMessage, telemetryService } from './telemetry'; -import { isCLIInstalled, setUpOrgExpirationWatcher } from './util'; +import { isCLIInstalled, setUpOrgExpirationWatcher, showCLINotInstalledMessage } from './util'; import { OrgAuthInfo } from './util/authInfo'; const flagOverwrite: FlagParameter = { @@ -555,7 +555,12 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - await new CheckCliVersion().getCliVersion(); + // TODO: add a line here to check if CLI is installed + const installed = await isCLIInstalled(); + if (!installed) { + showCLINotInstalledMessage(); + } + await new CheckCliVersion().validateCliVersion(); await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index 67cdfd5f99..b530222426 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -290,7 +290,7 @@ export const messages = { error_parsing_sfdx_project_file: "Couldn't parse sfdx-project.json file (%s). Parse error: %s", sfdx_cli_not_found: - 'Salesforce CLI is not installed. Install it from [%s](%s)', + 'Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [%s](%s)', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From 81745461cbb0ca8678678813dd376e12b5271814 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 24 Oct 2023 22:54:34 -0400 Subject: [PATCH 05/52] feat: check CLI version using regex --- .../src/cli/checkCliVersion.ts | 84 ++++++++++++++----- 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index e824e8b767..4448a8fe09 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -11,12 +11,9 @@ import { CommandOutput } from './commandOutput'; export class CheckCliVersion { - // decide whether to make a new function here or reuse isCLIInstalled() from packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts - // public async isCliInstalled() { - // } - - public async getCliVersion(): Promise { + public async validateCliVersion(): Promise { + // Execute the command "sfdx --version" in the Terminal const execution = new CliCommandExecutor( new SfdxCommandBuilder() .withArg('--version') @@ -25,31 +22,78 @@ export class CheckCliVersion { {} ).execute(); + // Save the result of the command const cmdOutput = new CommandOutput(); const result = await cmdOutput.getCmdResult(execution); console.log('**** result = ' + result); - // Get the version number of the CLI - let version = ''; - for (let position = 0; position < result.length; position++) { - console.log('result[' + position + '] = {' + result[position] + '}'); - if (result[position] === ' ') { - console.log('HERE'); - break; + // Parse the result to check if the version is supported + const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; + const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + + const sfdxMatch = sfdxPattern.exec(result); + const sfMatch = sfPattern.exec(result); + + // Case 1: SFDX CLI is installed + if (sfdxMatch) { + const sfdxVersion = sfdxMatch[1]; + const sfdxVersionNumber = sfdxVersion.split('.').map(Number); + let validSfdxVersion = false; + // The last working version of SFDX is v7.193.2 + if (sfdxVersionNumber[0] >= 7 && sfdxVersionNumber[1] >= 193 && sfdxVersionNumber[2] >= 2) { + validSfdxVersion = true; } - else if (Number.isInteger(+result[position]) || result[position] === '.') { - version += result[position]; + if (validSfdxVersion === false) { + throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: https://developer.salesforce.com/tools/salesforcecli'); } + } + // Case 2: SF CLI is installed + else if (sfMatch) { + const sfVersion = sfMatch[1]; + const sfVersionNumber = sfVersion.split('.').map(Number); + let validSfVersion = false; + // SF v1 does not map sf commands to sfdx commands and is not supported + if (sfVersionNumber[0] >= 2 && sfVersionNumber[1] >= 0 && sfVersionNumber[2] >= 0) { + validSfVersion = true; + } + if (validSfVersion === false) { + throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: https://developer.salesforce.com/tools/salesforcecli'); + } } - console.log('**** version = ' + version); - // Get the type of CLI (the old SFDX or the new SF) - let isSfdx = false; - if (result.includes('sfdx')) { - isSfdx = true; + // Case 3: Neither SFDX CLI nor SF CLI is installed + else { + throw new Error('Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from https://developer.salesforce.com/tools/salesforcecli'); } - console.log('**** isSfdx = ' + isSfdx); + + // // Get the version number of the CLI + // let version = ''; + // for (let position = 0; position < result.length; position++) { + // console.log('result[' + position + '] = {' + result[position] + '}'); + // if (result[position] === ' ') { + // console.log('HERE'); + // break; + // } + // else if (Number.isInteger(+result[position]) || result[position] === '.') { + // version += result[position]; + // } + + // } + // console.log('**** version = ' + version); + + // // Get the type of CLI (the old SFDX or the new SF) + // let isSfdx = null; + // if (result.includes('sfdx')) { + // isSfdx = true; + // } + // else if (result.includes('@salesforce')) { + // isSfdx = false; + // } + // else { + // throw new Error ('No compatible CLI installed'); + // } + // console.log('**** isSfdx = ' + isSfdx); // throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); From 123e01a6887ae658e1644d20889093c852e39af3 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 25 Oct 2023 14:24:36 -0400 Subject: [PATCH 06/52] fix: show error message instead of warning message if CLI is not installed --- packages/salesforcedx-vscode-core/src/index.ts | 4 +++- .../salesforcedx-vscode-core/src/util/cliConfiguration.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index bddaf7bf45..b996234f8f 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -555,12 +555,14 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - // TODO: add a line here to check if CLI is installed + + // Check that the CLI is installed and that it is a supported version const installed = await isCLIInstalled(); if (!installed) { showCLINotInstalledMessage(); } await new CheckCliVersion().validateCliVersion(); + await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); diff --git a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts index 5d094f3c19..7da62d6a76 100644 --- a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts +++ b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts @@ -35,7 +35,7 @@ export function showCLINotInstalledMessage() { SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK ); - window.showWarningMessage(showMessage); + window.showErrorMessage(showMessage); } export function disableCLITelemetry() { From 4b899fbb60c0c1006b4be31923b5573b37c70129 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 25 Oct 2023 14:43:16 -0400 Subject: [PATCH 07/52] fix: links in error notifications when CLI version is not supported --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 4448a8fe09..c68a575a6b 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -44,7 +44,7 @@ export class CheckCliVersion { validSfdxVersion = true; } if (validSfdxVersion === false) { - throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: https://developer.salesforce.com/tools/salesforcecli'); + throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); } } @@ -58,13 +58,13 @@ export class CheckCliVersion { validSfVersion = true; } if (validSfVersion === false) { - throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: https://developer.salesforce.com/tools/salesforcecli'); + throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); } } // Case 3: Neither SFDX CLI nor SF CLI is installed else { - throw new Error('Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from https://developer.salesforce.com/tools/salesforcecli'); + throw new Error('Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); } // // Get the version number of the CLI From 04b8ef7e902bf463892611f1d1ef8cdbf9ac792a Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 25 Oct 2023 23:18:48 -0400 Subject: [PATCH 08/52] feat: support internationalization of error message when CLI version is unsupported + cleanup code --- .../src/cli/checkCliVersion.ts | 50 +++---------------- .../salesforcedx-vscode-core/src/index.ts | 12 ++++- .../src/messages/i18n.ja.ts | 2 + .../src/messages/i18n.ts | 2 + .../src/util/cliConfiguration.ts | 9 ++++ .../src/util/index.ts | 3 +- 6 files changed, 33 insertions(+), 45 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index c68a575a6b..0cfcaa9b87 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -11,7 +11,7 @@ import { CommandOutput } from './commandOutput'; export class CheckCliVersion { - public async validateCliVersion(): Promise { + public async validateCliVersion(): Promise { // Execute the command "sfdx --version" in the Terminal const execution = new CliCommandExecutor( @@ -38,13 +38,12 @@ export class CheckCliVersion { if (sfdxMatch) { const sfdxVersion = sfdxMatch[1]; const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - let validSfdxVersion = false; // The last working version of SFDX is v7.193.2 if (sfdxVersionNumber[0] >= 7 && sfdxVersionNumber[1] >= 193 && sfdxVersionNumber[2] >= 2) { - validSfdxVersion = true; + return 'validCli'; } - if (validSfdxVersion === false) { - throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); + else { + return 'cliNotSupported'; } } @@ -52,51 +51,18 @@ export class CheckCliVersion { else if (sfMatch) { const sfVersion = sfMatch[1]; const sfVersionNumber = sfVersion.split('.').map(Number); - let validSfVersion = false; // SF v1 does not map sf commands to sfdx commands and is not supported if (sfVersionNumber[0] >= 2 && sfVersionNumber[1] >= 0 && sfVersionNumber[2] >= 0) { - validSfVersion = true; + return 'validCli'; } - if (validSfVersion === false) { - throw new Error('Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); + else { + return 'cliNotSupported'; } } // Case 3: Neither SFDX CLI nor SF CLI is installed else { - throw new Error('Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [https://developer.salesforce.com/tools/salesforcecli](https://developer.salesforce.com/tools/salesforcecli)'); + return 'cliNotInstalled'; } - - // // Get the version number of the CLI - // let version = ''; - // for (let position = 0; position < result.length; position++) { - // console.log('result[' + position + '] = {' + result[position] + '}'); - // if (result[position] === ' ') { - // console.log('HERE'); - // break; - // } - // else if (Number.isInteger(+result[position]) || result[position] === '.') { - // version += result[position]; - // } - - // } - // console.log('**** version = ' + version); - - // // Get the type of CLI (the old SFDX or the new SF) - // let isSfdx = null; - // if (result.includes('sfdx')) { - // isSfdx = true; - // } - // else if (result.includes('@salesforce')) { - // isSfdx = false; - // } - // else { - // throw new Error ('No compatible CLI installed'); - // } - // console.log('**** isSfdx = ' + isSfdx); - - // throw new Error('Your installed CLI version is no longer supported. Uninstall CLI and reinstall it at https://developer.salesforce.com/tools/sfdxcli'); - } - } \ No newline at end of file diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index b996234f8f..9f402b2bbc 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -115,7 +115,7 @@ import { isSfdxProjectOpened } from './predicates'; import { registerPushOrDeployOnSave, sfdxCoreSettings } from './settings'; import { taskViewService } from './statuses'; import { showTelemetryMessage, telemetryService } from './telemetry'; -import { isCLIInstalled, setUpOrgExpirationWatcher, showCLINotInstalledMessage } from './util'; +import { isCLIInstalled, setUpOrgExpirationWatcher, showCLINotInstalledMessage, showCLINotSupportedMessage } from './util'; import { OrgAuthInfo } from './util/authInfo'; const flagOverwrite: FlagParameter = { @@ -557,11 +557,19 @@ export async function activate(extensionContext: vscode.ExtensionContext) { ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); // Check that the CLI is installed and that it is a supported version + // If there is no CLI or it is an unsupported version then the Core extension will not activate const installed = await isCLIInstalled(); if (!installed) { showCLINotInstalledMessage(); } - await new CheckCliVersion().validateCliVersion(); + const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(); + if (cliVersionCheckResult === 'cliNotSupported') { + showCLINotSupportedMessage(); + throw new Error(); + } else if (cliVersionCheckResult === 'cliNotInstalled') { + showCLINotInstalledMessage(); + throw new Error(); + } await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 397fcb92ce..39c849a1a9 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -250,6 +250,8 @@ export const messages = { 'sfdx-project.json ファイル (%s) をパースできませんでした。パースエラー: %s', sfdx_cli_not_found: 'Salesforce CLI がインストールされていません。[%s](%s) からインストールしてください。', + sfdx_cli_not_supported: + '!!! Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [%s](%s)', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index b530222426..7e289c1fb3 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -291,6 +291,8 @@ export const messages = { "Couldn't parse sfdx-project.json file (%s). Parse error: %s", sfdx_cli_not_found: 'Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [%s](%s)', + sfdx_cli_not_supported: + 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [%s](%s)', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts index 7da62d6a76..2f432f6926 100644 --- a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts +++ b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts @@ -38,6 +38,15 @@ export function showCLINotInstalledMessage() { window.showErrorMessage(showMessage); } +export function showCLINotSupportedMessage() { + const showMessage = nls.localize( + 'sfdx_cli_not_supported', + SFDX_CLI_DOWNLOAD_LINK, + SFDX_CLI_DOWNLOAD_LINK + ); + window.showErrorMessage(showMessage); +} + export function disableCLITelemetry() { GlobalCliEnvironment.environmentVariables.set( ENV_SF_DISABLE_TELEMETRY, diff --git a/packages/salesforcedx-vscode-core/src/util/index.ts b/packages/salesforcedx-vscode-core/src/util/index.ts index 371183fd0b..8573f08812 100644 --- a/packages/salesforcedx-vscode-core/src/util/index.ts +++ b/packages/salesforcedx-vscode-core/src/util/index.ts @@ -10,7 +10,8 @@ export { disableCLITelemetry, isCLIInstalled, isCLITelemetryAllowed, - showCLINotInstalledMessage + showCLINotInstalledMessage, + showCLINotSupportedMessage } from './cliConfiguration'; export { workspaceUtils } from './rootWorkspace'; export { MetadataDictionary, MetadataInfo } from './metadataDictionary'; From c6fc6dabc087a3d30f38e0dfb8ada37eff5a7a6a Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 25 Oct 2023 23:38:45 -0400 Subject: [PATCH 09/52] chore: remove logging --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 0cfcaa9b87..9f3698c1b8 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -25,7 +25,6 @@ export class CheckCliVersion { // Save the result of the command const cmdOutput = new CommandOutput(); const result = await cmdOutput.getCmdResult(execution); - console.log('**** result = ' + result); // Parse the result to check if the version is supported const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; From c44ae108377a1c3c75516df0fea978796780a493 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Fri, 27 Oct 2023 17:15:04 -0400 Subject: [PATCH 10/52] chore: make error messages more consistent --- packages/salesforcedx-vscode-core/src/messages/i18n.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index 7e289c1fb3..817c0ceb30 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -292,7 +292,7 @@ export const messages = { sfdx_cli_not_found: 'Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [%s](%s)', sfdx_cli_not_supported: - 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [%s](%s)', + 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From 0936d5706d44b5a809c1c5180a35c51bf9d3fb70 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 5 Nov 2023 21:45:22 -0500 Subject: [PATCH 11/52] refactor: use enums instead of returning strings --- .../src/cli/checkCliVersion.ts | 18 ++++++++++++------ packages/salesforcedx-utils/src/cli/index.ts | 2 +- packages/salesforcedx-vscode-core/src/index.ts | 6 +++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 9f3698c1b8..c8624e0ea2 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -9,9 +9,15 @@ import { SfdxCommandBuilder } from './sfdxCommandBuilder'; import { CliCommandExecutor } from './cliCommandExecutor'; import { CommandOutput } from './commandOutput'; +export enum CheckCliEnum { + validCli = 1, + cliNotSupported = 2, + cliNotInstalled = 3 +} + export class CheckCliVersion { - public async validateCliVersion(): Promise { + public async validateCliVersion(): Promise { // Execute the command "sfdx --version" in the Terminal const execution = new CliCommandExecutor( @@ -39,10 +45,10 @@ export class CheckCliVersion { const sfdxVersionNumber = sfdxVersion.split('.').map(Number); // The last working version of SFDX is v7.193.2 if (sfdxVersionNumber[0] >= 7 && sfdxVersionNumber[1] >= 193 && sfdxVersionNumber[2] >= 2) { - return 'validCli'; + return CheckCliEnum.validCli; } else { - return 'cliNotSupported'; + return CheckCliEnum.cliNotSupported; } } @@ -52,16 +58,16 @@ export class CheckCliVersion { const sfVersionNumber = sfVersion.split('.').map(Number); // SF v1 does not map sf commands to sfdx commands and is not supported if (sfVersionNumber[0] >= 2 && sfVersionNumber[1] >= 0 && sfVersionNumber[2] >= 0) { - return 'validCli'; + return CheckCliEnum.validCli; } else { - return 'cliNotSupported'; + return CheckCliEnum.cliNotSupported; } } // Case 3: Neither SFDX CLI nor SF CLI is installed else { - return 'cliNotInstalled'; + return CheckCliEnum.cliNotInstalled; } } } \ No newline at end of file diff --git a/packages/salesforcedx-utils/src/cli/index.ts b/packages/salesforcedx-utils/src/cli/index.ts index 9a95b477e0..67e9f6cfc0 100644 --- a/packages/salesforcedx-utils/src/cli/index.ts +++ b/packages/salesforcedx-utils/src/cli/index.ts @@ -6,4 +6,4 @@ export { ForceConfigGet } from './forceConfigGet'; export { GlobalCliEnvironment } from './globalCliEnvironment'; export { OrgDisplay } from './orgDisplay'; export { SfdxCommandBuilder } from './sfdxCommandBuilder'; -export { CheckCliVersion } from './checkCliVersion'; +export { CheckCliEnum, CheckCliVersion } from './checkCliVersion'; diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 9f402b2bbc..eebbc1f949 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -4,7 +4,7 @@ * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; +import { CheckCliEnum, CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; import { ChannelService, getRootWorkspacePath, @@ -563,10 +563,10 @@ export async function activate(extensionContext: vscode.ExtensionContext) { showCLINotInstalledMessage(); } const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(); - if (cliVersionCheckResult === 'cliNotSupported') { + if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { showCLINotSupportedMessage(); throw new Error(); - } else if (cliVersionCheckResult === 'cliNotInstalled') { + } else if (cliVersionCheckResult === CheckCliEnum.cliNotInstalled) { showCLINotInstalledMessage(); throw new Error(); } From b2aced93128fb636444e02b2c46dbf2f3fd5d295 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 5 Nov 2023 22:15:38 -0500 Subject: [PATCH 12/52] refactor: separate getCliVersion() into another function to make the code unit testable --- .../salesforcedx-utils/src/cli/checkCliVersion.ts | 12 +++++++----- packages/salesforcedx-vscode-core/src/index.ts | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index c8624e0ea2..fa2f0fc029 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -17,8 +17,7 @@ export enum CheckCliEnum { export class CheckCliVersion { - public async validateCliVersion(): Promise { - + public async getCliVersion(): Promise { // Execute the command "sfdx --version" in the Terminal const execution = new CliCommandExecutor( new SfdxCommandBuilder() @@ -30,14 +29,17 @@ export class CheckCliVersion { // Save the result of the command const cmdOutput = new CommandOutput(); - const result = await cmdOutput.getCmdResult(execution); + return await cmdOutput.getCmdResult(execution); + } + + public async validateCliVersion(cliVersion: string): Promise { // Parse the result to check if the version is supported const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; - const sfdxMatch = sfdxPattern.exec(result); - const sfMatch = sfPattern.exec(result); + const sfdxMatch = sfdxPattern.exec(cliVersion); + const sfMatch = sfPattern.exec(cliVersion); // Case 1: SFDX CLI is installed if (sfdxMatch) { diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index eebbc1f949..0e40bb9156 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -562,7 +562,8 @@ export async function activate(extensionContext: vscode.ExtensionContext) { if (!installed) { showCLINotInstalledMessage(); } - const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(); + const cliVersion = await new CheckCliVersion().getCliVersion(); + const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(cliVersion); if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { showCLINotSupportedMessage(); throw new Error(); From 7a93ee6da181352e686431fd1aec2fa786e5da73 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Mon, 6 Nov 2023 11:34:14 -0500 Subject: [PATCH 13/52] feat: add Jest unit tests for checkCliVersion.ts --- .../test/jest/cli/checkCliVersion.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts new file mode 100644 index 0000000000..46b7a63abd --- /dev/null +++ b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts @@ -0,0 +1,53 @@ +import { CheckCliVersion } from '../../../src'; + +describe('CheckCliVersion unit tests.', () => { + + const validSFVersion = '@salesforce/cli/2.15.9 darwin-arm64 node-v18.17.1'; + const validSFDXVersion = 'sfdx-cli/7.209.6 win32-x64 node-v18.15.0'; + const outdatedSFVersion = '@salesforce/cli/1.87.0 darwin-arm64 node-v18.17.1'; + const outdatedSFDXVersion = 'sfdx-cli/7.183.1 darwin-arm64 node-v16.19.1'; + const emptyString = ''; + const dummyText = 'dummy text'; + + it('Should create instance.', () => { + const checkCliVersion = new CheckCliVersion(); + expect(checkCliVersion).toBeInstanceOf(CheckCliVersion); + }); + + it('SF v2 should be a valid CLI version', async () => { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(validSFVersion); + expect(result).toBe(1); + }); + + it('SF v1 should NOT be a valid CLI version', async () => { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(outdatedSFVersion); + expect(result).toBe(2); + }); + + it('SFDX >=v1.193.2 should be a valid CLI version', async () => { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(validSFDXVersion); + expect(result).toBe(1); + }); + + it('SFDX { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(outdatedSFDXVersion); + expect(result).toBe(2); + }); + + it('Empty string should NOT be a valid CLI version', async () => { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(emptyString); + expect(result).toBe(3); + }); + + it('Dummy text should NOT be a valid CLI version', async () => { + const checkCliVersion = new CheckCliVersion(); + const result = await checkCliVersion.validateCliVersion(dummyText); + expect(result).toBe(3); + }); + +}); \ No newline at end of file From d6ddd1b39b12b6f33603e01eb36aa6fdea6f2b94 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Mon, 6 Nov 2023 11:46:05 -0500 Subject: [PATCH 14/52] fix: cliConfiguration.test.ts checks for error instead of warning when CLI is not installed --- .../test/vscode-integration/util/cliConfiguration.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts b/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts index a466860964..9612c4c904 100644 --- a/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts +++ b/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts @@ -67,12 +67,12 @@ describe('SFDX CLI Configuration utility', () => { }); describe('showCLINotInstalledMessage', () => { - let mShowWarning: SinonStub; + let mShowError: SinonStub; beforeEach(() => { sandboxStub = createSandbox(); - mShowWarning = sandboxStub - .stub(window, 'showWarningMessage') + mShowError = sandboxStub + .stub(window, 'showErrorMessage') .returns(Promise.resolve(null)); }); @@ -82,7 +82,7 @@ describe('SFDX CLI Configuration utility', () => { it('Should show cli install info message', async () => { showCLINotInstalledMessage(); - assert.calledOnce(mShowWarning); + assert.calledOnce(mShowError); }); }); From 1baa2cd01f9ba4d833155732af5fbef8b8359503 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 9 Nov 2023 13:10:36 -0500 Subject: [PATCH 15/52] refactor: move validation of CLI installation and version from activate() to helper function --- .../salesforcedx-vscode-core/src/index.ts | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 911d8e5deb..7da43cd5f3 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -1,9 +1,9 @@ -/* - * Copyright (c) 2017, salesforce.com, inc. +/** + * Copyright (c) 2023, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ + **/ import { CheckCliEnum, CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; import { ChannelService, @@ -522,21 +522,7 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - // Check that the CLI is installed and that it is a supported version - // If there is no CLI or it is an unsupported version then the Core extension will not activate - const installed = await isCLIInstalled(); - if (!installed) { - showCLINotInstalledMessage(); - } - const cliVersion = await new CheckCliVersion().getCliVersion(); - const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(cliVersion); - if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { - showCLINotSupportedMessage(); - throw new Error(); - } else if (cliVersionCheckResult === CheckCliEnum.cliNotInstalled) { - showCLINotInstalledMessage(); - throw new Error(); - } + await validateCliInstallationAndVersion(); await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); @@ -701,3 +687,21 @@ export function deactivate(): Promise { disposeTraceFlagExpiration(); return turnOffLogging(); } + +export async function validateCliInstallationAndVersion(): Promise { + // Check that the CLI is installed and that it is a supported version + // If there is no CLI or it is an unsupported version then the Core extension will not activate + const installed = await isCLIInstalled(); + if (!installed) { + showCLINotInstalledMessage(); + } + const cliVersion = await new CheckCliVersion().getCliVersion(); + const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(cliVersion); + if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { + showCLINotSupportedMessage(); + throw new Error(); + } else if (cliVersionCheckResult === CheckCliEnum.cliNotInstalled) { + showCLINotInstalledMessage(); + throw new Error(); + } +} From 7b984018efb0ba6b4a7e2eb9d437f8048123b128 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 9 Nov 2023 15:33:47 -0500 Subject: [PATCH 16/52] fix: add error messages to avoid throwing empty errors --- packages/salesforcedx-vscode-core/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 7da43cd5f3..48b12f9a3e 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -699,9 +699,9 @@ export async function validateCliInstallationAndVersion(): Promise { const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(cliVersion); if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { showCLINotSupportedMessage(); - throw new Error(); + throw new Error('CLI version is no longer supported'); } else if (cliVersionCheckResult === CheckCliEnum.cliNotInstalled) { showCLINotInstalledMessage(); - throw new Error(); + throw new Error('Salesforce CLI is not installed'); } } From 3d5383acfa9809832f2e074135f6456184c7e1b9 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 9 Nov 2023 15:56:44 -0500 Subject: [PATCH 17/52] fix: turn off trailing commas in .prettierrc so that files can pass linting --- .prettierrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index 57a1013229..d2c6710849 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,6 @@ { "printWidth": 80, "tabWidth": 2, - "singleQuote": true + "singleQuote": true, + "trailingComma": "none" } From 8f7d0fe5219edbb01cc96054362f90ea28911e81 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 9 Nov 2023 16:05:00 -0500 Subject: [PATCH 18/52] chore: run prettier on checkCliVersion.ts --- .../src/cli/checkCliVersion.ts | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index fa2f0fc029..55e69f3336 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -1,13 +1,13 @@ -/* +/** * Copyright (c) 2023, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ + **/ -import { SfdxCommandBuilder } from './sfdxCommandBuilder'; import { CliCommandExecutor } from './cliCommandExecutor'; import { CommandOutput } from './commandOutput'; +import { SfdxCommandBuilder } from './sfdxCommandBuilder'; export enum CheckCliEnum { validCli = 1, @@ -16,16 +16,12 @@ export enum CheckCliEnum { } export class CheckCliVersion { - public async getCliVersion(): Promise { // Execute the command "sfdx --version" in the Terminal const execution = new CliCommandExecutor( - new SfdxCommandBuilder() - .withArg('--version') - .withJson() - .build(), - {} - ).execute(); + new SfdxCommandBuilder().withArg('--version').withJson().build(), + {} + ).execute(); // Save the result of the command const cmdOutput = new CommandOutput(); @@ -33,7 +29,6 @@ export class CheckCliVersion { } public async validateCliVersion(cliVersion: string): Promise { - // Parse the result to check if the version is supported const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; @@ -46,10 +41,13 @@ export class CheckCliVersion { const sfdxVersion = sfdxMatch[1]; const sfdxVersionNumber = sfdxVersion.split('.').map(Number); // The last working version of SFDX is v7.193.2 - if (sfdxVersionNumber[0] >= 7 && sfdxVersionNumber[1] >= 193 && sfdxVersionNumber[2] >= 2) { + if ( + sfdxVersionNumber[0] >= 7 && + sfdxVersionNumber[1] >= 193 && + sfdxVersionNumber[2] >= 2 + ) { return CheckCliEnum.validCli; - } - else { + } else { return CheckCliEnum.cliNotSupported; } } @@ -59,10 +57,13 @@ export class CheckCliVersion { const sfVersion = sfMatch[1]; const sfVersionNumber = sfVersion.split('.').map(Number); // SF v1 does not map sf commands to sfdx commands and is not supported - if (sfVersionNumber[0] >= 2 && sfVersionNumber[1] >= 0 && sfVersionNumber[2] >= 0) { + if ( + sfVersionNumber[0] >= 2 && + sfVersionNumber[1] >= 0 && + sfVersionNumber[2] >= 0 + ) { return CheckCliEnum.validCli; - } - else { + } else { return CheckCliEnum.cliNotSupported; } } @@ -72,4 +73,4 @@ export class CheckCliVersion { return CheckCliEnum.cliNotInstalled; } } -} \ No newline at end of file +} From bc594e3bf810df9ccbd80741f05a3b30fe80750d Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 9 Nov 2023 16:35:36 -0500 Subject: [PATCH 19/52] refactor: use constants for SFDX CLI and SF CLI versions --- .../src/cli/checkCliVersion.ts | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 55e69f3336..d6c99e8f2a 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -29,6 +29,14 @@ export class CheckCliVersion { } public async validateCliVersion(cliVersion: string): Promise { + // The last working version of SFDX is v7.193.2 + const minSFDXVersion = '7.193.2'; + const minSFDXVersionArray = minSFDXVersion.split('.').map(Number); + + // SF v1 does not map sf commands to sfdx commands and is not supported + const minSFVersion = '2.0.0'; + const minSFVersionArray = minSFVersion.split('.').map(Number); + // Parse the result to check if the version is supported const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; @@ -40,11 +48,10 @@ export class CheckCliVersion { if (sfdxMatch) { const sfdxVersion = sfdxMatch[1]; const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - // The last working version of SFDX is v7.193.2 if ( - sfdxVersionNumber[0] >= 7 && - sfdxVersionNumber[1] >= 193 && - sfdxVersionNumber[2] >= 2 + sfdxVersionNumber[0] >= minSFDXVersionArray[0] && + sfdxVersionNumber[1] >= minSFDXVersionArray[1] && + sfdxVersionNumber[2] >= minSFDXVersionArray[2] ) { return CheckCliEnum.validCli; } else { @@ -56,11 +63,10 @@ export class CheckCliVersion { else if (sfMatch) { const sfVersion = sfMatch[1]; const sfVersionNumber = sfVersion.split('.').map(Number); - // SF v1 does not map sf commands to sfdx commands and is not supported if ( - sfVersionNumber[0] >= 2 && - sfVersionNumber[1] >= 0 && - sfVersionNumber[2] >= 0 + sfVersionNumber[0] >= minSFVersionArray[0] && + sfVersionNumber[1] >= minSFVersionArray[1] && + sfVersionNumber[2] >= minSFVersionArray[2] ) { return CheckCliEnum.validCli; } else { From 31d01156794fa18bfc6097ca540e3f2a11e436e0 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 28 Nov 2023 10:04:39 -0500 Subject: [PATCH 20/52] feat: add support to throw error when both SFDX v7 and SF v2 are present --- .../src/cli/checkCliVersion.ts | 127 ++++++++++------ .../src/cli/sfCommandBuilder.ts | 8 + .../src/constants/constants.ts | 1 + .../test/jest/cli/checkCliVersion.test.ts | 142 ++++++++++++++---- .../salesforcedx-vscode-core/src/index.ts | 50 ++++-- .../src/messages/i18n.ja.ts | 6 +- .../src/messages/i18n.ts | 6 +- .../src/util/cliConfiguration.ts | 11 +- .../src/util/index.ts | 3 +- .../util/cliConfiguration.test.ts | 8 +- 10 files changed, 254 insertions(+), 108 deletions(-) create mode 100644 packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index d6c99e8f2a..c0e6cec4c3 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -7,28 +7,82 @@ import { CliCommandExecutor } from './cliCommandExecutor'; import { CommandOutput } from './commandOutput'; +import { SfCommandBuilder } from './sfCommandBuilder'; import { SfdxCommandBuilder } from './sfdxCommandBuilder'; export enum CheckCliEnum { validCli = 1, - cliNotSupported = 2, - cliNotInstalled = 3 + outdatedSFDXVersion = 2, + onlySFv1 = 3, + cliNotInstalled = 4, + bothSFDXAndSFInstalled = 5 } export class CheckCliVersion { - public async getCliVersion(): Promise { - // Execute the command "sfdx --version" in the Terminal - const execution = new CliCommandExecutor( - new SfdxCommandBuilder().withArg('--version').withJson().build(), - {} - ).execute(); - // Save the result of the command - const cmdOutput = new CommandOutput(); - return await cmdOutput.getCmdResult(execution); + public async getSfdxCliVersion(): Promise { + try { + // Execute the command "sfdx --version" in the Terminal + const sfdxExecution = new CliCommandExecutor( + new SfdxCommandBuilder().withArg('--version').withJson().build(), + {} + ).execute(); + // Save the result of the command + const sfdxCmdOutput = new CommandOutput(); + const sfdxVersion = await sfdxCmdOutput.getCmdResult(sfdxExecution); + return sfdxVersion; + } catch { + return 'No SFDX CLI'; + } + } + + public async getSfCliVersion(): Promise { + try { + // Execute the command "sf --version" in the Terminal + const sfExecution = new CliCommandExecutor( + new SfCommandBuilder().withArg('--version').withJson().build(), + {} + ).execute(); + // Save the result of the command + const sfCmdOutput = new CommandOutput(); + const sfVersion = await sfCmdOutput.getCmdResult(sfExecution); + return sfVersion; + } catch { + return 'No SF CLI'; + } + } + + public async parseSfdxCliVersion(sfdxCliVersion: string): Promise { + // Both SFDX and SF v2 can match a valid SFDX version, so there are 2 patterns to search for + const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; + const sfdxMatch = sfdxPattern.exec(sfdxCliVersion); + const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + const sfMatch = sfPattern.exec(sfdxCliVersion); + if (sfdxMatch) { + const sfdxVersion = sfdxMatch[1]; + const sfdxVersionNumber = sfdxVersion.split('.').map(Number); + return sfdxVersionNumber; + } + else if (sfMatch) { + const sfdxVersion = sfMatch[1]; + const sfdxVersionNumber = sfdxVersion.split('.').map(Number); + return sfdxVersionNumber; + } + return [-1]; } - public async validateCliVersion(cliVersion: string): Promise { + public async parseSfCliVersion(sfCliVersion: string): Promise { + const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + const sfMatch = sfPattern.exec(sfCliVersion); + if (sfMatch) { + const sfVersion = sfMatch[1]; + const sfVersionNumber = sfVersion.split('.').map(Number); + return sfVersionNumber; + } + return [-1]; + } + + public async validateCliInstallationAndVersion(sfdxCliVersionArray: number[], sfCliVersionArray: number[]): Promise { // The last working version of SFDX is v7.193.2 const minSFDXVersion = '7.193.2'; const minSFDXVersionArray = minSFDXVersion.split('.').map(Number); @@ -37,46 +91,35 @@ export class CheckCliVersion { const minSFVersion = '2.0.0'; const minSFVersionArray = minSFVersion.split('.').map(Number); - // Parse the result to check if the version is supported - const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; - const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + // Case 1: Neither SFDX CLI nor SF CLI is installed + if (sfdxCliVersionArray[0] === -1 && sfCliVersionArray[0] === -1) { + return CheckCliEnum.cliNotInstalled; + } - const sfdxMatch = sfdxPattern.exec(cliVersion); - const sfMatch = sfPattern.exec(cliVersion); + // Case 2: Only SF CLI (v1) is installed (SF v1 cannot be used because it does not map sf to sfdx) + if (sfdxCliVersionArray[0] === -1 && sfCliVersionArray[0] === 1) { + return CheckCliEnum.onlySFv1; + } - // Case 1: SFDX CLI is installed - if (sfdxMatch) { - const sfdxVersion = sfdxMatch[1]; - const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - if ( - sfdxVersionNumber[0] >= minSFDXVersionArray[0] && - sfdxVersionNumber[1] >= minSFDXVersionArray[1] && - sfdxVersionNumber[2] >= minSFDXVersionArray[2] - ) { - return CheckCliEnum.validCli; - } else { - return CheckCliEnum.cliNotSupported; - } + // Case 3: Both SFDX CLI (v7) and SF CLI (v2) are installed at the same time + if (sfCliVersionArray[0] >= minSFVersionArray[0] && !sfdxCliVersionArray.every((val, index) => val === sfCliVersionArray[index])) { + return CheckCliEnum.bothSFDXAndSFInstalled; } - // Case 2: SF CLI is installed - else if (sfMatch) { - const sfVersion = sfMatch[1]; - const sfVersionNumber = sfVersion.split('.').map(Number); + // Case 4: SFDX CLI is installed - need to validate if the version is above the minimum supported version + if (sfCliVersionArray[0] < minSFVersionArray[0] && sfdxCliVersionArray[0] !== -1) { if ( - sfVersionNumber[0] >= minSFVersionArray[0] && - sfVersionNumber[1] >= minSFVersionArray[1] && - sfVersionNumber[2] >= minSFVersionArray[2] + sfdxCliVersionArray[0] >= minSFDXVersionArray[0] && + sfdxCliVersionArray[1] >= minSFDXVersionArray[1] && + sfdxCliVersionArray[2] >= minSFDXVersionArray[2] ) { return CheckCliEnum.validCli; } else { - return CheckCliEnum.cliNotSupported; + return CheckCliEnum.outdatedSFDXVersion; } } - // Case 3: Neither SFDX CLI nor SF CLI is installed - else { - return CheckCliEnum.cliNotInstalled; - } + // Case 5: SF v2 is installed + return CheckCliEnum.validCli; } } diff --git a/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts b/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts new file mode 100644 index 0000000000..a96e3cd1ea --- /dev/null +++ b/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts @@ -0,0 +1,8 @@ +import { SF_COMMAND } from '../constants'; +import { CommandBuilder } from './commandBuilder'; + +export class SfCommandBuilder extends CommandBuilder { + public constructor() { + super(SF_COMMAND); + } +} diff --git a/packages/salesforcedx-utils/src/constants/constants.ts b/packages/salesforcedx-utils/src/constants/constants.ts index 34434d9817..40e8b16397 100644 --- a/packages/salesforcedx-utils/src/constants/constants.ts +++ b/packages/salesforcedx-utils/src/constants/constants.ts @@ -17,6 +17,7 @@ export const DEFAULT_LOCALE = 'en'; export const LOCALE_JA = 'ja'; export const MISSING_LABEL_MSG = '!!! MISSING LABEL !!!'; export const SFDX_COMMAND = 'sfdx'; +export const SF_COMMAND = 'sf'; export const SFDX_CONFIG_ISV_DEBUGGER_SID = 'isvDebuggerSid'; export const SFDX_CONFIG_ISV_DEBUGGER_URL = 'isvDebuggerUrl'; export const TELEMETRY_HEADER = 'salesforce-vscode-extensions'; diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts index 46b7a63abd..c71be81b4c 100644 --- a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts @@ -1,53 +1,129 @@ -import { CheckCliVersion } from '../../../src'; +import { CheckCliEnum, CheckCliVersion } from '../../../src'; describe('CheckCliVersion unit tests.', () => { - const validSFVersion = '@salesforce/cli/2.15.9 darwin-arm64 node-v18.17.1'; - const validSFDXVersion = 'sfdx-cli/7.209.6 win32-x64 node-v18.15.0'; - const outdatedSFVersion = '@salesforce/cli/1.87.0 darwin-arm64 node-v18.17.1'; - const outdatedSFDXVersion = 'sfdx-cli/7.183.1 darwin-arm64 node-v16.19.1'; - const emptyString = ''; - const dummyText = 'dummy text'; + const sfV2_string = '@salesforce/cli/2.15.9 darwin-arm64 node-v18.17.1'; + const sfdxV7_valid_string = 'sfdx-cli/7.209.6 win32-x64 node-v18.15.0'; + const sfV1_string = '@salesforce/cli/1.87.0 darwin-arm64 node-v18.17.1'; + const sfdxV7_outdated_string = 'sfdx-cli/7.183.1 darwin-arm64 node-v16.19.1'; + const noSFDX_string = 'No SFDX CLI'; + const noSF_string = 'No SF CLI'; + + const sfV2_array = [2, 15, 9]; + const sfdxV7_valid_array = [7, 209, 6]; + const sfV1_array = [1, 87, 0]; + const sfdxV7_outdated_array = [7, 183, 1]; + const noSFDX_array = [-1]; + const noSF_array = [-1]; it('Should create instance.', () => { - const checkCliVersion = new CheckCliVersion(); - expect(checkCliVersion).toBeInstanceOf(CheckCliVersion); + const c = new CheckCliVersion(); + expect(c).toBeInstanceOf(CheckCliVersion); + }); + + /* + Test cases for the parseSfdxCliVersion() function + */ + it('Parse valid SFDX', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfdxV7_valid_string); + expect(result).toStrictEqual(sfdxV7_valid_array); + }); + + it('Parse outdated SFDX', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfdxV7_outdated_string); + expect(result).toStrictEqual(sfdxV7_outdated_array); + }); + + it('Parse valid SF v2', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfV2_string); + expect(result).toStrictEqual(sfV2_array); + }); + + it('Parse SFDX not installed', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(noSFDX_string); + expect(result).toStrictEqual(noSFDX_array); + }); + + /* + Test cases for the parseSfCliVersion() function + */ + it('Parse SF v1', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(sfV1_string); + expect(result).toStrictEqual(sfV1_array); + }); + + it('Parse SF v2', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(sfV2_string); + expect(result).toStrictEqual(sfV2_array); + }); + + it('Parse SF not installed', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(noSF_string); + expect(result).toStrictEqual(noSF_array); + }); + + /* + Test cases for the validateCliInstallationAndVersion() function + */ + it('Case 1: No Salesforce CLI installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(noSFDX_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.cliNotInstalled); + }); + + it('Case 2: Only SF v1 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(noSFDX_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.onlySFv1); + }); + + it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); }); - it('SF v2 should be a valid CLI version', async () => { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(validSFVersion); - expect(result).toBe(1); + it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); }); - it('SF v1 should NOT be a valid CLI version', async () => { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(outdatedSFVersion); - expect(result).toBe(2); + it('Case 5: Only SFDX v7 (outdated) installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); }); - it('SFDX >=v1.193.2 should be a valid CLI version', async () => { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(validSFDXVersion); - expect(result).toBe(1); + it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); }); - it('SFDX { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(outdatedSFDXVersion); - expect(result).toBe(2); + it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); }); - it('Empty string should NOT be a valid CLI version', async () => { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(emptyString); - expect(result).toBe(3); + it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); }); - it('Dummy text should NOT be a valid CLI version', async () => { - const checkCliVersion = new CheckCliVersion(); - const result = await checkCliVersion.validateCliVersion(dummyText); - expect(result).toBe(3); + it('Case 9: Only SF v2 installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfV2_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); }); }); \ No newline at end of file diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 8642909da2..8c561aa0aa 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -109,8 +109,10 @@ import { isSfdxProjectOpened } from './predicates'; import { registerPushOrDeployOnSave, sfdxCoreSettings } from './settings'; import { taskViewService } from './statuses'; import { showTelemetryMessage, telemetryService } from './telemetry'; -import { isCLIInstalled, setUpOrgExpirationWatcher, showCLINotInstalledMessage, showCLINotSupportedMessage } from './util'; +import { isCLIInstalled, setUpOrgExpirationWatcher } from './util'; import { OrgAuthInfo } from './util/authInfo'; +import { nls } from './messages'; +import { SFDX_CLI_DOWNLOAD_LINK } from './constants'; const flagOverwrite: FlagParameter = { flag: '--forceoverwrite' @@ -527,9 +529,7 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - await validateCliInstallationAndVersion(); - await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); @@ -697,17 +697,37 @@ export function deactivate(): Promise { export async function validateCliInstallationAndVersion(): Promise { // Check that the CLI is installed and that it is a supported version // If there is no CLI or it is an unsupported version then the Core extension will not activate - const installed = await isCLIInstalled(); - if (!installed) { - showCLINotInstalledMessage(); - } - const cliVersion = await new CheckCliVersion().getCliVersion(); - const cliVersionCheckResult = await new CheckCliVersion().validateCliVersion(cliVersion); - if (cliVersionCheckResult === CheckCliEnum.cliNotSupported) { - showCLINotSupportedMessage(); - throw new Error('CLI version is no longer supported'); - } else if (cliVersionCheckResult === CheckCliEnum.cliNotInstalled) { - showCLINotInstalledMessage(); - throw new Error('Salesforce CLI is not installed'); + const c = new CheckCliVersion(); + + const sfdxCliVersionString = await c.getSfdxCliVersion(); + const sfCliVersionString = await c.getSfCliVersion(); + + const sfdxCliVersionArray = await c.parseSfdxCliVersion(sfdxCliVersionString); + const sfCliVersionArray = await c.parseSfCliVersion(sfCliVersionString); + + const cliInstallationResult = await c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); + + if (cliInstallationResult === CheckCliEnum.cliNotInstalled) { + showPopupMessage('sfdx_cli_not_found', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + throw Error('No Salesforce CLI installed'); + } else if (cliInstallationResult === CheckCliEnum.onlySFv1) { + showPopupMessage('sf_v1_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + throw Error('Only SF v1 installed'); + } else if (cliInstallationResult === CheckCliEnum.outdatedSFDXVersion) { + showPopupMessage('sfdx_cli_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + throw Error('Outdated SFDX CLI version that is no longer supported'); + } else if (cliInstallationResult === CheckCliEnum.bothSFDXAndSFInstalled) { + showPopupMessage('both_sfdx_and_sf', []); + throw Error('Both SFDX v7 and SF v2 are installed'); + } else { + // do nothing - this is a valid CLI version that is compatible with the extensions } } + +export function showPopupMessage(type: string, args: any[]) { + const showMessage = nls.localize( + type, + ...args + ); + vscode.window.showErrorMessage(showMessage); +} diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 39c849a1a9..6abbf55647 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -251,7 +251,11 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI がインストールされていません。[%s](%s) からインストールしてください。', sfdx_cli_not_supported: - '!!! Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version using this link: [%s](%s)', + '--- Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + sf_v1_not_supported: + '--- Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + both_sfdx_and_sf: + '--- You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index ba8507bfd3..244beb63e9 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -291,9 +291,13 @@ export const messages = { error_parsing_sfdx_project_file: "Couldn't parse sfdx-project.json file (%s). Parse error: %s", sfdx_cli_not_found: - 'Either Salesforce CLI is not installed or only SF v1 is present. Install the latest CLI version from [%s](%s)', + 'Salesforce CLI is not installed. Install it from [%s](%s)', sfdx_cli_not_supported: 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + sf_v1_not_supported: + 'Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + both_sfdx_and_sf: + 'You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts index 2f432f6926..5d094f3c19 100644 --- a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts +++ b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts @@ -35,16 +35,7 @@ export function showCLINotInstalledMessage() { SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK ); - window.showErrorMessage(showMessage); -} - -export function showCLINotSupportedMessage() { - const showMessage = nls.localize( - 'sfdx_cli_not_supported', - SFDX_CLI_DOWNLOAD_LINK, - SFDX_CLI_DOWNLOAD_LINK - ); - window.showErrorMessage(showMessage); + window.showWarningMessage(showMessage); } export function disableCLITelemetry() { diff --git a/packages/salesforcedx-vscode-core/src/util/index.ts b/packages/salesforcedx-vscode-core/src/util/index.ts index 8573f08812..371183fd0b 100644 --- a/packages/salesforcedx-vscode-core/src/util/index.ts +++ b/packages/salesforcedx-vscode-core/src/util/index.ts @@ -10,8 +10,7 @@ export { disableCLITelemetry, isCLIInstalled, isCLITelemetryAllowed, - showCLINotInstalledMessage, - showCLINotSupportedMessage + showCLINotInstalledMessage } from './cliConfiguration'; export { workspaceUtils } from './rootWorkspace'; export { MetadataDictionary, MetadataInfo } from './metadataDictionary'; diff --git a/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts b/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts index 9612c4c904..a466860964 100644 --- a/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts +++ b/packages/salesforcedx-vscode-core/test/vscode-integration/util/cliConfiguration.test.ts @@ -67,12 +67,12 @@ describe('SFDX CLI Configuration utility', () => { }); describe('showCLINotInstalledMessage', () => { - let mShowError: SinonStub; + let mShowWarning: SinonStub; beforeEach(() => { sandboxStub = createSandbox(); - mShowError = sandboxStub - .stub(window, 'showErrorMessage') + mShowWarning = sandboxStub + .stub(window, 'showWarningMessage') .returns(Promise.resolve(null)); }); @@ -82,7 +82,7 @@ describe('SFDX CLI Configuration utility', () => { it('Should show cli install info message', async () => { showCLINotInstalledMessage(); - assert.calledOnce(mShowError); + assert.calledOnce(mShowWarning); }); }); From 5bc03f73311d177d1c2d02ae8eb07c7b09f6bcd4 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 28 Nov 2023 10:18:25 -0500 Subject: [PATCH 21/52] chore: change function name from showPopupMessage() to showErrorNotification() --- packages/salesforcedx-vscode-core/src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 8c561aa0aa..23495f42f8 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -708,23 +708,23 @@ export async function validateCliInstallationAndVersion(): Promise { const cliInstallationResult = await c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); if (cliInstallationResult === CheckCliEnum.cliNotInstalled) { - showPopupMessage('sfdx_cli_not_found', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sfdx_cli_not_found', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); throw Error('No Salesforce CLI installed'); } else if (cliInstallationResult === CheckCliEnum.onlySFv1) { - showPopupMessage('sf_v1_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sf_v1_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); throw Error('Only SF v1 installed'); } else if (cliInstallationResult === CheckCliEnum.outdatedSFDXVersion) { - showPopupMessage('sfdx_cli_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sfdx_cli_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); throw Error('Outdated SFDX CLI version that is no longer supported'); } else if (cliInstallationResult === CheckCliEnum.bothSFDXAndSFInstalled) { - showPopupMessage('both_sfdx_and_sf', []); + showErrorNotification('both_sfdx_and_sf', []); throw Error('Both SFDX v7 and SF v2 are installed'); } else { // do nothing - this is a valid CLI version that is compatible with the extensions } } -export function showPopupMessage(type: string, args: any[]) { +export function showErrorNotification(type: string, args: any[]) { const showMessage = nls.localize( type, ...args From c7b3c9ea515be9ed1068eacfe35b36aa460ad47b Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 28 Nov 2023 10:21:19 -0500 Subject: [PATCH 22/52] revert: revert copyright in index.ts --- packages/salesforcedx-vscode-core/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 23495f42f8..ad9f58f3e8 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2023, salesforce.com, inc. +/* + * Copyright (c) 2017, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - **/ + */ import { CheckCliEnum, CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; import { ChannelService, From 9ae6e7132d68ee85d8c729c8e5d8e2d8d8e25922 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 28 Nov 2023 16:01:53 -0500 Subject: [PATCH 23/52] chore: make Japanese error messages just the English messages without extra warnings --- packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 6abbf55647..c2c1f5024d 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -251,11 +251,11 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI がインストールされていません。[%s](%s) からインストールしてください。', sfdx_cli_not_supported: - '--- Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', sf_v1_not_supported: - '--- Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', both_sfdx_and_sf: - '--- You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', + 'You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From 1df5748d6d9ffef71c46bf3832f84b8f20920674 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sat, 2 Dec 2023 08:00:41 -0500 Subject: [PATCH 24/52] fix: add missing export for SfCommandBuilder in index.ts --- packages/salesforcedx-utils/src/cli/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/salesforcedx-utils/src/cli/index.ts b/packages/salesforcedx-utils/src/cli/index.ts index 67e9f6cfc0..9a9e70eb72 100644 --- a/packages/salesforcedx-utils/src/cli/index.ts +++ b/packages/salesforcedx-utils/src/cli/index.ts @@ -6,4 +6,5 @@ export { ForceConfigGet } from './forceConfigGet'; export { GlobalCliEnvironment } from './globalCliEnvironment'; export { OrgDisplay } from './orgDisplay'; export { SfdxCommandBuilder } from './sfdxCommandBuilder'; +export { SfCommandBuilder } from './sfCommandBuilder'; export { CheckCliEnum, CheckCliVersion } from './checkCliVersion'; From 8269907db31e837a5c4faaa14375ddcfe1f577df Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sat, 2 Dec 2023 20:11:21 -0500 Subject: [PATCH 25/52] fix: add export class SfCommandBuilder to commandBuilder.ts --- .../salesforcedx-utils-vscode/src/cli/commandBuilder.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts b/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts index 4d84d3cda2..9c4a4e8163 100644 --- a/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts +++ b/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts @@ -79,3 +79,9 @@ export class SfdxCommandBuilder extends CommandBuilder { super('sfdx'); } } + +export class SfCommandBuilder extends CommandBuilder { + public constructor() { + super('sf'); + } +} From 4c3e78288c730204bb44bef0ad3257497682e909 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 3 Dec 2023 00:29:13 -0500 Subject: [PATCH 26/52] revert: revert changes to commandBuilder.ts --- .../salesforcedx-utils-vscode/src/cli/commandBuilder.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts b/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts index 9c4a4e8163..4d84d3cda2 100644 --- a/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts +++ b/packages/salesforcedx-utils-vscode/src/cli/commandBuilder.ts @@ -79,9 +79,3 @@ export class SfdxCommandBuilder extends CommandBuilder { super('sfdx'); } } - -export class SfCommandBuilder extends CommandBuilder { - public constructor() { - super('sf'); - } -} From 7432e2001123ce2b8c93ef05cea8985c1e974819 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 3 Dec 2023 21:04:39 -0500 Subject: [PATCH 27/52] fix: do not call validateCliInstallationAndVersion() in index.ts if OS is win32 --- packages/salesforcedx-vscode-core/src/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 04a746661c..cdc9cb6a8a 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -537,7 +537,11 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - await validateCliInstallationAndVersion(); + const platform = process.platform.toLowerCase(); + const isWindows = platform === 'win32'; + if (!isWindows) { + await validateCliInstallationAndVersion(); + } setNodeExtraCaCerts(); await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); From f132d69e25a31740732e4a2b610ec84c6ae90a89 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 3 Dec 2023 21:50:42 -0500 Subject: [PATCH 28/52] fix: add/fix headers for checkCliVersion.ts, sfCommandBuilder.ts, checkCliVersion.test.ts --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 4 ++-- packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts | 6 ++++++ .../test/jest/cli/checkCliVersion.test.ts | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index c0e6cec4c3..f8d0c8db4d 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -1,9 +1,9 @@ -/** +/* * Copyright (c) 2023, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - **/ + */ import { CliCommandExecutor } from './cliCommandExecutor'; import { CommandOutput } from './commandOutput'; diff --git a/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts b/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts index a96e3cd1ea..caadbdcba9 100644 --- a/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts +++ b/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ import { SF_COMMAND } from '../constants'; import { CommandBuilder } from './commandBuilder'; diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts index c71be81b4c..a5db48096f 100644 --- a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ import { CheckCliEnum, CheckCliVersion } from '../../../src'; describe('CheckCliVersion unit tests.', () => { From 5b0ced9d01569a695a0a8fc55ffe99145eb9d56a Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 3 Dec 2023 21:57:29 -0500 Subject: [PATCH 29/52] fix: organize imports in index.ts to pass linting --- packages/salesforcedx-vscode-core/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index ef44b7e2e1..c96c313d33 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -93,7 +93,8 @@ import { } from './conflict'; import { ENABLE_SOBJECT_REFRESH_ON_STARTUP, - ORG_OPEN_COMMAND + ORG_OPEN_COMMAND, + SFDX_CLI_DOWNLOAD_LINK } from './constants'; import { WorkspaceContext, workspaceContextUtils } from './context'; import { @@ -101,6 +102,7 @@ import { disposeTraceFlagExpiration, showDemoMode } from './decorators'; +import { nls } from './messages'; import { isDemoMode } from './modes/demo-mode'; import { notificationService, ProgressNotification } from './notifications'; import { orgBrowser } from './orgBrowser'; @@ -115,8 +117,6 @@ import { setNodeExtraCaCerts } from './util'; import { OrgAuthInfo } from './util/authInfo'; -import { nls } from './messages'; -import { SFDX_CLI_DOWNLOAD_LINK } from './constants'; const flagOverwrite: FlagParameter = { flag: '--forceoverwrite' From 75236c6a851e6615ff58cb13d54e5b8fc545dc91 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 09:37:50 -0500 Subject: [PATCH 30/52] refactor: move tests in checkCliVersion.test.ts into describe() functions --- .../test/jest/cli/checkCliVersion.test.ts | 187 +++++++++--------- 1 file changed, 96 insertions(+), 91 deletions(-) diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts index a5db48096f..bedc0729fa 100644 --- a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts @@ -30,106 +30,111 @@ describe('CheckCliVersion unit tests.', () => { /* Test cases for the parseSfdxCliVersion() function */ - it('Parse valid SFDX', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfdxV7_valid_string); - expect(result).toStrictEqual(sfdxV7_valid_array); - }); - - it('Parse outdated SFDX', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfdxV7_outdated_string); - expect(result).toStrictEqual(sfdxV7_outdated_array); - }); - - it('Parse valid SF v2', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfV2_string); - expect(result).toStrictEqual(sfV2_array); - }); - - it('Parse SFDX not installed', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(noSFDX_string); - expect(result).toStrictEqual(noSFDX_array); + describe('Test cases for the parseSfdxCliVersion() function', () => { + it('Parse valid SFDX', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfdxV7_valid_string); + expect(result).toStrictEqual(sfdxV7_valid_array); + }); + + it('Parse outdated SFDX', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfdxV7_outdated_string); + expect(result).toStrictEqual(sfdxV7_outdated_array); + }); + + it('Parse valid SF v2', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(sfV2_string); + expect(result).toStrictEqual(sfV2_array); + }); + + it('Parse SFDX not installed', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfdxCliVersion(noSFDX_string); + expect(result).toStrictEqual(noSFDX_array); + }); }); /* Test cases for the parseSfCliVersion() function */ - it('Parse SF v1', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(sfV1_string); - expect(result).toStrictEqual(sfV1_array); - }); - - it('Parse SF v2', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(sfV2_string); - expect(result).toStrictEqual(sfV2_array); - }); - - it('Parse SF not installed', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(noSF_string); - expect(result).toStrictEqual(noSF_array); + describe('Test cases for the parseSfCliVersion() function', () => { + it('Parse SF v1', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(sfV1_string); + expect(result).toStrictEqual(sfV1_array); + }); + + it('Parse SF v2', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(sfV2_string); + expect(result).toStrictEqual(sfV2_array); + }); + + it('Parse SF not installed', async () => { + const c = new CheckCliVersion(); + const result = await c.parseSfCliVersion(noSF_string); + expect(result).toStrictEqual(noSF_array); + }); }); /* Test cases for the validateCliInstallationAndVersion() function */ - it('Case 1: No Salesforce CLI installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(noSFDX_array, noSF_array); - expect(result).toStrictEqual(CheckCliEnum.cliNotInstalled); + describe('Test cases for the validateCliInstallationAndVersion() function', () => { + it('Case 1: No Salesforce CLI installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(noSFDX_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.cliNotInstalled); + }); + + it('Case 2: Only SF v1 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(noSFDX_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.onlySFv1); + }); + + it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); + }); + + it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); + }); + + it('Case 5: Only SFDX v7 (outdated) installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); + }); + + it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, noSF_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); + }); + + it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); + }); + + it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV1_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); + }); + + it('Case 9: Only SF v2 installed - should activate Core extension', async () => { + const c = new CheckCliVersion(); + const result = await c.validateCliInstallationAndVersion(sfV2_array, sfV2_array); + expect(result).toStrictEqual(CheckCliEnum.validCli); + }); }); - - it('Case 2: Only SF v1 installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(noSFDX_array, sfV1_array); - expect(result).toStrictEqual(CheckCliEnum.onlySFv1); - }); - - it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV2_array); - expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); - }); - - it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV2_array); - expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); - }); - - it('Case 5: Only SFDX v7 (outdated) installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, noSF_array); - expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); - }); - - it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, noSF_array); - expect(result).toStrictEqual(CheckCliEnum.validCli); - }); - - it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV1_array); - expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); - }); - - it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV1_array); - expect(result).toStrictEqual(CheckCliEnum.validCli); - }); - - it('Case 9: Only SF v2 installed - should activate Core extension', async () => { - const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfV2_array, sfV2_array); - expect(result).toStrictEqual(CheckCliEnum.validCli); - }); - }); \ No newline at end of file From 2958f7ecc8d0b3495c2833d7f296147350ced377 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 09:40:26 -0500 Subject: [PATCH 31/52] chore: rename SFDX_CLI_DOWNLOAD_LINK to SF_CLI_DOWNLOAD_LINK --- packages/salesforcedx-vscode-core/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/salesforcedx-vscode-core/src/constants.ts b/packages/salesforcedx-vscode-core/src/constants.ts index ecc7aa6b91..6e71dd8a6f 100644 --- a/packages/salesforcedx-vscode-core/src/constants.ts +++ b/packages/salesforcedx-vscode-core/src/constants.ts @@ -13,7 +13,7 @@ export const STATUS_BAR_MSG_TIMEOUT_MS = 5000; export const APEX_CODE_DEBUG_LEVEL = 'FINEST'; export const VISUALFORCE_DEBUG_LEVEL = 'FINER'; export const ENV_SF_DISABLE_TELEMETRY = 'SF_DISABLE_TELEMETRY'; -export const SFDX_CLI_DOWNLOAD_LINK = +export const SF_CLI_DOWNLOAD_LINK = 'https://developer.salesforce.com/tools/salesforcecli'; export const TARGET_ORG_KEY = 'target-org'; export const PKG_ID_PREFIX = '04t'; From 757eab27557b7ab4fb4d6ad77d5f021daad3e4bd Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 10:10:48 -0500 Subject: [PATCH 32/52] chore: replace all calls to SFDX_CLI_DOWNLOAD_LINK with SF_CLI_DOWNLOAD_LINK --- packages/salesforcedx-vscode-core/src/index.ts | 8 ++++---- .../salesforcedx-vscode-core/src/util/cliConfiguration.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index c96c313d33..19c2ff48d2 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -94,7 +94,7 @@ import { import { ENABLE_SOBJECT_REFRESH_ON_STARTUP, ORG_OPEN_COMMAND, - SFDX_CLI_DOWNLOAD_LINK + SF_CLI_DOWNLOAD_LINK } from './constants'; import { WorkspaceContext, workspaceContextUtils } from './context'; import { @@ -727,13 +727,13 @@ export async function validateCliInstallationAndVersion(): Promise { const cliInstallationResult = await c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); if (cliInstallationResult === CheckCliEnum.cliNotInstalled) { - showErrorNotification('sfdx_cli_not_found', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sfdx_cli_not_found', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('No Salesforce CLI installed'); } else if (cliInstallationResult === CheckCliEnum.onlySFv1) { - showErrorNotification('sf_v1_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sf_v1_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('Only SF v1 installed'); } else if (cliInstallationResult === CheckCliEnum.outdatedSFDXVersion) { - showErrorNotification('sfdx_cli_not_supported', [SFDX_CLI_DOWNLOAD_LINK, SFDX_CLI_DOWNLOAD_LINK]); + showErrorNotification('sfdx_cli_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('Outdated SFDX CLI version that is no longer supported'); } else if (cliInstallationResult === CheckCliEnum.bothSFDXAndSFInstalled) { showErrorNotification('both_sfdx_and_sf', []); diff --git a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts index 13048aa770..a9a2b7ba1a 100644 --- a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts +++ b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts @@ -14,7 +14,7 @@ import { window } from 'vscode'; import { ENV_NODE_EXTRA_CA_CERTS, ENV_SF_DISABLE_TELEMETRY, - SFDX_CLI_DOWNLOAD_LINK + SF_CLI_DOWNLOAD_LINK } from '../constants'; import { nls } from '../messages'; import { sfdxCoreSettings } from '../settings'; @@ -34,8 +34,8 @@ export function isCLIInstalled(): boolean { export function showCLINotInstalledMessage() { const showMessage = nls.localize( 'sfdx_cli_not_found', - SFDX_CLI_DOWNLOAD_LINK, - SFDX_CLI_DOWNLOAD_LINK + SF_CLI_DOWNLOAD_LINK, + SF_CLI_DOWNLOAD_LINK ); window.showWarningMessage(showMessage); } From 04ee5fe9019ec9d4e2cced878b266e62fba3867e Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 10:12:20 -0500 Subject: [PATCH 33/52] chore: remove last else that does nothing --- packages/salesforcedx-vscode-core/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 19c2ff48d2..2b276e98f0 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -738,8 +738,6 @@ export async function validateCliInstallationAndVersion(): Promise { } else if (cliInstallationResult === CheckCliEnum.bothSFDXAndSFInstalled) { showErrorNotification('both_sfdx_and_sf', []); throw Error('Both SFDX v7 and SF v2 are installed'); - } else { - // do nothing - this is a valid CLI version that is compatible with the extensions } } From 4d59a2e8b47b9993142710c8bab3c73934401f44 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 10:26:13 -0500 Subject: [PATCH 34/52] chore: change Number to number for eslint --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index f8d0c8db4d..1fe6e5a020 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -82,7 +82,7 @@ export class CheckCliVersion { return [-1]; } - public async validateCliInstallationAndVersion(sfdxCliVersionArray: number[], sfCliVersionArray: number[]): Promise { + public async validateCliInstallationAndVersion(sfdxCliVersionArray: number[], sfCliVersionArray: number[]): Promise { // The last working version of SFDX is v7.193.2 const minSFDXVersion = '7.193.2'; const minSFDXVersionArray = minSFDXVersion.split('.').map(Number); From bc23525df8d3281441f4239f800bbcda4b48b366 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 5 Dec 2023 12:28:35 -0500 Subject: [PATCH 35/52] fix: user-facing error messages after working with doc writer --- packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts | 6 +++--- packages/salesforcedx-vscode-core/src/messages/i18n.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 303efdaece..6878dc6704 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -251,11 +251,11 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI がインストールされていません。[%s](%s) からインストールしてください。', sfdx_cli_not_supported: - 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed Salesforce CLI version is no longer supported. Uninstall CLI and install the latest version from [%s](%s).', sf_v1_not_supported: - 'Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed Salesforce CLI version is incompatible with all versions of our extensions. Uninstall Salesforce CLI and install the latest version from [%s](%s).', both_sfdx_and_sf: - 'You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', + 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index ca06614f48..712a1606e6 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -293,11 +293,11 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI is not installed. Install it from [%s](%s)', sfdx_cli_not_supported: - 'Your installed CLI version is no longer supported. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed Salesforce CLI version is no longer supported. Uninstall CLI and install the latest version from [%s](%s).', sf_v1_not_supported: - 'Your installed CLI version is incompatible with our extensions. Please uninstall your CLI and reinstall the latest version from [%s](%s)', + 'Your installed Salesforce CLI version is incompatible with all versions of our extensions. Uninstall Salesforce CLI and install the latest version from [%s](%s).', both_sfdx_and_sf: - 'You have both SFDX v7 and SF v2 installed. Please uninstall SFDX v7 by running "npm uninstall sfdx-cli --global" in your Terminal.', + 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From 08560b7c6818addfdb88f6460c766353286cb9af Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Fri, 15 Dec 2023 20:41:58 -0500 Subject: [PATCH 36/52] fix: directly use child_process instead of CliCommandExecutor + use semver for CLI version checking --- package-lock.json | 31 ++++ packages/salesforcedx-utils/package.json | 3 +- .../src/cli/checkCliVersion.ts | 136 ++++++++---------- .../salesforcedx-vscode-core/src/index.ts | 6 +- 4 files changed, 98 insertions(+), 78 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d28846ba1..d3df2f9622 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36229,6 +36229,7 @@ "cross-spawn": "7.0.3", "request-light": "^0.7.0", "rxjs": "^5.4.1", + "semver": "^7.5.4", "tree-kill": "^1.1.0" }, "devDependencies": { @@ -36321,6 +36322,36 @@ "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==", "dev": true }, + "packages/salesforcedx-utils/node_modules/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==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "packages/salesforcedx-utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "packages/salesforcedx-utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "packages/salesforcedx-visualforce-language-server": { "name": "@salesforce/salesforcedx-visualforce-language-server", "version": "59.9.0", diff --git a/packages/salesforcedx-utils/package.json b/packages/salesforcedx-utils/package.json index 8d4161d142..79b181e862 100644 --- a/packages/salesforcedx-utils/package.json +++ b/packages/salesforcedx-utils/package.json @@ -19,7 +19,8 @@ "cross-spawn": "7.0.3", "request-light": "^0.7.0", "rxjs": "^5.4.1", - "tree-kill": "^1.1.0" + "tree-kill": "^1.1.0", + "semver": "^7.5.4" }, "devDependencies": { "@types/jest": "^29.5.5", diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 1fe6e5a020..f04d156247 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -5,10 +5,12 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { CliCommandExecutor } from './cliCommandExecutor'; -import { CommandOutput } from './commandOutput'; -import { SfCommandBuilder } from './sfCommandBuilder'; -import { SfdxCommandBuilder } from './sfdxCommandBuilder'; +// import { CliCommandExecutor } from './cliCommandExecutor'; +// import { CommandOutput } from './commandOutput'; +// import { SfCommandBuilder } from './sfCommandBuilder'; +// import { SfdxCommandBuilder } from './sfdxCommandBuilder'; +import { execSync } from 'child_process'; +import * as semver from 'semver'; export enum CheckCliEnum { validCli = 1, @@ -20,106 +22,92 @@ export enum CheckCliEnum { export class CheckCliVersion { - public async getSfdxCliVersion(): Promise { + public getSfdxCliVersion(): Promise { try { - // Execute the command "sfdx --version" in the Terminal - const sfdxExecution = new CliCommandExecutor( - new SfdxCommandBuilder().withArg('--version').withJson().build(), - {} - ).execute(); - // Save the result of the command - const sfdxCmdOutput = new CommandOutput(); - const sfdxVersion = await sfdxCmdOutput.getCmdResult(sfdxExecution); - return sfdxVersion; + const result = execSync('sfdx --version'); + return Promise.resolve(result.toString()); } catch { - return 'No SFDX CLI'; + return Promise.resolve('No SFDX CLI'); } } - public async getSfCliVersion(): Promise { try { - // Execute the command "sf --version" in the Terminal - const sfExecution = new CliCommandExecutor( - new SfCommandBuilder().withArg('--version').withJson().build(), - {} - ).execute(); - // Save the result of the command - const sfCmdOutput = new CommandOutput(); - const sfVersion = await sfCmdOutput.getCmdResult(sfExecution); - return sfVersion; + const result = execSync('sf --version'); + return Promise.resolve(result.toString()); } catch { - return 'No SF CLI'; + return Promise.resolve('No SF CLI'); } } - public async parseSfdxCliVersion(sfdxCliVersion: string): Promise { - // Both SFDX and SF v2 can match a valid SFDX version, so there are 2 patterns to search for - const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; - const sfdxMatch = sfdxPattern.exec(sfdxCliVersion); - const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; - const sfMatch = sfPattern.exec(sfdxCliVersion); - if (sfdxMatch) { - const sfdxVersion = sfdxMatch[1]; - const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - return sfdxVersionNumber; - } - else if (sfMatch) { - const sfdxVersion = sfMatch[1]; - const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - return sfdxVersionNumber; - } - return [-1]; - } + // public async parseSfdxCliVersion(sfdxCliVersion: string): Promise { + // // Both SFDX and SF v2 can match a valid SFDX version, so there are 2 patterns to search for + // const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; + // const sfdxMatch = sfdxPattern.exec(sfdxCliVersion); + // const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + // const sfMatch = sfPattern.exec(sfdxCliVersion); + // if (sfdxMatch) { + // const sfdxVersion = sfdxMatch[1]; + // const sfdxVersionNumber = sfdxVersion.split('.').map(Number); + // return sfdxVersionNumber; + // } + // else if (sfMatch) { + // const sfdxVersion = sfMatch[1]; + // const sfdxVersionNumber = sfdxVersion.split('.').map(Number); + // return sfdxVersionNumber; + // } + // return [-1]; + // } - public async parseSfCliVersion(sfCliVersion: string): Promise { - const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; - const sfMatch = sfPattern.exec(sfCliVersion); - if (sfMatch) { - const sfVersion = sfMatch[1]; - const sfVersionNumber = sfVersion.split('.').map(Number); - return sfVersionNumber; + // public async parseSfCliVersion(sfCliVersion: string): Promise { + // const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; + // const sfMatch = sfPattern.exec(sfCliVersion); + // if (sfMatch) { + // const sfVersion = sfMatch[1]; + // const sfVersionNumber = sfVersion.split('.').map(Number); + // return sfVersionNumber; + // } + // return [-1]; + // } + + public parseCliVersion(sfCliVersion: string): string { + const pattern = /sfdx-cli\/(\d+\.\d+\.\d+)|@salesforce\/cli\/(\d+\.\d+\.\d+)/; + const match = pattern.exec(sfCliVersion); + const y = match?.length; + console.log('y = ' + y); + for (let x = 0; x < y!; x++) { + console.log('match[' + x + '] = ' + match![x]); } - return [-1]; + // SFDX v7 reports results in match[1], SF v2 reports results in match[2] + return match ? (match[1] ? match[1] : match[2]) : '0.0.0'; } - public async validateCliInstallationAndVersion(sfdxCliVersionArray: number[], sfCliVersionArray: number[]): Promise { - // The last working version of SFDX is v7.193.2 - const minSFDXVersion = '7.193.2'; - const minSFDXVersionArray = minSFDXVersion.split('.').map(Number); + public validateCliInstallationAndVersion(sfdxCliVersionString: string, sfCliVersionString: string): CheckCliEnum { - // SF v1 does not map sf commands to sfdx commands and is not supported - const minSFVersion = '2.0.0'; - const minSFVersionArray = minSFVersion.split('.').map(Number); + console.log('sfdxCliVersionString = ' + sfdxCliVersionString); + console.log('sfCliVersionString = ' + sfCliVersionString); // Case 1: Neither SFDX CLI nor SF CLI is installed - if (sfdxCliVersionArray[0] === -1 && sfCliVersionArray[0] === -1) { + if (semver.satisfies(sfdxCliVersionString, '0.0.0') && semver.satisfies(sfCliVersionString, '0.0.0')) { return CheckCliEnum.cliNotInstalled; } // Case 2: Only SF CLI (v1) is installed (SF v1 cannot be used because it does not map sf to sfdx) - if (sfdxCliVersionArray[0] === -1 && sfCliVersionArray[0] === 1) { + if (semver.satisfies(sfdxCliVersionString, '0.0.0') && semver.satisfies(sfCliVersionString, '1.x')) { return CheckCliEnum.onlySFv1; } // Case 3: Both SFDX CLI (v7) and SF CLI (v2) are installed at the same time - if (sfCliVersionArray[0] >= minSFVersionArray[0] && !sfdxCliVersionArray.every((val, index) => val === sfCliVersionArray[index])) { + if (semver.satisfies(sfCliVersionString, '2.x') && !semver.satisfies(sfdxCliVersionString, sfCliVersionString)) { return CheckCliEnum.bothSFDXAndSFInstalled; } - // Case 4: SFDX CLI is installed - need to validate if the version is above the minimum supported version - if (sfCliVersionArray[0] < minSFVersionArray[0] && sfdxCliVersionArray[0] !== -1) { - if ( - sfdxCliVersionArray[0] >= minSFDXVersionArray[0] && - sfdxCliVersionArray[1] >= minSFDXVersionArray[1] && - sfdxCliVersionArray[2] >= minSFDXVersionArray[2] - ) { - return CheckCliEnum.validCli; - } else { - return CheckCliEnum.outdatedSFDXVersion; - } + // Case 4: Outdated SFDX CLI version is installed + const minSFDXVersion = '7.193.2'; + if (semver.satisfies(sfdxCliVersionString, ('<' + minSFDXVersion)) && semver.satisfies(sfCliVersionString, '<2.0.0')) { + return CheckCliEnum.outdatedSFDXVersion; } - // Case 5: SF v2 is installed + // Case 5: Valid SFDX v7 version or SF v2 is installed return CheckCliEnum.validCli; } } diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 7938d7a4b3..28ed906de2 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -723,10 +723,10 @@ export async function validateCliInstallationAndVersion(): Promise { const sfdxCliVersionString = await c.getSfdxCliVersion(); const sfCliVersionString = await c.getSfCliVersion(); - const sfdxCliVersionArray = await c.parseSfdxCliVersion(sfdxCliVersionString); - const sfCliVersionArray = await c.parseSfCliVersion(sfCliVersionString); + const sfdxCliVersionArray = c.parseCliVersion(sfdxCliVersionString); + const sfCliVersionArray = c.parseCliVersion(sfCliVersionString); - const cliInstallationResult = await c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); + const cliInstallationResult = c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); if (cliInstallationResult === CheckCliEnum.cliNotInstalled) { showErrorNotification('sfdx_cli_not_found', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); From de67697e086cb112b38b9d8b12bbd52cbf08c1f2 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 17 Dec 2023 07:41:15 -0500 Subject: [PATCH 37/52] fix: make checkCliVersion.test.ts unit tests run and pass with new structure --- .../test/jest/cli/checkCliVersion.test.ts | 102 ++++++++---------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts index bedc0729fa..a51267b163 100644 --- a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts @@ -4,7 +4,8 @@ * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { CheckCliEnum, CheckCliVersion } from '../../../src'; + +import { CheckCliEnum, CheckCliVersion } from '../../../src/cli/checkCliVersion'; describe('CheckCliVersion unit tests.', () => { @@ -15,12 +16,12 @@ describe('CheckCliVersion unit tests.', () => { const noSFDX_string = 'No SFDX CLI'; const noSF_string = 'No SF CLI'; - const sfV2_array = [2, 15, 9]; - const sfdxV7_valid_array = [7, 209, 6]; - const sfV1_array = [1, 87, 0]; - const sfdxV7_outdated_array = [7, 183, 1]; - const noSFDX_array = [-1]; - const noSF_array = [-1]; + const sfV2_parsed = '2.15.9'; + const sfdxV7_valid_parsed = '7.209.6'; + const sfV1_parsed = '1.87.0'; + const sfdxV7_outdated_parsed = '7.183.1'; + const noSFDX_parsed = '0.0.0'; + const noSF_parsed = '0.0.0'; it('Should create instance.', () => { const c = new CheckCliVersion(); @@ -28,54 +29,43 @@ describe('CheckCliVersion unit tests.', () => { }); /* - Test cases for the parseSfdxCliVersion() function + Test cases for the parseCliVersion() function */ - describe('Test cases for the parseSfdxCliVersion() function', () => { - it('Parse valid SFDX', async () => { + describe('Test cases for the parseCliVersion() function', () => { + it('Parse valid SFDX', () => { const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfdxV7_valid_string); - expect(result).toStrictEqual(sfdxV7_valid_array); + const result = c.parseCliVersion(sfdxV7_valid_string); + expect(result).toStrictEqual(sfdxV7_valid_parsed); }); - it('Parse outdated SFDX', async () => { + it('Parse outdated SFDX', () => { const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfdxV7_outdated_string); - expect(result).toStrictEqual(sfdxV7_outdated_array); + const result = c.parseCliVersion(sfdxV7_outdated_string); + expect(result).toStrictEqual(sfdxV7_outdated_parsed); }); - it('Parse valid SF v2', async () => { + it('Parse valid SF v2', () => { const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(sfV2_string); - expect(result).toStrictEqual(sfV2_array); + const result = c.parseCliVersion(sfV2_string); + expect(result).toStrictEqual(sfV2_parsed); }); - it('Parse SFDX not installed', async () => { - const c = new CheckCliVersion(); - const result = await c.parseSfdxCliVersion(noSFDX_string); - expect(result).toStrictEqual(noSFDX_array); - }); - }); - - /* - Test cases for the parseSfCliVersion() function - */ - describe('Test cases for the parseSfCliVersion() function', () => { - it('Parse SF v1', async () => { + it('Parse SFDX not installed', () => { const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(sfV1_string); - expect(result).toStrictEqual(sfV1_array); + const result = c.parseCliVersion(noSFDX_string); + expect(result).toStrictEqual(noSFDX_parsed); }); - it('Parse SF v2', async () => { + it('Parse SF v1', () => { const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(sfV2_string); - expect(result).toStrictEqual(sfV2_array); + const result = c.parseCliVersion(sfV1_string); + expect(result).toStrictEqual(sfV1_parsed); }); - it('Parse SF not installed', async () => { + it('Parse SF not installed', () => { const c = new CheckCliVersion(); - const result = await c.parseSfCliVersion(noSF_string); - expect(result).toStrictEqual(noSF_array); + const result = c.parseCliVersion(noSF_string); + expect(result).toStrictEqual(noSF_parsed); }); }); @@ -83,57 +73,57 @@ describe('CheckCliVersion unit tests.', () => { Test cases for the validateCliInstallationAndVersion() function */ describe('Test cases for the validateCliInstallationAndVersion() function', () => { - it('Case 1: No Salesforce CLI installed - should fail', async () => { + it('Case 1: No Salesforce CLI installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(noSFDX_array, noSF_array); + const result = c.validateCliInstallationAndVersion(noSFDX_parsed, noSF_parsed); expect(result).toStrictEqual(CheckCliEnum.cliNotInstalled); }); - it('Case 2: Only SF v1 installed - should fail', async () => { + it('Case 2: Only SF v1 installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(noSFDX_array, sfV1_array); + const result = c.validateCliInstallationAndVersion(noSFDX_parsed, sfV1_parsed); expect(result).toStrictEqual(CheckCliEnum.onlySFv1); }); - it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', async () => { + it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV2_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, sfV2_parsed); expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); }); - it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', async () => { + it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV2_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, sfV2_parsed); expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); }); - it('Case 5: Only SFDX v7 (outdated) installed - should fail', async () => { + it('Case 5: Only SFDX v7 (outdated) installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, noSF_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, noSF_parsed); expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); }); - it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', async () => { + it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, noSF_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, noSF_parsed); expect(result).toStrictEqual(CheckCliEnum.validCli); }); - it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', async () => { + it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_outdated_array, sfV1_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, sfV1_parsed); expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); }); - it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', async () => { + it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfdxV7_valid_array, sfV1_array); + const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, sfV1_parsed); expect(result).toStrictEqual(CheckCliEnum.validCli); }); - it('Case 9: Only SF v2 installed - should activate Core extension', async () => { + it('Case 9: Only SF v2 installed - should activate Core extension', () => { const c = new CheckCliVersion(); - const result = await c.validateCliInstallationAndVersion(sfV2_array, sfV2_array); + const result = c.validateCliInstallationAndVersion(sfV2_parsed, sfV2_parsed); expect(result).toStrictEqual(CheckCliEnum.validCli); }); }); From f512a879f6abb388ec01a00e06678ef02525a3c9 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 17 Dec 2023 07:59:37 -0500 Subject: [PATCH 38/52] chore: clean up checkCliVersion.ts --- .../src/cli/checkCliVersion.ts | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index f04d156247..54a786585c 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -5,10 +5,6 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -// import { CliCommandExecutor } from './cliCommandExecutor'; -// import { CommandOutput } from './commandOutput'; -// import { SfCommandBuilder } from './sfCommandBuilder'; -// import { SfdxCommandBuilder } from './sfdxCommandBuilder'; import { execSync } from 'child_process'; import * as semver from 'semver'; @@ -39,53 +35,15 @@ export class CheckCliVersion { } } - // public async parseSfdxCliVersion(sfdxCliVersion: string): Promise { - // // Both SFDX and SF v2 can match a valid SFDX version, so there are 2 patterns to search for - // const sfdxPattern = /sfdx-cli\/(\d+\.\d+\.\d+)/; - // const sfdxMatch = sfdxPattern.exec(sfdxCliVersion); - // const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; - // const sfMatch = sfPattern.exec(sfdxCliVersion); - // if (sfdxMatch) { - // const sfdxVersion = sfdxMatch[1]; - // const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - // return sfdxVersionNumber; - // } - // else if (sfMatch) { - // const sfdxVersion = sfMatch[1]; - // const sfdxVersionNumber = sfdxVersion.split('.').map(Number); - // return sfdxVersionNumber; - // } - // return [-1]; - // } - - // public async parseSfCliVersion(sfCliVersion: string): Promise { - // const sfPattern = /@salesforce\/cli\/(\d+\.\d+\.\d+)/; - // const sfMatch = sfPattern.exec(sfCliVersion); - // if (sfMatch) { - // const sfVersion = sfMatch[1]; - // const sfVersionNumber = sfVersion.split('.').map(Number); - // return sfVersionNumber; - // } - // return [-1]; - // } - public parseCliVersion(sfCliVersion: string): string { const pattern = /sfdx-cli\/(\d+\.\d+\.\d+)|@salesforce\/cli\/(\d+\.\d+\.\d+)/; const match = pattern.exec(sfCliVersion); - const y = match?.length; - console.log('y = ' + y); - for (let x = 0; x < y!; x++) { - console.log('match[' + x + '] = ' + match![x]); - } // SFDX v7 reports results in match[1], SF v2 reports results in match[2] return match ? (match[1] ? match[1] : match[2]) : '0.0.0'; } public validateCliInstallationAndVersion(sfdxCliVersionString: string, sfCliVersionString: string): CheckCliEnum { - console.log('sfdxCliVersionString = ' + sfdxCliVersionString); - console.log('sfCliVersionString = ' + sfCliVersionString); - // Case 1: Neither SFDX CLI nor SF CLI is installed if (semver.satisfies(sfdxCliVersionString, '0.0.0') && semver.satisfies(sfCliVersionString, '0.0.0')) { return CheckCliEnum.cliNotInstalled; From b04e05c3e2969358def0997e5bc5bbfb8122e4c3 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Sun, 17 Dec 2023 08:35:02 -0500 Subject: [PATCH 39/52] refactor: replace if/else block with switch statement --- .../src/cli/checkCliVersion.ts | 2 +- .../salesforcedx-vscode-core/src/index.ts | 39 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 54a786585c..8184171c49 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -26,7 +26,7 @@ export class CheckCliVersion { return Promise.resolve('No SFDX CLI'); } } - public async getSfCliVersion(): Promise { + public getSfCliVersion(): Promise { try { const result = execSync('sf --version'); return Promise.resolve(result.toString()); diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 28ed906de2..a6d030d65d 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -723,23 +723,28 @@ export async function validateCliInstallationAndVersion(): Promise { const sfdxCliVersionString = await c.getSfdxCliVersion(); const sfCliVersionString = await c.getSfCliVersion(); - const sfdxCliVersionArray = c.parseCliVersion(sfdxCliVersionString); - const sfCliVersionArray = c.parseCliVersion(sfCliVersionString); - - const cliInstallationResult = c.validateCliInstallationAndVersion(sfdxCliVersionArray, sfCliVersionArray); - - if (cliInstallationResult === CheckCliEnum.cliNotInstalled) { - showErrorNotification('sfdx_cli_not_found', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); - throw Error('No Salesforce CLI installed'); - } else if (cliInstallationResult === CheckCliEnum.onlySFv1) { - showErrorNotification('sf_v1_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); - throw Error('Only SF v1 installed'); - } else if (cliInstallationResult === CheckCliEnum.outdatedSFDXVersion) { - showErrorNotification('sfdx_cli_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); - throw Error('Outdated SFDX CLI version that is no longer supported'); - } else if (cliInstallationResult === CheckCliEnum.bothSFDXAndSFInstalled) { - showErrorNotification('both_sfdx_and_sf', []); - throw Error('Both SFDX v7 and SF v2 are installed'); + const sfdxCliVersionParsed = c.parseCliVersion(sfdxCliVersionString); + const sfCliVersionParsed = c.parseCliVersion(sfCliVersionString); + + const cliInstallationResult = c.validateCliInstallationAndVersion(sfdxCliVersionParsed, sfCliVersionParsed); + + switch(cliInstallationResult) { + case CheckCliEnum.cliNotInstalled: { + showErrorNotification('sfdx_cli_not_found', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); + throw Error('No Salesforce CLI installed'); + } + case CheckCliEnum.onlySFv1: { + showErrorNotification('sf_v1_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); + throw Error('Only SF v1 installed'); + } + case CheckCliEnum.outdatedSFDXVersion: { + showErrorNotification('sfdx_cli_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); + throw Error('Outdated SFDX CLI version that is no longer supported'); + } + case CheckCliEnum.bothSFDXAndSFInstalled: { + showErrorNotification('both_sfdx_and_sf', []); + throw Error('Both SFDX v7 and SF v2 are installed'); + } } } From d73533c57753454f3cad7ad01a3e6f4f0c39ddee Mon Sep 17 00:00:00 2001 From: Daphne Yang <139700604+daphne-sfdc@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:41:55 -0500 Subject: [PATCH 40/52] Apply suggestions from Pete's code review Co-authored-by: peternhale --- .../src/cli/checkCliVersion.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 8184171c49..2ac4f972aa 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -18,28 +18,28 @@ export enum CheckCliEnum { export class CheckCliVersion { - public getSfdxCliVersion(): Promise { + public getSfdxCliVersion(): string { try { const result = execSync('sfdx --version'); - return Promise.resolve(result.toString()); + return result.toString(); } catch { - return Promise.resolve('No SFDX CLI'); + return 'No SFDX CLI'; } } - public getSfCliVersion(): Promise { + public getSfCliVersion(): string { try { const result = execSync('sf --version'); - return Promise.resolve(result.toString()); + return result.toString(); } catch { - return Promise.resolve('No SF CLI'); + return 'No SF CLI'; } } public parseCliVersion(sfCliVersion: string): string { - const pattern = /sfdx-cli\/(\d+\.\d+\.\d+)|@salesforce\/cli\/(\d+\.\d+\.\d+)/; + const pattern = (?:sfdx-cli\/|@salesforce\/cli\/)(\d+\.\d+\.\d+); const match = pattern.exec(sfCliVersion); // SFDX v7 reports results in match[1], SF v2 reports results in match[2] - return match ? (match[1] ? match[1] : match[2]) : '0.0.0'; + return match ? match[1] : '0.0.0'; } public validateCliInstallationAndVersion(sfdxCliVersionString: string, sfCliVersionString: string): CheckCliEnum { @@ -61,7 +61,7 @@ export class CheckCliVersion { // Case 4: Outdated SFDX CLI version is installed const minSFDXVersion = '7.193.2'; - if (semver.satisfies(sfdxCliVersionString, ('<' + minSFDXVersion)) && semver.satisfies(sfCliVersionString, '<2.0.0')) { + if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`) && semver.satisfies(sfCliVersionString, '<2.0.0')) { return CheckCliEnum.outdatedSFDXVersion; } From dc5da0dec8dba81a2bec31122e688974df7110fa Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Mon, 18 Dec 2023 11:52:50 -0500 Subject: [PATCH 41/52] chore: fix syntax errors to allow code to compile --- packages/salesforcedx-utils/src/cli/checkCliVersion.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts index 2ac4f972aa..c898e6658c 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/checkCliVersion.ts @@ -36,7 +36,7 @@ export class CheckCliVersion { } public parseCliVersion(sfCliVersion: string): string { - const pattern = (?:sfdx-cli\/|@salesforce\/cli\/)(\d+\.\d+\.\d+); + const pattern = /(?:sfdx-cli\/|@salesforce\/cli\/)(\d+\.\d+\.\d+)/; const match = pattern.exec(sfCliVersion); // SFDX v7 reports results in match[1], SF v2 reports results in match[2] return match ? match[1] : '0.0.0'; @@ -61,7 +61,7 @@ export class CheckCliVersion { // Case 4: Outdated SFDX CLI version is installed const minSFDXVersion = '7.193.2'; - if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`) && semver.satisfies(sfCliVersionString, '<2.0.0')) { + if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`)) && semver.satisfies(sfCliVersionString, '<2.0.0')) { return CheckCliEnum.outdatedSFDXVersion; } From f1487b135087d904e8359dc13ba5bf2486f492c4 Mon Sep 17 00:00:00 2001 From: Daphne Yang <139700604+daphne-sfdc@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:57:37 -0500 Subject: [PATCH 42/52] chore: sfdx_cli_not_found -> salesforce_cli_not_found in cliConfiguration.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cristina Cañizales <113132642+CristiCanizales@users.noreply.github.com> --- packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts index a9a2b7ba1a..91242c3392 100644 --- a/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts +++ b/packages/salesforcedx-vscode-core/src/util/cliConfiguration.ts @@ -33,7 +33,7 @@ export function isCLIInstalled(): boolean { export function showCLINotInstalledMessage() { const showMessage = nls.localize( - 'sfdx_cli_not_found', + 'salesforce_cli_not_found', SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK ); From 2e8d6fb0b1ccb29f620b97263c8b6ca86bb01489 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Mon, 18 Dec 2023 12:27:02 -0500 Subject: [PATCH 43/52] revert: revert all references to SfCommandBuilder because it is no longer used --- packages/salesforcedx-utils/src/cli/index.ts | 1 - .../salesforcedx-utils/src/cli/sfCommandBuilder.ts | 14 -------------- .../salesforcedx-utils/src/constants/constants.ts | 1 - 3 files changed, 16 deletions(-) delete mode 100644 packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts diff --git a/packages/salesforcedx-utils/src/cli/index.ts b/packages/salesforcedx-utils/src/cli/index.ts index eb7e49489c..293eb64101 100644 --- a/packages/salesforcedx-utils/src/cli/index.ts +++ b/packages/salesforcedx-utils/src/cli/index.ts @@ -12,5 +12,4 @@ export { ForceConfigGet } from './forceConfigGet'; export { GlobalCliEnvironment } from './globalCliEnvironment'; export { OrgDisplay } from './orgDisplay'; export { SfdxCommandBuilder } from './sfdxCommandBuilder'; -export { SfCommandBuilder } from './sfCommandBuilder'; export { CheckCliEnum, CheckCliVersion } from './checkCliVersion'; diff --git a/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts b/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts deleted file mode 100644 index caadbdcba9..0000000000 --- a/packages/salesforcedx-utils/src/cli/sfCommandBuilder.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023, salesforce.com, inc. - * All rights reserved. - * Licensed under the BSD 3-Clause license. - * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -import { SF_COMMAND } from '../constants'; -import { CommandBuilder } from './commandBuilder'; - -export class SfCommandBuilder extends CommandBuilder { - public constructor() { - super(SF_COMMAND); - } -} diff --git a/packages/salesforcedx-utils/src/constants/constants.ts b/packages/salesforcedx-utils/src/constants/constants.ts index 40e8b16397..34434d9817 100644 --- a/packages/salesforcedx-utils/src/constants/constants.ts +++ b/packages/salesforcedx-utils/src/constants/constants.ts @@ -17,7 +17,6 @@ export const DEFAULT_LOCALE = 'en'; export const LOCALE_JA = 'ja'; export const MISSING_LABEL_MSG = '!!! MISSING LABEL !!!'; export const SFDX_COMMAND = 'sfdx'; -export const SF_COMMAND = 'sf'; export const SFDX_CONFIG_ISV_DEBUGGER_SID = 'isvDebuggerSid'; export const SFDX_CONFIG_ISV_DEBUGGER_URL = 'isvDebuggerUrl'; export const TELEMETRY_HEADER = 'salesforce-vscode-extensions'; From 0d5c1e139ab525d99da8867d0428e5e7e751618c Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 19 Dec 2023 16:02:19 -0500 Subject: [PATCH 44/52] fix: apply Pete's suggestions from code review --- ...checkCliVersion.ts => cliVersionStatus.ts} | 16 +++--- packages/salesforcedx-utils/src/cli/index.ts | 2 +- ...rsion.test.ts => cliVersionStatus.test.ts} | 57 +++++++++---------- .../salesforcedx-vscode-core/src/index.ts | 18 +++--- 4 files changed, 44 insertions(+), 49 deletions(-) rename packages/salesforcedx-utils/src/cli/{checkCliVersion.ts => cliVersionStatus.ts} (86%) rename packages/salesforcedx-utils/test/jest/cli/{checkCliVersion.test.ts => cliVersionStatus.test.ts} (71%) diff --git a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts similarity index 86% rename from packages/salesforcedx-utils/src/cli/checkCliVersion.ts rename to packages/salesforcedx-utils/src/cli/cliVersionStatus.ts index c898e6658c..17a14977ba 100644 --- a/packages/salesforcedx-utils/src/cli/checkCliVersion.ts +++ b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts @@ -8,7 +8,7 @@ import { execSync } from 'child_process'; import * as semver from 'semver'; -export enum CheckCliEnum { +export enum CliStatusEnum { validCli = 1, outdatedSFDXVersion = 2, onlySFv1 = 3, @@ -16,7 +16,7 @@ export enum CheckCliEnum { bothSFDXAndSFInstalled = 5 } -export class CheckCliVersion { +export class CliVersionStatus { public getSfdxCliVersion(): string { try { @@ -42,30 +42,30 @@ export class CheckCliVersion { return match ? match[1] : '0.0.0'; } - public validateCliInstallationAndVersion(sfdxCliVersionString: string, sfCliVersionString: string): CheckCliEnum { + public validateCliInstallationAndVersion(sfdxCliVersionString: string, sfCliVersionString: string): CliStatusEnum { // Case 1: Neither SFDX CLI nor SF CLI is installed if (semver.satisfies(sfdxCliVersionString, '0.0.0') && semver.satisfies(sfCliVersionString, '0.0.0')) { - return CheckCliEnum.cliNotInstalled; + return CliStatusEnum.cliNotInstalled; } // Case 2: Only SF CLI (v1) is installed (SF v1 cannot be used because it does not map sf to sfdx) if (semver.satisfies(sfdxCliVersionString, '0.0.0') && semver.satisfies(sfCliVersionString, '1.x')) { - return CheckCliEnum.onlySFv1; + return CliStatusEnum.onlySFv1; } // Case 3: Both SFDX CLI (v7) and SF CLI (v2) are installed at the same time if (semver.satisfies(sfCliVersionString, '2.x') && !semver.satisfies(sfdxCliVersionString, sfCliVersionString)) { - return CheckCliEnum.bothSFDXAndSFInstalled; + return CliStatusEnum.bothSFDXAndSFInstalled; } // Case 4: Outdated SFDX CLI version is installed const minSFDXVersion = '7.193.2'; if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`)) && semver.satisfies(sfCliVersionString, '<2.0.0')) { - return CheckCliEnum.outdatedSFDXVersion; + return CliStatusEnum.outdatedSFDXVersion; } // Case 5: Valid SFDX v7 version or SF v2 is installed - return CheckCliEnum.validCli; + return CliStatusEnum.validCli; } } diff --git a/packages/salesforcedx-utils/src/cli/index.ts b/packages/salesforcedx-utils/src/cli/index.ts index 293eb64101..db9535da53 100644 --- a/packages/salesforcedx-utils/src/cli/index.ts +++ b/packages/salesforcedx-utils/src/cli/index.ts @@ -12,4 +12,4 @@ export { ForceConfigGet } from './forceConfigGet'; export { GlobalCliEnvironment } from './globalCliEnvironment'; export { OrgDisplay } from './orgDisplay'; export { SfdxCommandBuilder } from './sfdxCommandBuilder'; -export { CheckCliEnum, CheckCliVersion } from './checkCliVersion'; +export { CliStatusEnum, CliVersionStatus } from './cliVersionStatus'; diff --git a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts similarity index 71% rename from packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts rename to packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts index a51267b163..8101a7e22b 100644 --- a/packages/salesforcedx-utils/test/jest/cli/checkCliVersion.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts @@ -5,9 +5,9 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { CheckCliEnum, CheckCliVersion } from '../../../src/cli/checkCliVersion'; +import { CliStatusEnum, CliVersionStatus } from '../../../src/cli/cliVersionStatus'; -describe('CheckCliVersion unit tests.', () => { +describe('CliVersionStatus unit tests.', () => { const sfV2_string = '@salesforce/cli/2.15.9 darwin-arm64 node-v18.17.1'; const sfdxV7_valid_string = 'sfdx-cli/7.209.6 win32-x64 node-v18.15.0'; @@ -23,47 +23,42 @@ describe('CheckCliVersion unit tests.', () => { const noSFDX_parsed = '0.0.0'; const noSF_parsed = '0.0.0'; - it('Should create instance.', () => { - const c = new CheckCliVersion(); - expect(c).toBeInstanceOf(CheckCliVersion); - }); - /* Test cases for the parseCliVersion() function */ describe('Test cases for the parseCliVersion() function', () => { it('Parse valid SFDX', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(sfdxV7_valid_string); expect(result).toStrictEqual(sfdxV7_valid_parsed); }); it('Parse outdated SFDX', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(sfdxV7_outdated_string); expect(result).toStrictEqual(sfdxV7_outdated_parsed); }); it('Parse valid SF v2', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(sfV2_string); expect(result).toStrictEqual(sfV2_parsed); }); it('Parse SFDX not installed', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(noSFDX_string); expect(result).toStrictEqual(noSFDX_parsed); }); it('Parse SF v1', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(sfV1_string); expect(result).toStrictEqual(sfV1_parsed); }); it('Parse SF not installed', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.parseCliVersion(noSF_string); expect(result).toStrictEqual(noSF_parsed); }); @@ -74,57 +69,57 @@ describe('CheckCliVersion unit tests.', () => { */ describe('Test cases for the validateCliInstallationAndVersion() function', () => { it('Case 1: No Salesforce CLI installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(noSFDX_parsed, noSF_parsed); - expect(result).toStrictEqual(CheckCliEnum.cliNotInstalled); + expect(result).toStrictEqual(CliStatusEnum.cliNotInstalled); }); it('Case 2: Only SF v1 installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(noSFDX_parsed, sfV1_parsed); - expect(result).toStrictEqual(CheckCliEnum.onlySFv1); + expect(result).toStrictEqual(CliStatusEnum.onlySFv1); }); it('Case 3: Both SFDX v7 (outdated) and SF v2 installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, sfV2_parsed); - expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); + expect(result).toStrictEqual(CliStatusEnum.bothSFDXAndSFInstalled); }); it('Case 4: Both SFDX v7 (valid) and SF v2 installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, sfV2_parsed); - expect(result).toStrictEqual(CheckCliEnum.bothSFDXAndSFInstalled); + expect(result).toStrictEqual(CliStatusEnum.bothSFDXAndSFInstalled); }); it('Case 5: Only SFDX v7 (outdated) installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, noSF_parsed); - expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); + expect(result).toStrictEqual(CliStatusEnum.outdatedSFDXVersion); }); it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, noSF_parsed); - expect(result).toStrictEqual(CheckCliEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.validCli); }); it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_outdated_parsed, sfV1_parsed); - expect(result).toStrictEqual(CheckCliEnum.outdatedSFDXVersion); + expect(result).toStrictEqual(CliStatusEnum.outdatedSFDXVersion); }); it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, sfV1_parsed); - expect(result).toStrictEqual(CheckCliEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.validCli); }); it('Case 9: Only SF v2 installed - should activate Core extension', () => { - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfV2_parsed, sfV2_parsed); - expect(result).toStrictEqual(CheckCliEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.validCli); }); }); }); \ No newline at end of file diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index a6d030d65d..a5b2d8bc80 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -4,7 +4,7 @@ * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { CheckCliEnum, CheckCliVersion, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; +import { CliStatusEnum, CliVersionStatus, ensureCurrentWorkingDirIsProjectPath } from '@salesforce/salesforcedx-utils'; import { ChannelService, getRootWorkspacePath, @@ -715,13 +715,13 @@ export function deactivate(): Promise { return turnOffLogging(); } -export async function validateCliInstallationAndVersion(): Promise { +export function validateCliInstallationAndVersion(): void { // Check that the CLI is installed and that it is a supported version // If there is no CLI or it is an unsupported version then the Core extension will not activate - const c = new CheckCliVersion(); + const c = new CliVersionStatus(); - const sfdxCliVersionString = await c.getSfdxCliVersion(); - const sfCliVersionString = await c.getSfCliVersion(); + const sfdxCliVersionString = c.getSfdxCliVersion(); + const sfCliVersionString = c.getSfCliVersion(); const sfdxCliVersionParsed = c.parseCliVersion(sfdxCliVersionString); const sfCliVersionParsed = c.parseCliVersion(sfCliVersionString); @@ -729,19 +729,19 @@ export async function validateCliInstallationAndVersion(): Promise { const cliInstallationResult = c.validateCliInstallationAndVersion(sfdxCliVersionParsed, sfCliVersionParsed); switch(cliInstallationResult) { - case CheckCliEnum.cliNotInstalled: { + case CliStatusEnum.cliNotInstalled: { showErrorNotification('sfdx_cli_not_found', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('No Salesforce CLI installed'); } - case CheckCliEnum.onlySFv1: { + case CliStatusEnum.onlySFv1: { showErrorNotification('sf_v1_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('Only SF v1 installed'); } - case CheckCliEnum.outdatedSFDXVersion: { + case CliStatusEnum.outdatedSFDXVersion: { showErrorNotification('sfdx_cli_not_supported', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); throw Error('Outdated SFDX CLI version that is no longer supported'); } - case CheckCliEnum.bothSFDXAndSFInstalled: { + case CliStatusEnum.bothSFDXAndSFInstalled: { showErrorNotification('both_sfdx_and_sf', []); throw Error('Both SFDX v7 and SF v2 are installed'); } From 3188d013c25a877eb854f2b99363351c6cc4440f Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 19 Dec 2023 18:18:46 -0500 Subject: [PATCH 45/52] chore: remove comment --- packages/salesforcedx-utils/src/cli/cliVersionStatus.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts index 17a14977ba..39045a6d6a 100644 --- a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts +++ b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts @@ -38,7 +38,6 @@ export class CliVersionStatus { public parseCliVersion(sfCliVersion: string): string { const pattern = /(?:sfdx-cli\/|@salesforce\/cli\/)(\d+\.\d+\.\d+)/; const match = pattern.exec(sfCliVersion); - // SFDX v7 reports results in match[1], SF v2 reports results in match[2] return match ? match[1] : '0.0.0'; } From 265679a56331ac006144676c0d54ceb413d9092c Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 20 Dec 2023 21:01:25 -0500 Subject: [PATCH 46/52] feat: mocking jest unit tests for getSfdxCliVersion() and getSfCliVersion() --- .../test/jest/cli/cliVersionStatus.test.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts index 8101a7e22b..07295b111b 100644 --- a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts @@ -5,6 +5,7 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +import * as child_process from 'child_process'; import { CliStatusEnum, CliVersionStatus } from '../../../src/cli/cliVersionStatus'; describe('CliVersionStatus unit tests.', () => { @@ -23,6 +24,62 @@ describe('CliVersionStatus unit tests.', () => { const noSFDX_parsed = '0.0.0'; const noSF_parsed = '0.0.0'; + describe('Test cases that produce a result for getSfdxCliVersion() and getSfCliVersion()', () => { + + const fakeExecution = Buffer.from('fake result'); + const fakeResult = 'fake result'; + + let executeSpy: jest.SpyInstance; + beforeEach(() => { + executeSpy = jest + .spyOn(child_process, 'execSync') + .mockReturnValue(fakeExecution); + }); + + it('getSfdxCliVersion() - can get a result', async () => { + const cliVersionStatus = new CliVersionStatus(); + const result = cliVersionStatus.getSfdxCliVersion(); + expect(result).toEqual(fakeResult); + expect(executeSpy).toHaveBeenCalled(); + }); + + it('getSfCliVersion() - can get a result', async () => { + const cliVersionStatus = new CliVersionStatus(); + const result = cliVersionStatus.getSfCliVersion(); + expect(result).toEqual(fakeResult); + expect(executeSpy).toHaveBeenCalled(); + }); + }); + + describe('Test cases that throw an error for getSfdxCliVersion() and getSfCliVersion()', () => { + + const sfdxNotFound = 'No SFDX CLI'; + const sfNotFound = 'No SF CLI'; + + let executeSpy: jest.SpyInstance; + beforeEach(() => { + executeSpy = jest + .spyOn(child_process, 'execSync') + .mockImplementationOnce(() => { + throw new Error('simulate exception in execSync()'); + }); + }); + + it('getSfdxCliVersion() - throws error', async () => { + const cliVersionStatus = new CliVersionStatus(); + const result = cliVersionStatus.getSfdxCliVersion(); + expect(result).toEqual(sfdxNotFound); + expect(executeSpy).toHaveBeenCalled(); + }); + + it('getSfCliVersion() - can get a result', async () => { + const cliVersionStatus = new CliVersionStatus(); + const result = cliVersionStatus.getSfCliVersion(); + expect(result).toEqual(sfNotFound); + expect(executeSpy).toHaveBeenCalled(); + }); + }); + /* Test cases for the parseCliVersion() function */ From d04d9c701bc0c710619edd6ddd3a3d743766fab5 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 20 Dec 2023 21:29:31 -0500 Subject: [PATCH 47/52] feat: add warning message that SFDX v7 will soon be deprecated --- .../src/cli/cliVersionStatus.ts | 20 ++++++++++++------- .../test/jest/cli/cliVersionStatus.test.ts | 12 ++++++++--- .../salesforcedx-vscode-core/src/index.ts | 11 ++++++++++ .../src/messages/i18n.ja.ts | 4 +++- .../src/messages/i18n.ts | 4 +++- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts index 39045a6d6a..0d1e1fce6e 100644 --- a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts +++ b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts @@ -9,11 +9,12 @@ import { execSync } from 'child_process'; import * as semver from 'semver'; export enum CliStatusEnum { - validCli = 1, + SFv2 = 1, outdatedSFDXVersion = 2, onlySFv1 = 3, cliNotInstalled = 4, - bothSFDXAndSFInstalled = 5 + bothSFDXAndSFInstalled = 5, + SFDXv7Valid = 6 } export class CliVersionStatus { @@ -58,13 +59,18 @@ export class CliVersionStatus { return CliStatusEnum.bothSFDXAndSFInstalled; } - // Case 4: Outdated SFDX CLI version is installed const minSFDXVersion = '7.193.2'; - if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`)) && semver.satisfies(sfCliVersionString, '<2.0.0')) { - return CliStatusEnum.outdatedSFDXVersion; + if (semver.satisfies(sfCliVersionString, '<2.0.0')) { + if (semver.satisfies(sfdxCliVersionString, (`<${minSFDXVersion}`))) { + // Case 4: Outdated SFDX CLI version is installed + return CliStatusEnum.outdatedSFDXVersion; + } else { + // Case 5: Valid SFDX v7 version is installed + return CliStatusEnum.SFDXv7Valid; + } } - // Case 5: Valid SFDX v7 version or SF v2 is installed - return CliStatusEnum.validCli; + // Case 6: SF v2 is installed + return CliStatusEnum.SFv2; } } diff --git a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts index 07295b111b..8e11bfd664 100644 --- a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts @@ -24,6 +24,9 @@ describe('CliVersionStatus unit tests.', () => { const noSFDX_parsed = '0.0.0'; const noSF_parsed = '0.0.0'; + /* + Test cases that produce a result for getSfdxCliVersion() and getSfCliVersion() + */ describe('Test cases that produce a result for getSfdxCliVersion() and getSfCliVersion()', () => { const fakeExecution = Buffer.from('fake result'); @@ -51,6 +54,9 @@ describe('CliVersionStatus unit tests.', () => { }); }); + /* + Test cases that throw an error for getSfdxCliVersion() and getSfCliVersion() + */ describe('Test cases that throw an error for getSfdxCliVersion() and getSfCliVersion()', () => { const sfdxNotFound = 'No SFDX CLI'; @@ -158,7 +164,7 @@ describe('CliVersionStatus unit tests.', () => { it('Case 6: Only SFDX v7 (valid) installed - should activate Core extension', () => { const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, noSF_parsed); - expect(result).toStrictEqual(CliStatusEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.SFDXv7Valid); }); it('Case 7: SFDX v7 (outdated) and SF v1 installed - should fail', () => { @@ -170,13 +176,13 @@ describe('CliVersionStatus unit tests.', () => { it('Case 8: SFDX v7 (valid) and SF v1 installed - should activate Core extension', () => { const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfdxV7_valid_parsed, sfV1_parsed); - expect(result).toStrictEqual(CliStatusEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.SFDXv7Valid); }); it('Case 9: Only SF v2 installed - should activate Core extension', () => { const c = new CliVersionStatus(); const result = c.validateCliInstallationAndVersion(sfV2_parsed, sfV2_parsed); - expect(result).toStrictEqual(CliStatusEnum.validCli); + expect(result).toStrictEqual(CliStatusEnum.SFv2); }); }); }); \ No newline at end of file diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index aa44578c8b..439cd3cb58 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -745,6 +745,9 @@ export function validateCliInstallationAndVersion(): void { showErrorNotification('both_sfdx_and_sf', []); throw Error('Both SFDX v7 and SF v2 are installed'); } + case CliStatusEnum.SFDXv7Valid: { + showWarningNotification('sfdx_v7_deprecation', [SF_CLI_DOWNLOAD_LINK, SF_CLI_DOWNLOAD_LINK]); + } } } @@ -755,3 +758,11 @@ export function showErrorNotification(type: string, args: any[]) { ); vscode.window.showErrorMessage(showMessage); } + +export function showWarningNotification(type: string, args: any[]) { + const showMessage = nls.localize( + type, + ...args + ); + vscode.window.showWarningMessage(showMessage); +} diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index b43e916672..99a49d7121 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -251,11 +251,13 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI がインストールされていません。[%s](%s) からインストールしてください。', sfdx_cli_not_supported: - 'Your installed Salesforce CLI version is no longer supported. Uninstall CLI and install the latest version from [%s](%s).', + 'Your installed Salesforce CLI version is no longer supported. Uninstall Salesforce CLI and install the latest version from [%s](%s).', sf_v1_not_supported: 'Your installed Salesforce CLI version is incompatible with all versions of our extensions. Uninstall Salesforce CLI and install the latest version from [%s](%s).', both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', + sfdx_v7_deprecation: + 'Our team will remove support for SFDX(v7) of Salesforce CLI in a few months. If you are able, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index 7cb31b04b0..0503e5eff6 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -293,11 +293,13 @@ export const messages = { sfdx_cli_not_found: 'Salesforce CLI is not installed. Install it from [%s](%s)', sfdx_cli_not_supported: - 'Your installed Salesforce CLI version is no longer supported. Uninstall CLI and install the latest version from [%s](%s).', + 'Your installed Salesforce CLI version is no longer supported. Uninstall Salesforce CLI and install the latest version from [%s](%s).', sf_v1_not_supported: 'Your installed Salesforce CLI version is incompatible with all versions of our extensions. Uninstall Salesforce CLI and install the latest version from [%s](%s).', both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', + sfdx_v7_deprecation: + 'Our team will remove support for SFDX(v7) of Salesforce CLI in a few months. If you are able, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From e02927dfdecbe40cd2ca4140174b263d4da23a80 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Wed, 20 Dec 2023 22:37:10 -0500 Subject: [PATCH 48/52] chore: allow CLI version validation to happen on Windows --- packages/salesforcedx-vscode-core/src/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 439cd3cb58..3ab7981703 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -544,11 +544,7 @@ export async function activate(extensionContext: vscode.ExtensionContext) { // thus avoiding the potential errors surfaced when the libs call // process.cwd(). ensureCurrentWorkingDirIsProjectPath(rootWorkspacePath); - const platform = process.platform.toLowerCase(); - const isWindows = platform === 'win32'; - if (!isWindows) { - await validateCliInstallationAndVersion(); - } + validateCliInstallationAndVersion(); setNodeExtraCaCerts(); await telemetryService.initializeService(extensionContext); showTelemetryMessage(extensionContext); From b2ed360d904b8cfe5878d7739c9a655ad08eddf4 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 26 Dec 2023 12:05:56 -0500 Subject: [PATCH 49/52] refactor: consolidate getSfdxCliVersion() and getSfCliVersion() into one function --- .../src/cli/cliVersionStatus.ts | 23 ++++++++----------- .../test/jest/cli/cliVersionStatus.test.ts | 19 ++++++++------- .../salesforcedx-vscode-core/src/index.ts | 4 ++-- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts index 0d1e1fce6e..5cf80bf929 100644 --- a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts +++ b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts @@ -19,26 +19,23 @@ export enum CliStatusEnum { export class CliVersionStatus { - public getSfdxCliVersion(): string { + public getCliVersion(isSfdx: boolean): string { try { - const result = execSync('sfdx --version'); - return result.toString(); - } catch { - return 'No SFDX CLI'; - } - } - public getSfCliVersion(): string { - try { - const result = execSync('sf --version'); + let result; + if (isSfdx) { + result = execSync('sfdx --version'); + } else { + result = execSync('sf --version'); + } return result.toString(); } catch { - return 'No SF CLI'; + return 'No CLI'; } } - public parseCliVersion(sfCliVersion: string): string { + public parseCliVersion(cliVersion: string): string { const pattern = /(?:sfdx-cli\/|@salesforce\/cli\/)(\d+\.\d+\.\d+)/; - const match = pattern.exec(sfCliVersion); + const match = pattern.exec(cliVersion); return match ? match[1] : '0.0.0'; } diff --git a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts index 8e11bfd664..89fb7664ef 100644 --- a/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts +++ b/packages/salesforcedx-utils/test/jest/cli/cliVersionStatus.test.ts @@ -14,8 +14,8 @@ describe('CliVersionStatus unit tests.', () => { const sfdxV7_valid_string = 'sfdx-cli/7.209.6 win32-x64 node-v18.15.0'; const sfV1_string = '@salesforce/cli/1.87.0 darwin-arm64 node-v18.17.1'; const sfdxV7_outdated_string = 'sfdx-cli/7.183.1 darwin-arm64 node-v16.19.1'; - const noSFDX_string = 'No SFDX CLI'; - const noSF_string = 'No SF CLI'; + const noSFDX_string = 'No CLI'; + const noSF_string = 'No CLI'; const sfV2_parsed = '2.15.9'; const sfdxV7_valid_parsed = '7.209.6'; @@ -41,14 +41,14 @@ describe('CliVersionStatus unit tests.', () => { it('getSfdxCliVersion() - can get a result', async () => { const cliVersionStatus = new CliVersionStatus(); - const result = cliVersionStatus.getSfdxCliVersion(); + const result = cliVersionStatus.getCliVersion(true); expect(result).toEqual(fakeResult); expect(executeSpy).toHaveBeenCalled(); }); it('getSfCliVersion() - can get a result', async () => { const cliVersionStatus = new CliVersionStatus(); - const result = cliVersionStatus.getSfCliVersion(); + const result = cliVersionStatus.getCliVersion(false); expect(result).toEqual(fakeResult); expect(executeSpy).toHaveBeenCalled(); }); @@ -59,8 +59,7 @@ describe('CliVersionStatus unit tests.', () => { */ describe('Test cases that throw an error for getSfdxCliVersion() and getSfCliVersion()', () => { - const sfdxNotFound = 'No SFDX CLI'; - const sfNotFound = 'No SF CLI'; + const cliNotFound = 'No CLI'; let executeSpy: jest.SpyInstance; beforeEach(() => { @@ -73,15 +72,15 @@ describe('CliVersionStatus unit tests.', () => { it('getSfdxCliVersion() - throws error', async () => { const cliVersionStatus = new CliVersionStatus(); - const result = cliVersionStatus.getSfdxCliVersion(); - expect(result).toEqual(sfdxNotFound); + const result = cliVersionStatus.getCliVersion(true); + expect(result).toEqual(cliNotFound); expect(executeSpy).toHaveBeenCalled(); }); it('getSfCliVersion() - can get a result', async () => { const cliVersionStatus = new CliVersionStatus(); - const result = cliVersionStatus.getSfCliVersion(); - expect(result).toEqual(sfNotFound); + const result = cliVersionStatus.getCliVersion(false); + expect(result).toEqual(cliNotFound); expect(executeSpy).toHaveBeenCalled(); }); }); diff --git a/packages/salesforcedx-vscode-core/src/index.ts b/packages/salesforcedx-vscode-core/src/index.ts index 3ab7981703..751d073954 100644 --- a/packages/salesforcedx-vscode-core/src/index.ts +++ b/packages/salesforcedx-vscode-core/src/index.ts @@ -716,8 +716,8 @@ export function validateCliInstallationAndVersion(): void { // If there is no CLI or it is an unsupported version then the Core extension will not activate const c = new CliVersionStatus(); - const sfdxCliVersionString = c.getSfdxCliVersion(); - const sfCliVersionString = c.getSfCliVersion(); + const sfdxCliVersionString = c.getCliVersion(true); + const sfCliVersionString = c.getCliVersion(false); const sfdxCliVersionParsed = c.parseCliVersion(sfdxCliVersionString); const sfCliVersionParsed = c.parseCliVersion(sfCliVersionString); From ca8c144fe2ac9100ce87e770e43553eb57cc276c Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Tue, 26 Dec 2023 12:12:05 -0500 Subject: [PATCH 50/52] chore: update warning message for SFDX CLI deprecation --- packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts | 2 +- packages/salesforcedx-vscode-core/src/messages/i18n.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 99a49d7121..0141e703d4 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -257,7 +257,7 @@ export const messages = { both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', sfdx_v7_deprecation: - 'Our team will remove support for SFDX(v7) of Salesforce CLI in a few months. If you are able, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', + 'SFDX CLI (v7) is scheduled for deprecation. We recommend transitioning to SF CLI for a seamless and improved experience. To do the transition, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index 0503e5eff6..3492d4b499 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -299,7 +299,7 @@ export const messages = { both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', sfdx_v7_deprecation: - 'Our team will remove support for SFDX(v7) of Salesforce CLI in a few months. If you are able, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', + 'SFDX CLI (v7) is scheduled for deprecation. We recommend transitioning to SF CLI for a seamless and improved experience. To do the transition, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', From 1b047e9fe5a70eedd88b9631e616934a7c4c6f65 Mon Sep 17 00:00:00 2001 From: Daphne Yang <139700604+daphne-sfdc@users.noreply.github.com> Date: Thu, 28 Dec 2023 11:42:38 -0500 Subject: [PATCH 51/52] refactor: getCliVersion() with ternary operator Co-authored-by: peternhale --- packages/salesforcedx-utils/src/cli/cliVersionStatus.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts index 5cf80bf929..ceb1e998b7 100644 --- a/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts +++ b/packages/salesforcedx-utils/src/cli/cliVersionStatus.ts @@ -21,12 +21,7 @@ export class CliVersionStatus { public getCliVersion(isSfdx: boolean): string { try { - let result; - if (isSfdx) { - result = execSync('sfdx --version'); - } else { - result = execSync('sf --version'); - } + const result = execSync(`${isSfdx ? 'sfdx' : 'sf'} --version`); return result.toString(); } catch { return 'No CLI'; From c6e0d5e9abb9eb938b995f1b83513cd4ad7d3431 Mon Sep 17 00:00:00 2001 From: Daphne Yang Date: Thu, 4 Jan 2024 11:48:07 -0500 Subject: [PATCH 52/52] chore: improved warning message for SFDX v7 deprecation --- packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts | 2 +- packages/salesforcedx-vscode-core/src/messages/i18n.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts index 0141e703d4..dab8e50a5e 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ja.ts @@ -257,7 +257,7 @@ export const messages = { both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', sfdx_v7_deprecation: - 'SFDX CLI (v7) is scheduled for deprecation. We recommend transitioning to SF CLI for a seamless and improved experience. To do the transition, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', + 'If you\'re currently using SFDX(v7), we highly recommend that you move to SF(v2). The move is easy: you first uninstall SFDX(v7) and then install SF(v2) from [%s](%s). After you move, the commands that you\'ve been running continue to work as before.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE', diff --git a/packages/salesforcedx-vscode-core/src/messages/i18n.ts b/packages/salesforcedx-vscode-core/src/messages/i18n.ts index 3492d4b499..6346145926 100644 --- a/packages/salesforcedx-vscode-core/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-core/src/messages/i18n.ts @@ -299,7 +299,7 @@ export const messages = { both_sfdx_and_sf: 'You have both SFDX(v7) and SF(v2) of Salesforce CLI installed. Uninstall SFDX(v7) by running `npm uninstall sfdx-cli --global` in your terminal.', sfdx_v7_deprecation: - 'SFDX CLI (v7) is scheduled for deprecation. We recommend transitioning to SF CLI for a seamless and improved experience. To do the transition, uninstall SFDX(v7) and install SF(v2) from [%s](%s).', + 'If you\'re currently using SFDX(v7), we highly recommend that you move to SF(v2). The move is easy: you first uninstall SFDX(v7) and then install SF(v2) from [%s](%s). After you move, the commands that you\'ve been running continue to work as before.', table_header_errors: 'ERRORS', table_header_project_path: 'PROJECT PATH', table_header_type: 'TYPE',