Skip to content

Commit 5db26f8

Browse files
authored
Point release with fixes for debugger and activation of environments (#5939)
* Fixes to activation of Conda environments (#5934) * Disable quoting paths sent to the debugger as args (#5936) * Disable quoting paths sent to the debugger as args * Remove unnecessary class * Fix typo * Fixes to tests * Update version for new point release
1 parent d47a991 commit 5db26f8

File tree

11 files changed

+83
-53
lines changed

11 files changed

+83
-53
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# Changelog
22

3-
## 2019.5.3 (5 June 2019)
3+
## 2019.5.4 (6 June 2019)
4+
5+
### Fixes
6+
7+
1. Disable quoting of paths sent to the debugger as arguments.
8+
([#5861](https://github.com/microsoft/vscode-python/issues/5861))
9+
1. Fixes to activation of Conda environments.
10+
([#5929](https://github.com/microsoft/vscode-python/issues/5929))
11+
12+
## 2019.5.18678 (5 June 2019)
413

514
### Fixes
615

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "python",
33
"displayName": "Python",
44
"description": "Linting, Debugging (multi-threaded, remote), Intellisense, code formatting, refactoring, unit tests, snippets, and more.",
5-
"version": "2019.5.3",
5+
"version": "2019.5.4",
66
"languageServerVersion": "0.2.82",
77
"publisher": "ms-python",
88
"author": {

src/client/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'use strict';
55

66
import { traceError } from './common/logger';
7-
import { RemoteDebuggerLauncherScriptProvider } from './debugger/debugAdapter/DebugClients/launcherProvider';
7+
import { RemoteDebuggerExternalLauncherScriptProvider } from './debugger/debugAdapter/DebugClients/launcherProvider';
88

99
/*
1010
* Do not introduce any breaking changes to this API.
@@ -42,7 +42,7 @@ export function buildApi(ready: Promise<any>) {
4242
}),
4343
debug: {
4444
async getRemoteLauncherCommand(host: string, port: number, waitUntilDebuggerAttaches: boolean = true): Promise<string[]> {
45-
return new RemoteDebuggerLauncherScriptProvider().getLauncherArgs({ host, port, waitUntilDebuggerAttaches });
45+
return new RemoteDebuggerExternalLauncherScriptProvider().getLauncherArgs({ host, port, waitUntilDebuggerAttaches });
4646
}
4747
}
4848
};

src/client/common/terminal/helper.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,8 @@ export class TerminalHelper implements ITerminalHelper {
5252
this.sendTelemetry(resource, terminalShellType, EventName.PYTHON_INTERPRETER_ACTIVATION_FOR_TERMINAL, promise).ignoreErrors();
5353
return promise;
5454
}
55-
public async getEnvironmentActivationShellCommands(resource: Resource, interpreter?: PythonInterpreter): Promise<string[] | undefined> {
56-
if (this.platform.osType === OSType.Unknown){
57-
return;
58-
}
59-
const shell = this.shellDetector.identifyTerminalShell();
60-
if (!shell) {
55+
public async getEnvironmentActivationShellCommands(resource: Resource, shell: TerminalShellType, interpreter?: PythonInterpreter): Promise<string[] | undefined> {
56+
if (this.platform.osType === OSType.Unknown) {
6157
return;
6258
}
6359
const providers = [this.bashCShellFish, this.commandPromptAndPowerShell];

src/client/common/terminal/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export interface ITerminalHelper {
5757
identifyTerminalShell(terminal?: Terminal): TerminalShellType;
5858
buildCommandForTerminal(terminalShellType: TerminalShellType, command: string, args: string[]): string;
5959
getEnvironmentActivationCommands(terminalShellType: TerminalShellType, resource?: Uri): Promise<string[] | undefined>;
60-
getEnvironmentActivationShellCommands(resource: Resource, interpreter?: PythonInterpreter): Promise<string[] | undefined>;
60+
getEnvironmentActivationShellCommands(resource: Resource, shell: TerminalShellType, interpreter?: PythonInterpreter): Promise<string[] | undefined>;
6161
}
6262

6363
export const ITerminalActivator = Symbol('ITerminalActivator');

src/client/debugger/debugAdapter/DebugClients/launcherProvider.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,26 @@ export class NoDebugLauncherScriptProvider implements IDebugLauncherScriptProvid
1515
constructor(@optional() private script: string = pathToScript) { }
1616
public getLauncherArgs(options: LocalDebugOptions): string[] {
1717
const customDebugger = options.customDebugger ? '--custom' : '--default';
18-
return [this.script.fileToCommandArgument(), customDebugger, '--nodebug', '--client', '--host', options.host, '--port', options.port.toString()];
18+
return [this.script, customDebugger, '--nodebug', '--client', '--host', options.host, '--port', options.port.toString()];
1919
}
2020
}
2121

2222
export class DebuggerLauncherScriptProvider implements IDebugLauncherScriptProvider<LocalDebugOptions> {
2323
constructor(@optional() private script: string = pathToScript) { }
2424
public getLauncherArgs(options: LocalDebugOptions): string[] {
2525
const customDebugger = options.customDebugger ? '--custom' : '--default';
26-
return [this.script.fileToCommandArgument(), customDebugger, '--client', '--host', options.host, '--port', options.port.toString()];
26+
return [this.script, customDebugger, '--client', '--host', options.host, '--port', options.port.toString()];
2727
}
2828
}
2929

30-
export class RemoteDebuggerLauncherScriptProvider implements IRemoteDebugLauncherScriptProvider {
30+
/**
31+
* This class is used to provide the launch scripts so external code can launch the debugger.
32+
* As we're passing command arguments, we need to ensure the file paths are quoted.
33+
* @export
34+
* @class RemoteDebuggerExternalLauncherScriptProvider
35+
* @implements {IRemoteDebugLauncherScriptProvider}
36+
*/
37+
export class RemoteDebuggerExternalLauncherScriptProvider implements IRemoteDebugLauncherScriptProvider {
3138
constructor(@optional() private script: string = pathToScript) { }
3239
public getLauncherArgs(options: RemoteDebugOptions): string[] {
3340
const waitArgs = options.waitUntilDebuggerAttaches ? ['--wait'] : [];

src/client/interpreter/activation/service.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as path from 'path';
99
import { LogOptions, traceDecorators, traceError, traceVerbose } from '../../common/logger';
1010
import { IPlatformService } from '../../common/platform/types';
1111
import { IProcessServiceFactory } from '../../common/process/types';
12-
import { ITerminalHelper } from '../../common/terminal/types';
12+
import { ITerminalHelper, TerminalShellType } from '../../common/terminal/types';
1313
import { ICurrentProcess, IDisposable, Resource } from '../../common/types';
1414
import {
1515
cacheResourceSpecificInterpreterData,
@@ -29,9 +29,9 @@ const getEnvironmentTimeout = 30000;
2929

3030
// The shell under which we'll execute activation scripts.
3131
const defaultShells = {
32-
[OSType.Windows]: 'cmd',
33-
[OSType.OSX]: 'bash',
34-
[OSType.Linux]: 'bash',
32+
[OSType.Windows]: { shell: 'cmd', shellType: TerminalShellType.commandPrompt },
33+
[OSType.OSX]: { shell: 'bash', shellType: TerminalShellType.bash },
34+
[OSType.Linux]: { shell: 'bash', shellType: TerminalShellType.bash },
3535
[OSType.Unknown]: undefined
3636
};
3737

@@ -54,14 +54,14 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
5454
@captureTelemetry(EventName.PYTHON_INTERPRETER_ACTIVATION_ENVIRONMENT_VARIABLES, { failed: false }, true)
5555
@cacheResourceSpecificInterpreterData('ActivatedEnvironmentVariables', cacheDuration)
5656
public async getActivatedEnvironmentVariables(resource: Resource, interpreter?: PythonInterpreter, allowExceptions?: boolean): Promise<NodeJS.ProcessEnv | undefined> {
57-
const shell = defaultShells[this.platform.osType];
58-
if (!shell) {
57+
const shellInfo = defaultShells[this.platform.osType];
58+
if (!shellInfo) {
5959
return;
6060
}
6161

6262
try {
63-
const activationCommands = await this.helper.getEnvironmentActivationShellCommands(resource, interpreter);
64-
traceVerbose(`Activation Commands received ${activationCommands}`);
63+
const activationCommands = await this.helper.getEnvironmentActivationShellCommands(resource, shellInfo.shellType, interpreter);
64+
traceVerbose(`Activation Commands received ${activationCommands} for shell ${shellInfo.shell}`);
6565
if (!activationCommands || !Array.isArray(activationCommands) || activationCommands.length === 0) {
6666
return;
6767
}
@@ -84,7 +84,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
8484
// See the discussion from hidesoon in this issue: https://github.com/Microsoft/vscode-python/issues/4424
8585
// His issue is conda never finishing during activate. This is a conda issue, but we
8686
// should at least tell the user.
87-
const result = await processService.shellExec(command, { env, shell, timeout: getEnvironmentTimeout, maxBuffer: 1000 * 1000 });
87+
const result = await processService.shellExec(command, { env, shell: shellInfo.shell, timeout: getEnvironmentTimeout, maxBuffer: 1000 * 1000 });
8888
if (result.stderr && result.stderr.length > 0) {
8989
throw new Error(`StdErr from ShellExec, ${result.stderr}`);
9090
}

src/test/common/terminals/helper.unit.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,10 @@ suite('Terminal Service helpers', () => {
315315
test('Activation command for Shell must be empty for unknown os', async () => {
316316
when(platformService.osType).thenReturn(OSType.Unknown);
317317

318-
const cmd = await helper.getEnvironmentActivationShellCommands(resource, interpreter);
319-
320-
expect(cmd).to.equal(undefined, 'Command must be undefined');
318+
for (const item of getNamesAndValues<TerminalShellType>(TerminalShellType)) {
319+
const cmd = await helper.getEnvironmentActivationShellCommands(resource, item.value, interpreter);
320+
expect(cmd).to.equal(undefined, 'Command must be undefined');
321+
}
321322
});
322323
});
323324
[undefined, pythonInterpreter].forEach(interpreter => {
@@ -332,7 +333,7 @@ suite('Terminal Service helpers', () => {
332333
when(bashActivationProvider.isShellSupported(shellToExpect)).thenReturn(false);
333334
when(cmdActivationProvider.isShellSupported(shellToExpect)).thenReturn(false);
334335

335-
const cmd = await helper.getEnvironmentActivationShellCommands(resource, interpreter);
336+
const cmd = await helper.getEnvironmentActivationShellCommands(resource, shellToExpect, interpreter);
336337

337338
expect(cmd).to.equal(undefined, 'Command must be undefined');
338339
verify(pythonSettings.terminal).once();

src/test/debugger/debugAdapter/debugClients/launcherProvider.unit.test.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { expect } from 'chai';
77
import * as fs from 'fs-extra';
88
import * as path from 'path';
99
import { EXTENSION_ROOT_DIR } from '../../../../client/common/constants';
10-
import { DebuggerLauncherScriptProvider, NoDebugLauncherScriptProvider, RemoteDebuggerLauncherScriptProvider } from '../../../../client/debugger/debugAdapter/DebugClients/launcherProvider';
10+
import { DebuggerLauncherScriptProvider, NoDebugLauncherScriptProvider, RemoteDebuggerExternalLauncherScriptProvider } from '../../../../client/debugger/debugAdapter/DebugClients/launcherProvider';
1111

1212
const expectedPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'ptvsd_launcher.py');
1313

@@ -21,12 +21,12 @@ suite('Debugger - Launcher Script Provider', () => {
2121
{
2222
testName: 'When path to ptvsd launcher does not contains spaces',
2323
path: path.join('path', 'to', 'ptvsd_launcher'),
24-
expectedPath: 'path/to/ptvsd_launcher'
24+
expectedPath: path.join('path', 'to', 'ptvsd_launcher')
2525
},
2626
{
2727
testName: 'When path to ptvsd launcher contains spaces',
2828
path: path.join('path', 'to', 'ptvsd_launcher', 'with spaces'),
29-
expectedPath: '"path/to/ptvsd_launcher/with spaces"'
29+
expectedPath: path.join('path', 'to', 'ptvsd_launcher', 'with spaces')
3030
}
3131
];
3232

@@ -52,15 +52,33 @@ suite('Debugger - Launcher Script Provider', () => {
5252
const expectedArgs = [testParams.expectedPath, '--custom', '--nodebug', '--client', '--host', 'something', '--port', '1234'];
5353
expect(args).to.be.deep.equal(expectedArgs);
5454
});
55-
test('Test remote debug launcher args (and do not wait for debugger to attach)', async () => {
56-
const args = new RemoteDebuggerLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: false });
57-
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234'];
58-
expect(args).to.be.deep.equal(expectedArgs);
59-
});
60-
test('Test remote debug launcher args (and wait for debugger to attach)', async () => {
61-
const args = new RemoteDebuggerLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: true });
62-
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234', '--wait'];
63-
expect(args).to.be.deep.equal(expectedArgs);
55+
});
56+
});
57+
58+
suite('External Debug Launcher', () => {
59+
[
60+
{
61+
testName: 'When path to ptvsd launcher does not contains spaces',
62+
path: path.join('path', 'to', 'ptvsd_launcher'),
63+
expectedPath: 'path/to/ptvsd_launcher'
64+
},
65+
{
66+
testName: 'When path to ptvsd launcher contains spaces',
67+
path: path.join('path', 'to', 'ptvsd_launcher', 'with spaces'),
68+
expectedPath: '"path/to/ptvsd_launcher/with spaces"'
69+
}
70+
].forEach(testParams => {
71+
suite(testParams.testName, async () => {
72+
test('Test remote debug launcher args (and do not wait for debugger to attach)', async () => {
73+
const args = new RemoteDebuggerExternalLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: false });
74+
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234'];
75+
expect(args).to.be.deep.equal(expectedArgs);
76+
});
77+
test('Test remote debug launcher args (and wait for debugger to attach)', async () => {
78+
const args = new RemoteDebuggerExternalLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: true });
79+
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234', '--wait'];
80+
expect(args).to.be.deep.equal(expectedArgs);
81+
});
6482
});
6583
});
6684
});

0 commit comments

Comments
 (0)