diff --git a/src/managers/common/utils.ts b/src/managers/common/utils.ts index 828f6e10..0d084da5 100644 --- a/src/managers/common/utils.ts +++ b/src/managers/common/utils.ts @@ -139,6 +139,18 @@ export function compareVersions(version1: string, version2: string): number { return 0; } +function buildPwshActivationCommands(ps1Path: string): PythonCommandRunConfiguration[] { + const commands: PythonCommandRunConfiguration[] = []; + if (isWindows()) { + commands.push({ + executable: 'Set-ExecutionPolicy', + args: ['-Scope', 'Process', '-ExecutionPolicy', 'RemoteSigned'], + }); + } + commands.push({ executable: '&', args: [ps1Path] }); + return commands; +} + export async function getShellActivationCommands(binDir: string): Promise<{ shellActivation: Map; shellDeactivation: Map; @@ -172,22 +184,10 @@ export async function getShellActivationCommands(binDir: string): Promise<{ shellDeactivation.set(ShellConstants.KSH, [{ executable: 'deactivate' }]); if (await fs.pathExists(path.join(binDir, 'Activate.ps1'))) { - shellActivation.set(ShellConstants.PWSH, [ - { - executable: 'Set-ExecutionPolicy', - args: ['-Scope', 'Process', '-ExecutionPolicy', 'RemoteSigned'], - }, - { executable: '&', args: [path.join(binDir, `Activate.ps1`)] }, - ]); + shellActivation.set(ShellConstants.PWSH, buildPwshActivationCommands(path.join(binDir, 'Activate.ps1'))); shellDeactivation.set(ShellConstants.PWSH, [{ executable: 'deactivate' }]); } else if (await fs.pathExists(path.join(binDir, 'activate.ps1'))) { - shellActivation.set(ShellConstants.PWSH, [ - { - executable: 'Set-ExecutionPolicy', - args: ['-Scope', 'Process', '-ExecutionPolicy', 'RemoteSigned'], - }, - { executable: '&', args: [path.join(binDir, `activate.ps1`)] }, - ]); + shellActivation.set(ShellConstants.PWSH, buildPwshActivationCommands(path.join(binDir, 'activate.ps1'))); shellDeactivation.set(ShellConstants.PWSH, [{ executable: 'deactivate' }]); } diff --git a/src/test/managers/common/utils.getShellActivationCommands.unit.test.ts b/src/test/managers/common/utils.getShellActivationCommands.unit.test.ts index 350cd013..756d30e0 100644 --- a/src/test/managers/common/utils.getShellActivationCommands.unit.test.ts +++ b/src/test/managers/common/utils.getShellActivationCommands.unit.test.ts @@ -80,6 +80,42 @@ suite('getShellActivationCommands', () => { }); }); + suite('PowerShell activation on non-Windows omits Set-ExecutionPolicy', () => { + test('Activate.ps1 (capitalized) on non-Windows has only the activation command', async () => { + isWindowsStub.returns(false); + await fs.writeFile(path.join(tmpDir, 'Activate.ps1'), ''); + + const result = await getShellActivationCommands(tmpDir); + const pwshActivation = result.shellActivation.get(ShellConstants.PWSH); + + assert.ok(pwshActivation, 'PowerShell activation should be defined'); + assert.strictEqual(pwshActivation.length, 1, 'Should have only 1 command: activate (no Set-ExecutionPolicy)'); + assert.strictEqual(pwshActivation[0].executable, '&'); + assert.ok(pwshActivation[0].args); + assert.ok( + pwshActivation[0].args[0].endsWith('Activate.ps1'), + `Expected path ending with Activate.ps1, got: ${pwshActivation[0].args[0]}`, + ); + }); + + test('activate.ps1 (lowercase) on non-Windows has only the activation command', async () => { + isWindowsStub.returns(false); + await fs.writeFile(path.join(tmpDir, 'activate.ps1'), ''); + + const result = await getShellActivationCommands(tmpDir); + const pwshActivation = result.shellActivation.get(ShellConstants.PWSH); + + assert.ok(pwshActivation, 'PowerShell activation should be defined'); + assert.strictEqual(pwshActivation.length, 1, 'Should have only 1 command: activate (no Set-ExecutionPolicy)'); + assert.strictEqual(pwshActivation[0].executable, '&'); + assert.ok(pwshActivation[0].args); + assert.ok( + pwshActivation[0].args[0].endsWith('activate.ps1'), + `Expected path ending with activate.ps1, got: ${pwshActivation[0].args[0]}`, + ); + }); + }); + suite('No PowerShell activation when Activate.ps1 is absent', () => { test('No pwsh activation when no ps1 file exists', async () => { isWindowsStub.returns(true);