From 1a1a957f593e072ab44ddde05dd47b5c3dab9e87 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 23 Mar 2022 23:37:09 +0530 Subject: [PATCH 1/3] Execute conda related commands using shell --- .../common/environmentManagers/conda.ts | 9 ++++++--- .../common/environmentManagers/conda.unit.test.ts | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/client/pythonEnvironments/common/environmentManagers/conda.ts b/src/client/pythonEnvironments/common/environmentManagers/conda.ts index 61a6487d3840..622aa1e060ae 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/conda.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/conda.ts @@ -4,7 +4,6 @@ import { lt, parse, SemVer } from 'semver'; import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; import { arePathsSame, - exec, getPythonSetting, isParentPath, pathExists, @@ -390,7 +389,9 @@ export class Conda { @cache(30_000, true, 10_000) // eslint-disable-next-line class-methods-use-this private async getInfoCached(command: string): Promise { - const result = await exec(command, ['info', '--json'], { timeout: CONDA_GENERAL_TIMEOUT }); + const quoted = [command.toCommandArgument(), 'info', '--json'].join(' '); + // Execute in a shell as `conda` on windows refers to `conda.bat`, which requires a shell to work. + const result = await shellExecute(quoted, { timeout: CONDA_GENERAL_TIMEOUT }); traceVerbose(`conda info --json: ${result.stdout}`); return JSON.parse(result.stdout); } @@ -491,7 +492,9 @@ export class Conda { if (info && info.conda_version) { versionString = info.conda_version; } else { - const stdOut = await exec(this.command, ['--version'], { timeout: CONDA_GENERAL_TIMEOUT }) + const quoted = `${this.command.toCommandArgument()} --version`; + // Execute in a shell as `conda` on windows refers to `conda.bat`, which requires a shell to work. + const stdOut = await shellExecute(quoted, { timeout: CONDA_GENERAL_TIMEOUT }) .then((result) => result.stdout.trim()) .catch(() => undefined); diff --git a/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts b/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts index e0a324eb70da..7857fb1d686b 100644 --- a/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts +++ b/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts @@ -16,7 +16,7 @@ import { createBasicEnv } from '../../base/common'; import { assertBasicEnvsEqual } from '../../base/locators/envTestUtils'; import { OUTPUT_MARKER_SCRIPT } from '../../../../client/common/process/internal/scripts'; -suite('Conda and its environments are located correctly', () => { +suite('xConda and its environments are located correctly', () => { // getOSType() is stubbed to return this. let osType: platform.OSType; @@ -185,7 +185,8 @@ suite('Conda and its environments are located correctly', () => { return contents; }); - sinon.stub(externalDependencies, 'exec').callsFake(async (command: string, args: string[]) => { + sinon.stub(externalDependencies, 'shellExecute').callsFake(async (quoted: string) => { + const [command, ...args] = quoted.split(' '); for (const prefix of ['', ...execPath]) { const contents = getFile(path.join(prefix, command)); if (args[0] === 'info' && args[1] === '--json') { From cd40c579bfb77d8d8e48b5bdd3ce87af58d2f3f8 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 23 Mar 2022 23:48:59 +0530 Subject: [PATCH 2/3] Fix resolve utils unit tests --- .../base/locators/composite/resolverUtils.unit.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts b/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts index ae62800eb753..73802c6fef6a 100644 --- a/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts +++ b/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts @@ -247,7 +247,8 @@ suite('Resolver Utils', () => { test('resolveEnv (Windows)', async () => { sinon.stub(platformApis, 'getOSType').callsFake(() => platformApis.OSType.Windows); - sinon.stub(externalDependencies, 'exec').callsFake(async (command: string, args: string[]) => { + sinon.stub(externalDependencies, 'shellExecute').callsFake(async (quoted: string) => { + const [command, ...args] = quoted.split(' '); if (command === 'conda' && args[0] === 'info' && args[1] === '--json') { return { stdout: JSON.stringify(condaInfo(condaPrefixWindows)) }; } @@ -262,7 +263,8 @@ suite('Resolver Utils', () => { test('resolveEnv (non-Windows)', async () => { sinon.stub(platformApis, 'getOSType').callsFake(() => platformApis.OSType.Linux); - sinon.stub(externalDependencies, 'exec').callsFake(async (command: string, args: string[]) => { + sinon.stub(externalDependencies, 'shellExecute').callsFake(async (quoted: string) => { + const [command, ...args] = quoted.split(' '); if (command === 'conda' && args[0] === 'info' && args[1] === '--json') { return { stdout: JSON.stringify(condaInfo(condaPrefixNonWindows)) }; } @@ -280,7 +282,7 @@ suite('Resolver Utils', () => { test('resolveEnv: If no conda binary found, resolve as a simple environment', async () => { sinon.stub(platformApis, 'getOSType').callsFake(() => platformApis.OSType.Windows); - sinon.stub(externalDependencies, 'exec').callsFake(async (command: string) => { + sinon.stub(externalDependencies, 'shellExecute').callsFake(async (command: string) => { throw new Error(`${command} is missing or is not executable`); }); const actual = await resolveBasicEnv({ @@ -603,7 +605,7 @@ suite('Resolver Utils', () => { }); test('If data provided by registry is less informative than kind resolvers, do not use it to update environment', async () => { - sinon.stub(externalDependencies, 'exec').callsFake(async (command: string) => { + sinon.stub(externalDependencies, 'shellExecute').callsFake(async (command: string) => { throw new Error(`${command} is missing or is not executable`); }); const interpreterPath = path.join(regTestRoot, 'conda3', 'python.exe'); From 86d36337440590fab316f7fe8f8e5a18d3ace29f Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 23 Mar 2022 23:51:25 +0530 Subject: [PATCH 3/3] Oops --- .../common/environmentManagers/conda.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts b/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts index 7857fb1d686b..553ef2e5e9d7 100644 --- a/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts +++ b/src/test/pythonEnvironments/common/environmentManagers/conda.unit.test.ts @@ -16,7 +16,7 @@ import { createBasicEnv } from '../../base/common'; import { assertBasicEnvsEqual } from '../../base/locators/envTestUtils'; import { OUTPUT_MARKER_SCRIPT } from '../../../../client/common/process/internal/scripts'; -suite('xConda and its environments are located correctly', () => { +suite('Conda and its environments are located correctly', () => { // getOSType() is stubbed to return this. let osType: platform.OSType;