Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/managers/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, PythonCommandRunConfiguration[]>;
shellDeactivation: Map<string, PythonCommandRunConfiguration[]>;
Expand Down Expand Up @@ -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' }]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down