Skip to content

Complete refactoring of code to use new code exec engine #493

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 86 commits into from
Jan 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 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
d392e8b
merged upstream
DonJayamanne Nov 16, 2017
92f775f
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 20, 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
eff4792
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
4553c28
Merge remote-tracking branch 'upstream/master'
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
029e055
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
e8c71c0
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
51cf9d2
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
7aadc43
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
f0f5c59
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
b2b9da9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
30a4091
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 5, 2017
b16d2f9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 6, 2017
c8db345
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 7, 2017
0df7f16
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 8, 2017
3ccc881
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 9, 2017
bb0709e
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
2c19004
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
8f224ab
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
41b7080
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
dab38dc
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
ae22dd4
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
d2340d2
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 14, 2017
bcb8879
use new exec engine instead of spawning manually
DonJayamanne Dec 14, 2017
c6d6f50
refactor to use new execution framework
DonJayamanne Dec 15, 2017
65a949b
refactor to use new exec framework
DonJayamanne Dec 15, 2017
c8559ea
fix linter errors
DonJayamanne Dec 15, 2017
51a2802
refactor
DonJayamanne Dec 15, 2017
c778493
disable messages and copy config files
DonJayamanne Dec 15, 2017
a34a62c
remove old execution layer
DonJayamanne Dec 15, 2017
9452d0e
misc
DonJayamanne Dec 15, 2017
52bb7ae
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 15, 2017
5760886
merged master
DonJayamanne Dec 15, 2017
1714f0c
Merge branch 'D' into FixDebuggerEnvVars
DonJayamanne Dec 15, 2017
1bdc95d
fix tests
DonJayamanne Dec 15, 2017
0313000
fix tests
DonJayamanne Dec 15, 2017
e7eb19e
disable message D102
DonJayamanne Dec 15, 2017
d09b3ef
fix bug introduced into test
DonJayamanne Dec 15, 2017
0467d4c
fix tests
DonJayamanne Dec 15, 2017
ffdfd5d
fixed code review comments
DonJayamanne Dec 15, 2017
59ff402
added tests for env variable parsing
DonJayamanne Dec 16, 2017
bab860f
remove metadata
DonJayamanne Dec 18, 2017
b6b2531
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 19, 2017
2b21cec
merged master
DonJayamanne Dec 19, 2017
56d5c60
Merge branch 'FixDebuggerEnvVars' into EnvVarFixes
DonJayamanne Dec 19, 2017
0ea674b
Merge branch 'RefactorJediAndOthers' into EnvVarFixes
DonJayamanne Dec 19, 2017
09d2372
refactor environment variables parser
DonJayamanne Dec 19, 2017
203e13e
fixed linter error
DonJayamanne Dec 19, 2017
21601f2
Fixed code review comments
DonJayamanne Dec 19, 2017
733f9a1
Merge branch 'RefactorJediAndOthers' into EnvVarFixes
DonJayamanne Dec 19, 2017
24fa57e
added tests for env vars service
DonJayamanne Dec 19, 2017
649b7e7
console could be null
DonJayamanne Dec 19, 2017
8d8d2fc
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 19, 2017
6641ec8
merged master
DonJayamanne Dec 19, 2017
b65d7c0
merged master
DonJayamanne Dec 19, 2017
e6c9472
use new env variables service in jedi service
DonJayamanne Dec 20, 2017
bf2d5d5
fix #456
DonJayamanne Dec 21, 2017
98b6993
add missing service registrations
DonJayamanne Dec 21, 2017
db84ded
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Dec 21, 2017
25e4b71
add missing service registration
DonJayamanne Dec 21, 2017
81bec0a
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Dec 21, 2017
3bbbaaa
add missing service registration
DonJayamanne Dec 21, 2017
4750999
use env service instead of child_process
DonJayamanne Dec 29, 2017
86eb43f
swallow the exception
DonJayamanne Dec 29, 2017
ead278c
fix shebang detection
DonJayamanne Dec 29, 2017
30d0bb5
remove imports of 'reflect-metadata'
DonJayamanne Jan 2, 2018
5eb11dc
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Jan 2, 2018
1f5fe49
Merge branch 'CommonToolExecution' into CompleteCodeExec
DonJayamanne Jan 2, 2018
c425a55
Merge remote-tracking branch 'upstream/master'
DonJayamanne Jan 3, 2018
f8b9eac
merge master
DonJayamanne Jan 3, 2018
8855bf7
Merge branch 'CommonToolExecution' into CompleteCodeExec
DonJayamanne Jan 3, 2018
3963217
Merge remote-tracking branch 'upstream/master'
DonJayamanne Jan 3, 2018
9ab1013
merge master
DonJayamanne Jan 3, 2018
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
4 changes: 2 additions & 2 deletions src/client/common/process/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export type ExecutionResult<T extends string | Buffer> = {
export const IProcessService = Symbol('IProcessService');

export interface IProcessService {
execObservable(file: string, args: string[], options: SpawnOptions): ObservableExecutionResult<string>;
exec(file: string, args: string[], options: SpawnOptions): Promise<ExecutionResult<string>>;
execObservable(file: string, args: string[], options?: SpawnOptions): ObservableExecutionResult<string>;
exec(file: string, args: string[], options?: SpawnOptions): Promise<ExecutionResult<string>>;
}

export const IPythonExecutionFactory = Symbol('IPythonExecutionFactory');
Expand Down
3 changes: 2 additions & 1 deletion src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export enum Product {
mypy = 11,
unittest = 12,
ctags = 13,
rope = 14
rope = 14,
isort = 15
}

export enum ModuleNamePurpose {
Expand Down
13 changes: 0 additions & 13 deletions src/client/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';
// tslint:disable: no-any one-line no-suspicious-comment prefer-template prefer-const no-unnecessary-callback-wrapper no-function-expression no-string-literal no-control-regex no-shadowed-variable

import * as child_process from 'child_process';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
Expand Down Expand Up @@ -30,18 +29,6 @@ export function fsReaddirAsync(root: string): Promise<string[]> {
});
}

export async function getPathFromPythonCommand(pythonPath: string): Promise<string> {
return await new Promise<string>((resolve, reject) => {
child_process.execFile(pythonPath, ['-c', 'import sys;print(sys.executable)'], (_, stdout) => {
if (stdout) {
const lines = stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0);
resolve(lines.length > 0 ? lines[0] : '');
} else {
reject();
}
});
});
}
export function formatErrorForLogging(error: Error | string): string {
let message: string = '';
if (typeof error === 'string') {
Expand Down
10 changes: 6 additions & 4 deletions src/client/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { STANDARD_OUTPUT_CHANNEL } from './common/constants';
import { FeatureDeprecationManager } from './common/featureDeprecationManager';
import { createDeferred } from './common/helpers';
import { registerTypes as processRegisterTypes } from './common/process/serviceRegistry';
import { IProcessService, IPythonExecutionFactory } from './common/process/types';
import { registerTypes as commonRegisterTypes } from './common/serviceRegistry';
import { GLOBAL_MEMENTO, IDisposableRegistry, ILogger, IMemento, IOutputChannel, IPersistentStateFactory, WORKSPACE_MEMENTO } from './common/types';
import { registerTypes as variableRegisterTypes } from './common/variables/serviceRegistry';
Expand Down Expand Up @@ -85,23 +86,24 @@ export async function activate(context: vscode.ExtensionContext) {
const pythonSettings = settings.PythonSettings.getInstance();
sendStartupTelemetry(activated, serviceContainer);

sortImports.activate(context, standardOutputChannel);
sortImports.activate(context, standardOutputChannel, serviceContainer);
const interpreterManager = new InterpreterManager(serviceContainer);
// This must be completed before we can continue.
await interpreterManager.autoSetInterpreter();

interpreterManager.refresh()
.catch(ex => console.error('Python Extension: interpreterManager.refresh', ex));
context.subscriptions.push(interpreterManager);
const processService = serviceContainer.get<IProcessService>(IProcessService);
const interpreterVersionService = serviceContainer.get<IInterpreterVersionService>(IInterpreterVersionService);
context.subscriptions.push(new SetInterpreterProvider(interpreterManager, interpreterVersionService));
context.subscriptions.push(new SetInterpreterProvider(interpreterManager, interpreterVersionService, processService));
context.subscriptions.push(...activateExecInTerminalProvider());
context.subscriptions.push(activateUpdateSparkLibraryProvider());
activateSimplePythonRefactorProvider(context, standardOutputChannel, serviceContainer);
const jediFactory = new JediFactory(context.asAbsolutePath('.'), serviceContainer);
context.subscriptions.push(...activateGoToObjectDefinitionProvider(jediFactory));

context.subscriptions.push(new ReplProvider());
context.subscriptions.push(new ReplProvider(serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory)));

// Enable indentAction
// tslint:disable-next-line:no-non-null-assertion
Expand Down Expand Up @@ -130,7 +132,7 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerHoverProvider(PYTHON, new PythonHoverProvider(jediFactory)));
context.subscriptions.push(vscode.languages.registerReferenceProvider(PYTHON, new PythonReferenceProvider(jediFactory)));
context.subscriptions.push(vscode.languages.registerCompletionItemProvider(PYTHON, new PythonCompletionItemProvider(jediFactory), '.'));
context.subscriptions.push(vscode.languages.registerCodeLensProvider(PYTHON, new ShebangCodeLensProvider()));
context.subscriptions.push(vscode.languages.registerCodeLensProvider(PYTHON, new ShebangCodeLensProvider(processService)));

const symbolProvider = new PythonSymbolProvider(jediFactory);
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(PYTHON, symbolProvider));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import { commands, ConfigurationTarget, Disposable, QuickPickItem, QuickPickOptions, Uri, window, workspace } from 'vscode';
import { InterpreterManager } from '../';
import * as settings from '../../common/configSettings';
import { IProcessService } from '../../common/process/types';
import { IInterpreterVersionService, PythonInterpreter, WorkspacePythonPath } from '../contracts';
import { ShebangCodeLensProvider } from '../display/shebangCodeLensProvider';
import { PythonPathUpdaterService } from './pythonPathUpdaterService';
Expand All @@ -15,7 +16,9 @@ interface PythonPathQuickPickItem extends QuickPickItem {
export class SetInterpreterProvider implements Disposable {
private disposables: Disposable[] = [];
private pythonPathUpdaterService: PythonPathUpdaterService;
constructor(private interpreterManager: InterpreterManager, interpreterVersionService: IInterpreterVersionService) {
constructor(private interpreterManager: InterpreterManager,
interpreterVersionService: IInterpreterVersionService,
private processService: IProcessService) {
this.disposables.push(commands.registerCommand('python.setInterpreter', this.setInterpreter.bind(this)));
this.disposables.push(commands.registerCommand('python.setShebangInterpreter', this.setShebangInterpreter.bind(this)));
this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), interpreterVersionService);
Expand Down Expand Up @@ -88,7 +91,7 @@ export class SetInterpreterProvider implements Disposable {
}

private async setShebangInterpreter(): Promise<void> {
const shebang = await ShebangCodeLensProvider.detectShebang(window.activeTextEditor!.document);
const shebang = await new ShebangCodeLensProvider(this.processService).detectShebang(window.activeTextEditor!.document);
if (!shebang) {
return;
}
Expand Down
14 changes: 6 additions & 8 deletions src/client/interpreter/display/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import * as child_process from 'child_process';
import { EOL } from 'os';
import * as path from 'path';
import { Disposable, StatusBarItem, Uri } from 'vscode';
import { PythonSettings } from '../../common/configSettings';
import { IProcessService } from '../../common/process/types';
import * as utils from '../../common/utils';
import { IInterpreterLocatorService, IInterpreterVersionService } from '../contracts';
import { getActiveWorkspaceUri, getFirstNonEmptyLineFromMultilineString } from '../helpers';
import { getActiveWorkspaceUri } from '../helpers';
import { IVirtualEnvironmentManager } from '../virtualEnvs/types';

// tslint:disable-next-line:completed-docs
export class InterpreterDisplay implements Disposable {
constructor(private statusBar: StatusBarItem,
private interpreterLocator: IInterpreterLocatorService,
private virtualEnvMgr: IVirtualEnvironmentManager,
private versionProvider: IInterpreterVersionService) {
private versionProvider: IInterpreterVersionService,
private processService: IProcessService) {

this.statusBar.command = 'python.setInterpreter';
}
Expand Down Expand Up @@ -69,11 +70,8 @@ export class InterpreterDisplay implements Disposable {
.then(env => env ? env.name : '');
}
private async getFullyQualifiedPathToInterpreter(pythonPath: string) {
return new Promise<string>(resolve => {
child_process.execFile(pythonPath, ['-c', 'import sys;print(sys.executable)'], (_, stdout) => {
resolve(getFirstNonEmptyLineFromMultilineString(stdout));
});
})
return this.processService.exec(pythonPath, ['-c', 'import sys;print(sys.executable)'])
.then(output => output.stdout.trim())
.then(value => value.length === 0 ? pythonPath : value)
.catch(() => pythonPath);
}
Expand Down
52 changes: 20 additions & 32 deletions src/client/interpreter/display/shebangCodeLensProvider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
'use strict';
import * as child_process from 'child_process';
import * as vscode from 'vscode';
import { CancellationToken, CodeLens, TextDocument } from 'vscode';
import * as settings from '../../common/configSettings';
import { IProcessService } from '../../common/process/types';
import { IS_WINDOWS } from '../../common/utils';
import { getFirstNonEmptyLineFromMultilineString } from '../../interpreter/helpers';

export class ShebangCodeLensProvider implements vscode.CodeLensProvider {
// tslint:disable-next-line:prefer-type-cast no-any
// tslint:disable-next-line:no-any
public onDidChangeCodeLenses: vscode.Event<void> = vscode.workspace.onDidChangeConfiguration as any as vscode.Event<void>;
// tslint:disable-next-line:function-name
public static async detectShebang(document: TextDocument): Promise<string | undefined> {
constructor(private processService: IProcessService) { }
public async detectShebang(document: TextDocument): Promise<string | undefined> {
const firstLine = document.lineAt(0);
if (firstLine.isEmptyOrWhitespace) {
return;
Expand All @@ -21,40 +19,30 @@ export class ShebangCodeLensProvider implements vscode.CodeLensProvider {
}

const shebang = firstLine.text.substr(2).trim();
const pythonPath = await ShebangCodeLensProvider.getFullyQualifiedPathToInterpreter(shebang);
const pythonPath = await this.getFullyQualifiedPathToInterpreter(shebang);
return typeof pythonPath === 'string' && pythonPath.length > 0 ? pythonPath : undefined;
}
private static async getFullyQualifiedPathToInterpreter(pythonPath: string) {
if (pythonPath.indexOf('bin/env ') >= 0 && !IS_WINDOWS) {
// In case we have pythonPath as '/usr/bin/env python'
return new Promise<string>(resolve => {
const command = child_process.exec(`${pythonPath} -c 'import sys;print(sys.executable)'`);
let result = '';
command.stdout.on('data', (data) => {
result += data.toString();
});
command.on('close', () => {
resolve(getFirstNonEmptyLineFromMultilineString(result));
});
});
} else {
return new Promise<string>(resolve => {
child_process.execFile(pythonPath, ['-c', 'import sys;print(sys.executable)'], (_, stdout) => {
resolve(getFirstNonEmptyLineFromMultilineString(stdout));
});
});
}
}

public async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
const codeLenses = await this.createShebangCodeLens(document);
return Promise.resolve(codeLenses);
}

private async getFullyQualifiedPathToInterpreter(pythonPath: string) {
let cmdFile = pythonPath;
let args = ['-c', 'import sys;print(sys.executable)'];
if (pythonPath.indexOf('bin/env ') >= 0 && !IS_WINDOWS) {
// In case we have pythonPath as '/usr/bin/env python'.
const parts = pythonPath.split(' ').map(part => part.trim()).filter(part => part.length > 0);
cmdFile = parts.shift()!;
args = parts.concat(args);
}
return this.processService.exec(cmdFile, args)
.then(output => output.stdout.trim())
.catch(() => '');
}
private async createShebangCodeLens(document: TextDocument) {
const shebang = await ShebangCodeLensProvider.detectShebang(document);
const shebang = await this.detectShebang(document);
const pythonPath = settings.PythonSettings.getInstance(document.uri).pythonPath;
const resolvedPythonPath = await ShebangCodeLensProvider.getFullyQualifiedPathToInterpreter(pythonPath);
const resolvedPythonPath = await this.getFullyQualifiedPathToInterpreter(pythonPath);
if (!shebang || shebang === resolvedPythonPath) {
return [];
}
Expand Down
4 changes: 3 additions & 1 deletion src/client/interpreter/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as path from 'path';
import { ConfigurationTarget, Disposable, StatusBarAlignment, Uri, window, workspace } from 'vscode';
import { PythonSettings } from '../common/configSettings';
import { IProcessService } from '../common/process/types';
import { IServiceContainer } from '../ioc/types';
import { PythonPathUpdaterService } from './configuration/pythonPathUpdaterService';
import { PythonPathUpdaterServiceFactory } from './configuration/pythonPathUpdaterServiceFactory';
Expand All @@ -21,7 +22,8 @@ export class InterpreterManager implements Disposable {
const statusBar = window.createStatusBarItem(StatusBarAlignment.Left);
this.interpreterProvider = serviceContainer.get<PythonInterpreterLocatorService>(IInterpreterLocatorService, INTERPRETER_LOCATOR_SERVICE);
const versionService = serviceContainer.get<IInterpreterVersionService>(IInterpreterVersionService);
this.display = new InterpreterDisplay(statusBar, this.interpreterProvider, virtualEnvMgr, versionService);
const processService = serviceContainer.get<IProcessService>(IProcessService);
this.display = new InterpreterDisplay(statusBar, this.interpreterProvider, virtualEnvMgr, versionService, processService);
this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), versionService);
PythonSettings.getInstance().addListener('change', () => this.onConfigChanged());
this.disposables.push(window.onDidChangeActiveTextEditor(() => this.refresh()));
Expand Down
47 changes: 20 additions & 27 deletions src/client/interpreter/locators/services/condaEnvService.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as child_process from 'child_process';
import * as fs from 'fs-extra';
import { inject, injectable } from 'inversify';
import * as path from 'path';
import { Uri } from 'vscode';
import { IProcessService } from '../../../common/process/types';
import { VersionUtils } from '../../../common/versionUtils';
import { ICondaLocatorService, IInterpreterLocatorService, IInterpreterVersionService, InterpreterType, PythonInterpreter } from '../../contracts';
import { AnacondaCompanyName, AnacondaCompanyNames, CONDA_RELATIVE_PY_PATH, CondaInfo } from './conda';
Expand All @@ -12,7 +12,8 @@ import { CondaHelper } from './condaHelper';
export class CondaEnvService implements IInterpreterLocatorService {
private readonly condaHelper = new CondaHelper();
constructor( @inject(ICondaLocatorService) private condaLocator: ICondaLocatorService,
@inject(IInterpreterVersionService) private versionService: IInterpreterVersionService) {
@inject(IInterpreterVersionService) private versionService: IInterpreterVersionService,
@inject(IProcessService) private processService: IProcessService) {
}
public async getInterpreters(resource?: Uri) {
return this.getSuggestionsFromConda();
Expand Down Expand Up @@ -99,32 +100,24 @@ export class CondaEnvService implements IInterpreterLocatorService {
}
private async getSuggestionsFromConda(): Promise<PythonInterpreter[]> {
return this.condaLocator.getCondaFile()
.then(async condaFile => {
return new Promise<PythonInterpreter[]>((resolve, reject) => {
// interrogate conda (if it's on the path) to find all environments.
child_process.execFile(condaFile, ['info', '--json'], (_, stdout) => {
if (stdout.length === 0) {
resolve([]);
return;
}
.then(condaFile => this.processService.exec(condaFile, ['info', '--json']))
.then(output => output.stdout)
.then(stdout => {
if (stdout.length === 0) {
return [];
}

try {
// tslint:disable-next-line:prefer-type-cast
const info = JSON.parse(stdout) as CondaInfo;
resolve(this.parseCondaInfo(info));
} catch (e) {
// Failed because either:
// 1. conda is not installed.
// 2. `conda info --json` has changed signature.
// 3. output of `conda info --json` has changed in structure.
// In all cases, we can't offer conda pythonPath suggestions.
resolve([]);
}
});
}).catch((err) => {
console.error('Python Extension (getSuggestionsFromConda):', err);
try {
const info = JSON.parse(stdout) as CondaInfo;
return this.parseCondaInfo(info);
} catch {
// Failed because either:
// 1. conda is not installed.
// 2. `conda info --json` has changed signature.
// 3. output of `conda info --json` has changed in structure.
// In all cases, we can't offer conda pythonPath suggestions.
return [];
});
});
}
}).catch(() => []);
}
}
13 changes: 3 additions & 10 deletions src/client/interpreter/locators/services/condaLocator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as child_process from 'child_process';
import * as fs from 'fs-extra';
import { inject, injectable, named, optional } from 'inversify';
import * as path from 'path';
Expand Down Expand Up @@ -70,15 +69,9 @@ export class CondaLocatorService implements ICondaLocatorService {
}
}
public async isCondaInCurrentPath() {
return new Promise<boolean>((resolve, reject) => {
child_process.execFile('conda', ['--version'], (_, stdout) => {
if (stdout && stdout.length > 0) {
resolve(true);
} else {
resolve(false);
}
});
});
return this.processService.exec('conda', ['--version'])
.then(output => output.stdout.length > 0)
.catch(() => false);
}
private async getCondaFileFromKnownLocations(): Promise<string> {
const condaFiles = await Promise.all(KNOWN_CONDA_LOCATIONS
Expand Down
Loading