Skip to content

Use new environment variable parser #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 137 commits into from
Dec 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
ecc1ca9
Fix Microsoft/vscode#37627 (#1368)
octref Nov 3, 2017
7c5778c
Version 0.7.0 of extension (#1381)
DonJayamanne Nov 9, 2017
9d1bf82
Update README.md
DonJayamanne Nov 9, 2017
ffba179
Update README.md
DonJayamanne Nov 9, 2017
905c713
sync fork with upstream
DonJayamanne Nov 10, 2017
acc2109
fix readme
DonJayamanne Nov 10, 2017
d470523
Merge branch 'master' of https://github.com/Microsoft/vscode-python
DonJayamanne Nov 16, 2017
d32a546
run without debugging
DonJayamanne Nov 15, 2017
3f14d0a
send terminated event when process ends and fix linters
DonJayamanne Nov 15, 2017
f37803f
gracefully handle program termination
DonJayamanne Nov 16, 2017
d69940e
use vscode infrastructure to launch code in terminals
DonJayamanne Nov 16, 2017
d392e8b
merged upstream
DonJayamanne Nov 16, 2017
11c9514
merged
DonJayamanne Nov 16, 2017
38befc0
ensure to check if launchArgs is not null
DonJayamanne Nov 16, 2017
bea91fc
ensure to check if launchArgs is not null
DonJayamanne Nov 16, 2017
0bb9054
ensure to check if launchArgs is not null
DonJayamanne Nov 16, 2017
a105a20
fix code review comments
DonJayamanne Nov 17, 2017
8b2fd7c
fixed code review comments
DonJayamanne Nov 17, 2017
5a7d21e
Merge branch 'master' into RunWithoutDebug
DonJayamanne Nov 17, 2017
acd90c5
Merge branch 'master' into RunWithoutDebug
DonJayamanne Nov 17, 2017
09b3359
fixes #250, do not copy all env variables
DonJayamanne Nov 17, 2017
9616eef
bug fix, launch using vscode and then fallback
DonJayamanne Nov 17, 2017
f9fe2a8
fix linter issue
DonJayamanne Nov 17, 2017
4963632
platform process services
DonJayamanne Nov 17, 2017
edbe63e
tests for decoder
DonJayamanne Nov 18, 2017
47acd08
tests for process service
DonJayamanne Nov 18, 2017
284e221
test to check source
DonJayamanne Nov 18, 2017
b27496b
tests for process utils
DonJayamanne Nov 20, 2017
92f775f
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 20, 2017
23fe3da
fix imports
DonJayamanne Nov 20, 2017
0277ca1
rename file
DonJayamanne Nov 20, 2017
bbc8290
environment variable parser
DonJayamanne Nov 21, 2017
29b5489
refactored variable services
DonJayamanne Nov 21, 2017
5e7a61b
environment variable caching service
DonJayamanne Nov 21, 2017
81af0e5
remove unwanted file
DonJayamanne Nov 21, 2017
e0ea914
process execution with unit tests
DonJayamanne Nov 21, 2017
f0c1978
process execution with unit tests
DonJayamanne Nov 21, 2017
32a6e53
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 21, 2017
4b30f2c
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 22, 2017
e396752
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 22, 2017
4c0bdb1
merged master
DonJayamanne Nov 22, 2017
3b71463
ensure env vars are always provided
DonJayamanne Nov 22, 2017
b5d9b1a
use range instead of xrange
DonJayamanne Nov 23, 2017
56ce88b
import reflect-metadata
DonJayamanne Nov 23, 2017
eff4792
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
4553c28
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
6382e96
added unit tests for python process and other services
DonJayamanne Nov 28, 2017
8ab2eb5
clean up of test runners and collectors
DonJayamanne Nov 28, 2017
39f272f
merged master
DonJayamanne Nov 28, 2017
b05a940
fix debugging unit tests and issue with used ports
DonJayamanne Nov 28, 2017
5049ed9
refactor code
DonJayamanne Nov 28, 2017
3c6520a
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
966e516
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
63d2d65
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
f6d469e
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
eced312
Merge branch 'master' into FixCodeExec
DonJayamanne Nov 29, 2017
ce930dc
fix for rx compilation issues
DonJayamanne Nov 29, 2017
53bbc1e
fixed linter issues and injected test debug launcher
DonJayamanne Nov 29, 2017
f0c4714
improvements to build scripts
DonJayamanne Nov 29, 2017
db0e778
update
DonJayamanne Nov 29, 2017
024509d
udpates to launc and tasks
DonJayamanne Nov 29, 2017
a32f846
add package-lock
DonJayamanne Nov 29, 2017
83a1ce5
fix linter errors
DonJayamanne Nov 29, 2017
560752b
add gulp-debounced-watch
DonJayamanne Nov 30, 2017
1addf10
refactor
DonJayamanne Nov 30, 2017
73c7c81
refactor unit tests to use DI
DonJayamanne Nov 30, 2017
07a8a18
read env variable instead on demand
DonJayamanne Nov 30, 2017
b4f5c10
refactor
DonJayamanne Nov 30, 2017
f14df93
fix #327, handle all promise rejections
DonJayamanne Nov 30, 2017
e856fe8
remove invalid item
DonJayamanne Nov 30, 2017
029e055
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
f0ba6d7
fixes to move interfaces around for DI
DonJayamanne Nov 30, 2017
6dcf879
improved bounce
DonJayamanne Nov 30, 2017
71c2531
bug fix
DonJayamanne Nov 30, 2017
e8c71c0
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
b5c51c4
merged master
DonJayamanne Nov 30, 2017
7e6ee4c
DI for unit tests
DonJayamanne Dec 1, 2017
51cf9d2
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
13df41b
perf improvement
DonJayamanne Dec 1, 2017
4968ebd
improvements
DonJayamanne Dec 1, 2017
7aadc43
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
aa4062e
incremental changes
DonJayamanne Dec 1, 2017
9ef2465
refactored
DonJayamanne Dec 1, 2017
0e15e8d
pytest tests
DonJayamanne Dec 1, 2017
5a60422
add tests for nosetests
DonJayamanne Dec 1, 2017
5cfb06f
added more nose tests
DonJayamanne Dec 2, 2017
b2b7dc6
better options
DonJayamanne Dec 2, 2017
35b8255
fix issue
DonJayamanne Dec 2, 2017
7854924
reduce tests
DonJayamanne Dec 2, 2017
d69fd1a
remove duplicate registration
DonJayamanne Dec 2, 2017
317cf88
use mock out put for format tests
DonJayamanne Dec 2, 2017
07e0710
debug
DonJayamanne Dec 2, 2017
9e0d27a
debug
DonJayamanne Dec 2, 2017
5a22791
Fix tests
DonJayamanne Dec 2, 2017
fec7d51
Merge branch 'master' into FixCodeExec
DonJayamanne Dec 2, 2017
0c4003f
Merge branch 'FixCodeExec' of https://github.com/DonJayamanne/pythonV…
DonJayamanne Dec 2, 2017
9d6194b
removed unused method
DonJayamanne Dec 2, 2017
34158ba
speed up gulp
DonJayamanne Dec 4, 2017
c823315
removed unwanted setting
DonJayamanne Dec 4, 2017
e349e56
ensure chai 4.0.6 is used in tsd
DonJayamanne Dec 4, 2017
a1fea85
fixes
DonJayamanne Dec 4, 2017
cb0a354
bitwise operations are allowed
DonJayamanne Dec 4, 2017
f0f5c59
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
c464a2a
merged
DonJayamanne Dec 4, 2017
011dca1
enforce eol in vscode
DonJayamanne Dec 4, 2017
bfb8036
enforce new line
DonJayamanne Dec 4, 2017
761f057
removed ts coding conventions
DonJayamanne Dec 4, 2017
b2b9da9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
51b6c81
Use spaces instead of tabs
DonJayamanne Dec 4, 2017
7fd36fc
merged master
DonJayamanne Dec 4, 2017
ada46ba
added missing license headers and fix linter warnings
DonJayamanne Dec 4, 2017
c5e2d5d
fix code comments
DonJayamanne Dec 5, 2017
b756ee8
fix code comments
DonJayamanne Dec 5, 2017
30a4091
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 5, 2017
de14c78
merged
DonJayamanne Dec 5, 2017
22e90fb
use new execution framework in linters
DonJayamanne Dec 6, 2017
b16d2f9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 6, 2017
d1079a2
merge master
DonJayamanne Dec 6, 2017
c0a2787
fix linter issues
DonJayamanne Dec 6, 2017
479a3c2
centralize creation of output channels
DonJayamanne Dec 6, 2017
514f654
bug fix
DonJayamanne Dec 6, 2017
2b3f2ef
code refactor
DonJayamanne Dec 6, 2017
51de97b
use new env vars parser with minor tweeks
DonJayamanne Dec 6, 2017
1c7d1c9
fix code review comments
DonJayamanne Dec 7, 2017
c0e8d8f
Merge branch 'FixCodeExecInLinters' into UseNewEnvVarsParser
DonJayamanne Dec 7, 2017
7bc71b0
add more delays
DonJayamanne Dec 7, 2017
c8db345
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 7, 2017
d884256
fix telemetry props
DonJayamanne Dec 7, 2017
041ae0c
Ensure we wait before flushing everything
DonJayamanne Dec 7, 2017
248575e
Merge branch 'master' into UseNewEnvVarsParser
DonJayamanne Dec 7, 2017
0df7f16
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 8, 2017
67387bf
Merge branch 'master' into UseNewEnvVarsParser
DonJayamanne Dec 8, 2017
b5901d8
increase time and fix bug (use & instead of ||)
DonJayamanne Dec 8, 2017
5785bec
increase timeout for test because of 6sec sleeps
DonJayamanne Dec 8, 2017
679329b
ignore linebreaks
DonJayamanne Dec 8, 2017
a9edca8
fixed code review comments
DonJayamanne Dec 8, 2017
554688b
fix tests
DonJayamanne Dec 8, 2017
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
5 changes: 3 additions & 2 deletions src/client/common/envFileParser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as fs from 'fs-extra';
import 'reflect-metadata';
import { PathUtils } from './platform/pathUtils';
import { EnvironmentVariablesService } from './variables/environment';
import { EnvironmentVariables } from './variables/types';
export const IS_WINDOWS = /^win/.test(process.platform);
Expand Down Expand Up @@ -38,7 +39,7 @@ export function parseEnvFile(envFile: string, mergeWithProcessEnvVars: boolean =
* @returns {EnvironmentVariables}
*/
export function mergeEnvVariables(targetEnvVars: EnvironmentVariables, sourceEnvVars: EnvironmentVariables = process.env): EnvironmentVariables {
const service = new EnvironmentVariablesService(IS_WINDOWS);
const service = new EnvironmentVariablesService(new PathUtils(IS_WINDOWS));
service.mergeVariables(sourceEnvVars, targetEnvVars);
service.appendPythonPath(targetEnvVars, sourceEnvVars.PYTHONPATH);
return targetEnvVars;
Expand All @@ -56,7 +57,7 @@ export function mergePythonPath(env: EnvironmentVariables, currentPythonPath: st
if (typeof currentPythonPath !== 'string' || currentPythonPath.length === 0) {
return env;
}
const service = new EnvironmentVariablesService(IS_WINDOWS);
const service = new EnvironmentVariablesService(new PathUtils(IS_WINDOWS));
service.appendPythonPath(env, currentPythonPath!);
return env;
}
12 changes: 12 additions & 0 deletions src/client/common/platform/pathUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { inject, injectable } from 'inversify';
import 'reflect-metadata';
import { IPathUtils, IsWindows } from '../types';
import { NON_WINDOWS_PATH_VARIABLE_NAME, WINDOWS_PATH_VARIABLE_NAME } from './constants';

@injectable()
export class PathUtils implements IPathUtils {
constructor( @inject(IsWindows) private isWindows: boolean) { }
public getPathVariableName() {
return this.isWindows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
}
}
8 changes: 8 additions & 0 deletions src/client/common/process/proc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export class ProcessService implements IProcessService {
if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) {
spawnOptions.env = process.env;
}

// Always ensure we have unbuffered output.
spawnOptions.env.PYTHONUNBUFFERED = '1';

const proc = spawn(file, args, spawnOptions);
let procExited = false;

Expand Down Expand Up @@ -72,6 +76,10 @@ export class ProcessService implements IProcessService {
if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) {
spawnOptions.env = process.env;
}

// Always ensure we have unbuffered output.
spawnOptions.env.PYTHONUNBUFFERED = '1';

const proc = spawn(file, args, spawnOptions);
const deferred = createDeferred<ExecutionResult<string>>();
const disposables: Disposable[] = [];
Expand Down
4 changes: 3 additions & 1 deletion src/client/common/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { Installer } from './installer';
import { Logger } from './logger';
import { PersistentStateFactory } from './persistentState';
import { IS_WINDOWS as isWindows } from './platform/constants';
import { IDiposableRegistry, IInstaller, ILogger, IPersistentStateFactory, IsWindows } from './types';
import { PathUtils } from './platform/pathUtils';
import { IDiposableRegistry, IInstaller, ILogger, IPathUtils, IPersistentStateFactory, IsWindows } from './types';

export function registerTypes(serviceManager: IServiceManager) {
serviceManager.addSingletonInstance<boolean>(IsWindows, isWindows);
serviceManager.addSingleton<IPersistentStateFactory>(IPersistentStateFactory, PersistentStateFactory);
serviceManager.addSingleton<IInstaller>(IInstaller, Installer);
serviceManager.addSingleton<ILogger>(ILogger, Logger);
serviceManager.addSingleton<IPathUtils>(IPathUtils, PathUtils);

const disposableRegistry = serviceManager.get<Disposable[]>(IDiposableRegistry);
disposableRegistry.push(serviceManager.get<IInstaller>(IInstaller));
Expand Down
6 changes: 6 additions & 0 deletions src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ export interface IInstaller extends Disposable {
isInstalled(product: Product, resource?: Uri): Promise<boolean | undefined>;
disableLinter(product: Product, resource?: Uri): Promise<void>;
}

export const IPathUtils = Symbol('IPathUtils');

export interface IPathUtils {
getPathVariableName(): 'Path' | 'PATH';
}
20 changes: 9 additions & 11 deletions src/client/common/variables/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import * as fs from 'fs-extra';
import { inject, injectable } from 'inversify';
import * as path from 'path';
import 'reflect-metadata';
import { NON_WINDOWS_PATH_VARIABLE_NAME, WINDOWS_PATH_VARIABLE_NAME } from '../platform/constants';
import { IsWindows } from '../types';
import { IPathUtils } from '../types';
import { EnvironmentVariables, IEnvironmentVariablesService } from './types';

@injectable()
export class EnvironmentVariablesService implements IEnvironmentVariablesService {
constructor( @inject(IsWindows) private isWidows: boolean) { }
private readonly pathVariable: 'PATH' | 'Path';
constructor( @inject(IPathUtils) pathUtils: IPathUtils) {
this.pathVariable = pathUtils.getPathVariableName();
}
public async parseFile(filePath: string): Promise<EnvironmentVariables | undefined> {
const exists = await fs.pathExists(filePath);
if (!exists) {
Expand All @@ -27,8 +29,7 @@ export class EnvironmentVariablesService implements IEnvironmentVariablesService
return resolve(undefined);
}
this.appendPythonPath(vars, process.env.PYTHONPATH);
const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
this.appendPath(vars, process.env[pathVariable]);
this.appendPath(vars, process.env[this.pathVariable]);
resolve(vars);
});
});
Expand All @@ -37,8 +38,7 @@ export class EnvironmentVariablesService implements IEnvironmentVariablesService
if (!target) {
return;
}
const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
const settingsNotToMerge = ['PYTHONPATH', pathVariable];
const settingsNotToMerge = ['PYTHONPATH', this.pathVariable];
Object.keys(source).forEach(setting => {
if (settingsNotToMerge.indexOf(setting) >= 0) {
return;
Expand All @@ -55,12 +55,10 @@ export class EnvironmentVariablesService implements IEnvironmentVariablesService
return this.appendOrPrependPaths(vars, 'PYTHONPATH', true, ...pythonPaths);
}
public prependPath(vars: EnvironmentVariables, ...paths: string[]) {
const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
return this.appendOrPrependPaths(vars, pathVariable, false, ...paths);
return this.appendOrPrependPaths(vars, this.pathVariable, false, ...paths);
}
public appendPath(vars: EnvironmentVariables, ...paths: string[]) {
const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
return this.appendOrPrependPaths(vars, pathVariable, true, ...paths);
return this.appendOrPrependPaths(vars, this.pathVariable, true, ...paths);
}
private appendOrPrependPaths(vars: EnvironmentVariables, variableName: 'PATH' | 'Path' | 'PYTHONPATH', append: boolean, ...pythonPaths: string[]) {
const pathToInsert = pythonPaths.filter(item => typeof item === 'string' && item.length > 0).join(path.delimiter);
Expand Down
32 changes: 2 additions & 30 deletions src/client/debugger/Common/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import * as child_process from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as untildify from 'untildify';
import { mergeEnvVariables, mergePythonPath, parseEnvFile } from '../../common/envFileParser';
import { IPythonEvaluationResult, IPythonModule, IPythonProcess, IPythonThread } from './Contracts';
import { IPythonModule, IPythonProcess, IPythonThread } from './Contracts';

export const IS_WINDOWS = /^win/.test(process.platform);
export const PATH_VARIABLE_NAME = IS_WINDOWS ? 'Path' : 'PATH';
Expand All @@ -31,7 +30,7 @@ export function validatePathSync(filePath: string): boolean {
return false;
}
if (PathValidity.has(filePath)) {
return PathValidity.get(filePath);
return PathValidity.get(filePath)!;
}
const exists = fs.existsSync(filePath);
PathValidity.set(filePath, exists);
Expand Down Expand Up @@ -116,30 +115,3 @@ function isValidPythonPath(pythonPath): boolean {
return false;
}
}

type EnvVars = Object & { [key: string]: string };

export function getCustomEnvVars(envVars: Object, envFile: string, mergeWithProcessEnvVars: boolean = true): EnvVars {
let envFileVars: EnvVars = null;
if (typeof envFile === 'string' && envFile.length > 0 && fs.existsSync(envFile)) {
try {
envFileVars = parseEnvFile(envFile, mergeWithProcessEnvVars);
} catch (ex) {
console.error('Failed to load env file');
console.error(ex);
}
}
if (envFileVars && Object.keys(envFileVars).length > 0) {
if (!envVars || Object.keys(envVars).length === 0) {
return envFileVars;
} else {
envVars = envVars || {};
return mergeEnvVariables(envVars as EnvVars, envFileVars);
}
}
if (!envVars || Object.keys(envVars).length === 0) {
return null;
}

return mergePythonPath(envVars as EnvVars, process.env.PYTHONPATH);
}
79 changes: 61 additions & 18 deletions src/client/debugger/DebugClients/LocalDebugClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import * as path from 'path';
import { DebugSession, OutputEvent } from 'vscode-debugadapter';
import { DebugProtocol } from 'vscode-debugprotocol';
import { open } from '../../common/open';
import { PathUtils } from '../../common/platform/pathUtils';
import { EnvironmentVariablesService } from '../../common/variables/environment';
import { EnvironmentVariables } from '../../common/variables/types';
import { IDebugServer, IPythonProcess } from '../Common/Contracts';
import { LaunchRequestArguments } from '../Common/Contracts';
import { getCustomEnvVars } from '../Common/Utils';
import { IS_WINDOWS } from '../Common/Utils';
import { BaseDebugServer } from '../DebugServers/BaseDebugServer';
import { LocalDebugServer } from '../DebugServers/LocalDebugServer';
import { DebugClient, DebugType } from './DebugClient';
Expand All @@ -17,10 +20,25 @@ const VALID_DEBUG_OPTIONS = [
'BreakOnSystemExitZero',
'DjangoDebugging'];

enum DebugServerStatus {
Unknown = 1,
Running = 2,
NotRunning = 3
}

export class LocalDebugClient extends DebugClient {
protected pyProc: child_process.ChildProcess;
protected pyProc: child_process.ChildProcess | undefined;
protected pythonProcess: IPythonProcess;
protected debugServer: BaseDebugServer;
protected debugServer: BaseDebugServer | undefined;
private get debugServerStatus(): DebugServerStatus {
if (this.debugServer && this.debugServer!.IsRunning) {
return DebugServerStatus.Running;
}
if (this.debugServer && !this.debugServer!.IsRunning) {
return DebugServerStatus.NotRunning;
}
return DebugServerStatus.Unknown;
}
// tslint:disable-next-line:no-any
constructor(args: any, debugSession: DebugSession, private canLaunchTerminal: boolean) {
super(args, debugSession);
Expand All @@ -38,24 +56,24 @@ export class LocalDebugClient extends DebugClient {

public Stop() {
if (this.debugServer) {
this.debugServer.Stop();
this.debugServer = null;
this.debugServer!.Stop();
this.debugServer = undefined;
}

if (this.pyProc) {
try {
this.pyProc.send('EXIT');
this.pyProc!.send('EXIT');
// tslint:disable-next-line:no-empty
} catch { }
try {
this.pyProc.stdin.write('EXIT');
this.pyProc!.stdin.write('EXIT');
// tslint:disable-next-line:no-empty
} catch { }
try {
this.pyProc.disconnect();
this.pyProc!.disconnect();
// tslint:disable-next-line:no-empty
} catch { }
this.pyProc = null;
this.pyProc = undefined;
}
}
protected getLauncherFilePath(): string {
Expand All @@ -71,7 +89,8 @@ export class LocalDebugClient extends DebugClient {
}
}
// tslint:disable-next-line:max-func-body-length member-ordering no-any
public LaunchApplicationToDebug(dbgServer: IDebugServer, processErrored: (error: any) => void): Promise<any> {
public async LaunchApplicationToDebug(dbgServer: IDebugServer, processErrored: (error: any) => void): Promise<any> {
const environmentVariables = await this.getEnvironmentVariables();
// tslint:disable-next-line:max-func-body-length cyclomatic-complexity no-any
return new Promise<any>((resolve, reject) => {
const fileDir = this.args && this.args.program ? path.dirname(this.args.program) : '';
Expand All @@ -83,8 +102,6 @@ export class LocalDebugClient extends DebugClient {
if (typeof this.args.pythonPath === 'string' && this.args.pythonPath.trim().length > 0) {
pythonPath = this.args.pythonPath;
}
let environmentVariables = getCustomEnvVars(this.args.env, this.args.envFile, false);
environmentVariables = environmentVariables ? environmentVariables : {};
if (!environmentVariables.hasOwnProperty('PYTHONIOENCODING')) {
environmentVariables.PYTHONIOENCODING = 'UTF-8';
}
Expand All @@ -103,12 +120,16 @@ export class LocalDebugClient extends DebugClient {
break;
}
default: {
// As we're spawning the process, we need to ensure all env variables are passed.
// Including those from the current process (i.e. everything, not just custom vars).
const envParser = new EnvironmentVariablesService(new PathUtils(IS_WINDOWS));
envParser.mergeVariables(process.env as EnvironmentVariables, environmentVariables);
this.pyProc = child_process.spawn(pythonPath, args, { cwd: processCwd, env: environmentVariables });
this.handleProcessOutput(this.pyProc, reject);
this.handleProcessOutput(this.pyProc!, reject);

// Here we wait for the application to connect to the socket server.
// Only once connected do we know that the application has successfully launched.
this.debugServer.DebugClientConnected
this.debugServer!.DebugClientConnected
.then(resolve)
.catch(ex => console.error('Python Extension: debugServer.DebugClientConnected', ex));
}
Expand All @@ -120,10 +141,11 @@ export class LocalDebugClient extends DebugClient {
proc.on('error', error => {
// If debug server has started, then don't display errors.
// The debug adapter will get this info from the debugger (e.g. ptvsd lib).
if (!this.debugServer && this.debugServer.IsRunning) {
const status = this.debugServerStatus;
if (status === DebugServerStatus.Running) {
return;
}
if (!this.debugServer.IsRunning && typeof (error) === 'object' && error !== null) {
if (status === DebugServerStatus.NotRunning && typeof (error) === 'object' && error !== null) {
return failedToLaunch(error);
}
// This could happen when the debugger didn't launch at all, e.g. python doesn't exist.
Expand All @@ -136,13 +158,14 @@ export class LocalDebugClient extends DebugClient {

// Either way, we need some code in here so we read the stdout of the python process,
// Else it just keep building up (related to issue #203 and #52).
if (this.debugServer && !this.debugServer.IsRunning) {
if (this.debugServerStatus === DebugServerStatus.NotRunning) {
return failedToLaunch(error);
}
});
proc.stdout.on('data', d => {
// This is necessary so we read the stdout of the python process,
// Else it just keep building up (related to issue #203 and #52).
// tslint:disable-next-line:prefer-const no-unused-variable
let x = 0;
});
}
Expand Down Expand Up @@ -193,12 +216,32 @@ export class LocalDebugClient extends DebugClient {
this.pyProc = proc;
resolve();
}, error => {
if (!this.debugServer && this.debugServer.IsRunning) {
if (this.debugServerStatus === DebugServerStatus.Running) {
return;
}
reject(error);
});
}
});
}
private async getEnvironmentVariables(): Promise<EnvironmentVariables> {
const args = this.args as LaunchRequestArguments;
const envParser = new EnvironmentVariablesService(new PathUtils(IS_WINDOWS));
const envFileVars = await envParser.parseFile(args.envFile);

const hasEnvVars = args.env && Object.keys(args.env).length > 0;
if (!envFileVars && !hasEnvVars) {
return {};
}
if (envFileVars && !hasEnvVars) {
return envFileVars!;
}
if (!envFileVars && hasEnvVars) {
return args.env as EnvironmentVariables;
}
// Merge the two sets of environment variables.
const env = { ...args.env } as EnvironmentVariables;
envParser.mergeVariables(envFileVars!, env);
return env;
}
}
9 changes: 3 additions & 6 deletions src/client/debugger/DebugClients/NonDebugClient.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { ChildProcess } from 'child_process';
import * as path from 'path';
import { DebugSession, OutputEvent } from 'vscode-debugadapter';
import { IPythonProcess } from '../Common/Contracts';
import { DebugSession } from 'vscode-debugadapter';
import { LaunchRequestArguments } from '../Common/Contracts';
import { BaseDebugServer } from '../DebugServers/BaseDebugServer';
import { LocalDebugServer } from '../DebugServers/LocalDebugServer';
import { DebugType } from './DebugClient';
import { LocalDebugClient } from './LocalDebugClient';

Expand All @@ -22,10 +19,10 @@ export class NonDebugClient extends LocalDebugClient {
super.Stop();
if (this.pyProc) {
try {
this.pyProc.kill();
this.pyProc!.kill();
// tslint:disable-next-line:no-empty
} catch { }
this.pyProc = null;
this.pyProc = undefined;
}
}
protected handleProcessOutput(proc: ChildProcess, _failedToLaunch: (error: Error | string | Buffer) => void) {
Expand Down
Loading