Skip to content

Commit

Permalink
Fix bugs found during TPI (microsoft#19925)
Browse files Browse the repository at this point in the history
  • Loading branch information
karthiknadig authored and eleanorjboyd committed Oct 4, 2022
1 parent fc4b0d5 commit 51d80fe
Show file tree
Hide file tree
Showing 23 changed files with 891 additions and 529 deletions.
11 changes: 7 additions & 4 deletions pythonFiles/create_conda.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def install_packages(env_path: str) -> None:
],
"CREATE_CONDA.FAILED_INSTALL_YML",
)
print("CREATE_CONDA.INSTALLED_YML")


def add_gitignore(name: str) -> None:
Expand All @@ -100,7 +101,10 @@ def main(argv: Optional[Sequence[str]] = None) -> None:
argv = []
args = parse_args(argv)

if not conda_env_exists(args.name):
if conda_env_exists(args.name):
env_path = get_conda_env_path(args.name)
print(f"EXISTING_CONDA_ENV:{env_path}")
else:
run_process(
[
sys.executable,
Expand All @@ -114,12 +118,11 @@ def main(argv: Optional[Sequence[str]] = None) -> None:
],
"CREATE_CONDA.ENV_FAILED_CREATION",
)
env_path = get_conda_env_path(args.name)
print(f"CREATED_CONDA_ENV:{env_path}")
if args.git_ignore:
add_gitignore(args.name)

env_path = get_conda_env_path(args.name)
print(f"CREATED_CONDA_ENV:{env_path}")

if args.install:
install_packages(env_path)

Expand Down
38 changes: 22 additions & 16 deletions pythonFiles/create_venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def file_exists(path: Union[str, pathlib.PurePath]) -> bool:


def venv_exists(name: str) -> bool:
return os.path.exists(CWD / name)
return os.path.exists(CWD / name) and file_exists(get_venv_path(name))


def run_process(args: Sequence[str], error_message: str) -> None:
Expand All @@ -72,9 +72,6 @@ def get_venv_path(name: str) -> str:


def install_packages(venv_path: str) -> None:
if not is_installed("pip"):
raise VenvError("CREATE_VENV.PIP_NOT_FOUND")

requirements = os.fspath(CWD / "requirements.txt")
pyproject = os.fspath(CWD / "pyproject.toml")

Expand All @@ -89,12 +86,14 @@ def install_packages(venv_path: str) -> None:
[venv_path, "-m", "pip", "install", "-r", requirements],
"CREATE_VENV.PIP_FAILED_INSTALL_REQUIREMENTS",
)
print("CREATE_VENV.PIP_INSTALLED_REQUIREMENTS")
elif file_exists(pyproject):
print(f"VENV_INSTALLING_PYPROJECT: {pyproject}")
run_process(
[venv_path, "-m", "pip", "install", "-e", ".[extras]"],
"CREATE_VENV.PIP_FAILED_INSTALL_PYPROJECT",
)
print("CREATE_VENV.PIP_INSTALLED_PYPROJECT")


def add_gitignore(name: str) -> None:
Expand All @@ -110,20 +109,27 @@ def main(argv: Optional[Sequence[str]] = None) -> None:
argv = []
args = parse_args(argv)

if is_installed("venv"):
if not venv_exists(args.name):
run_process(
[sys.executable, "-m", "venv", args.name],
"CREATE_VENV.VENV_FAILED_CREATION",
)
if args.git_ignore:
add_gitignore(args.name)
if not is_installed("venv"):
raise VenvError("CREATE_VENV.VENV_NOT_FOUND")

if args.install and not is_installed("pip"):
raise VenvError("CREATE_VENV.PIP_NOT_FOUND")

if venv_exists(args.name):
venv_path = get_venv_path(args.name)
print(f"CREATED_VENV:{venv_path}")
if args.install:
install_packages(venv_path)
print(f"EXISTING_VENV:{venv_path}")
else:
raise VenvError("CREATE_VENV.VENV_NOT_FOUND")
run_process(
[sys.executable, "-m", "venv", args.name],
"CREATE_VENV.VENV_FAILED_CREATION",
)
venv_path = get_venv_path(args.name)
print(f"CREATED_VENV:{venv_path}")
if args.git_ignore:
add_gitignore(args.name)

if args.install:
install_packages(venv_path)


if __name__ == "__main__":
Expand Down
38 changes: 17 additions & 21 deletions src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,12 @@ export namespace SwitchToDefaultLS {
}

export namespace CreateEnv {
export const informEnvCreation = localize(
'createEnv.informEnvCreation',
'We have selected the following environment:',
);
export const statusTitle = localize('createEnv.statusTitle', 'Creating environment');
export const statusStarting = localize('createEnv.statusStarting', 'Starting...');
export const statusError = localize('createEnv.statusError', 'Error.');
export const statusDone = localize('createEnv.statusDone', 'Done.');

export const hasVirtualEnv = localize('createEnv.hasVirtualEnv', 'Workspace folder contains a virtual environment');

Expand All @@ -564,21 +566,23 @@ export namespace CreateEnv {
'Please open a directory when creating an environment using venv.',
);

export const pickWorkspaceTitle = localize(
'createEnv.workspaceQuickPick.title',
export const pickWorkspacePlaceholder = localize(
'createEnv.workspaceQuickPick.placeholder',
'Select a workspace to create environment',
);

export const providersQuickPickTitle = localize('createEnv.providersQuickPick.title', 'Select an environment type');
export const providersQuickPickPlaceholder = localize(
'createEnv.providersQuickPick.placeholder',
'Select an environment type',
);

export namespace Venv {
export const creating = localize('createEnv.venv.creating', 'Creating venv...');
export const created = localize('createEnv.venv.created', 'Environment created...');
export const installingPackages = localize('createEnv.venv.installingPackages', 'Installing packages...');
export const waitingForPython = localize('createEnv.venv.waitingForPython', 'Waiting on Python selection...');
export const waitingForWorkspace = localize(
'createEnv.venv.waitingForWorkspace',
'Waiting on workspace selection...',
export const errorCreatingEnvironment = localize(
'createEnv.venv.errorCreatingEnvironment',
'Error while creating virtual environment.',
);
export const selectPythonQuickPickTitle = localize(
'createEnv.venv.basePython.title',
Expand All @@ -588,6 +592,7 @@ export namespace CreateEnv {
'createEnv.venv.description',
'Creates a `.venv` virtual environment in the current workspace',
);
export const error = localize('createEnv.venv.error', 'Creating virtual environment failed with error.');
}

export namespace Conda {
Expand All @@ -601,20 +606,11 @@ export namespace CreateEnv {
'createEnv.conda.errorCreatingEnvironment',
'Error while creating conda environment.',
);
export const waitingForWorkspace = localize(
'createEnv.conda.waitingForWorkspace',
'Waiting on workspace selection...',
);
export const waitingForPython = localize(
'createEnv.conda.waitingForPython',
'Waiting on Python version selection...',
);
export const selectPythonQuickPickTitle = localize(
'createEnv.conda.pythonSelection.title',
export const selectPythonQuickPickPlaceholder = localize(
'createEnv.conda.pythonSelection.placeholder',
'Please select the version of Python to install in the environment',
);
export const searching = localize('createEnv.conda.searching', 'Searching for conda (base)...');
export const creating = localize('createEnv.venv.creating', 'Running conda create...');
export const creating = localize('createEnv.conda.creating', 'Creating conda environment...');
export const providerDescription = localize(
'createEnv.conda.description',
'Creates a `.conda` Conda environment in the current workspace',
Expand Down
17 changes: 17 additions & 0 deletions src/client/common/vscodeApis/windowApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ export function showErrorMessage<T>(message: string, ...items: any[]): Thenable<
return window.showErrorMessage(message, ...items);
}

export function showInformationMessage<T extends string>(message: string, ...items: T[]): Thenable<T | undefined>;
export function showInformationMessage<T extends string>(
message: string,
options: MessageOptions,
...items: T[]
): Thenable<T | undefined>;
export function showInformationMessage<T extends MessageItem>(message: string, ...items: T[]): Thenable<T | undefined>;
export function showInformationMessage<T extends MessageItem>(
message: string,
options: MessageOptions,
...items: T[]
): Thenable<T | undefined>;

export function showInformationMessage<T>(message: string, ...items: any[]): Thenable<T | undefined> {
return window.showInformationMessage(message, ...items);
}

export function withProgress<R>(
options: ProgressOptions,
task: (progress: Progress<{ message?: string; increment?: number }>, token: CancellationToken) => Thenable<R>,
Expand Down
15 changes: 12 additions & 3 deletions src/client/extensionActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ import { IApplicationEnvironment, ICommandManager, IWorkspaceService } from './c
import { Commands, PYTHON, PYTHON_LANGUAGE, STANDARD_OUTPUT_CHANNEL, UseProposedApi } from './common/constants';
import { registerTypes as installerRegisterTypes } from './common/installer/serviceRegistry';
import { IFileSystem } from './common/platform/types';
import { IConfigurationService, IDisposableRegistry, IExtensions, IOutputChannel } from './common/types';
import {
IConfigurationService,
IDisposableRegistry,
IExtensions,
IInterpreterPathService,
IOutputChannel,
} from './common/types';
import { noop } from './common/utils/misc';
import { DebuggerTypeName } from './debugger/constants';
import { registerTypes as debugConfigurationRegisterTypes } from './debugger/extension/serviceRegistry';
Expand Down Expand Up @@ -97,11 +103,14 @@ export async function activateComponents(
return Promise.all([legacyActivationResult, ...promises]);
}

export function activateFeatures(ext: ExtensionState, components: Components): void {
export function activateFeatures(ext: ExtensionState, _components: Components): void {
const interpreterQuickPick: IInterpreterQuickPick = ext.legacyIOC.serviceContainer.get<IInterpreterQuickPick>(
IInterpreterQuickPick,
);
registerCreateEnvironmentFeatures(ext.disposables, components.pythonEnvs, interpreterQuickPick);
const interpreterPathService: IInterpreterPathService = ext.legacyIOC.serviceContainer.get<IInterpreterPathService>(
IInterpreterPathService,
);
registerCreateEnvironmentFeatures(ext.disposables, interpreterQuickPick, interpreterPathService);
}

/// //////////////////////////
Expand Down
7 changes: 4 additions & 3 deletions src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { ConfigurationTarget, Disposable, Uri } from 'vscode';
import { IExtensionActivationService } from '../../activation/types';
import { IApplicationShell } from '../../common/application/types';
import { IDisposableRegistry, IPersistentStateFactory } from '../../common/types';
import { sleep } from '../../common/utils/async';
import { Common, Interpreters } from '../../common/utils/localize';
import { traceDecoratorError, traceVerbose } from '../../logging';
import { isCreatingEnvironment } from '../../pythonEnvironments/creation/createEnvApi';
import { PythonEnvironment } from '../../pythonEnvironments/info';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
Expand Down Expand Up @@ -38,8 +38,9 @@ export class VirtualEnvironmentPrompt implements IExtensionActivationService {

@traceDecoratorError('Error in event handler for detection of new environment')
protected async handleNewEnvironment(resource: Uri): Promise<void> {
// Wait for a while, to ensure environment gets created and is accessible (as this is slow on Windows)
await sleep(1000);
if (isCreatingEnvironment()) {
return;
}
const interpreters = await this.pyenvs.getWorkspaceVirtualEnvInterpreters(resource);
const interpreter =
Array.isArray(interpreters) && interpreters.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export async function pickWorkspaceFolder(
const selected = await showQuickPick(
getWorkspacesForQuickPick(workspaces),
{
title: CreateEnv.pickWorkspaceTitle,
placeHolder: CreateEnv.pickWorkspacePlaceholder,
ignoreFocusOut: true,
canPickMany: options?.allowMultiSelect,
},
Expand Down
27 changes: 19 additions & 8 deletions src/client/pythonEnvironments/creation/createEnvApi.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { Disposable } from 'vscode';
import { ConfigurationTarget, Disposable } from 'vscode';
import { Commands } from '../../common/constants';
import { IDisposableRegistry } from '../../common/types';
import { IDisposableRegistry, IInterpreterPathService } from '../../common/types';
import { registerCommand } from '../../common/vscodeApis/commandApis';
import { IInterpreterQuickPick } from '../../interpreter/configuration/types';
import { IDiscoveryAPI } from '../base/locator';
import { handleCreateEnvironmentCommand } from './createEnvQuickPick';
import { getCreationEvents, handleCreateEnvironmentCommand } from './createEnvironment';
import { condaCreationProvider } from './provider/condaCreationProvider';
import { VenvCreationProvider } from './provider/venvCreationProvider';
import { CreateEnvironmentOptions, CreateEnvironmentProvider } from './types';
import { CreateEnvironmentOptions, CreateEnvironmentProvider, CreateEnvironmentResult } from './types';
import { showInformationMessage } from '../../common/vscodeApis/windowApis';
import { CreateEnv } from '../../common/utils/localize';

class CreateEnvironmentProviders {
private _createEnvProviders: CreateEnvironmentProvider[] = [];
Expand Down Expand Up @@ -41,20 +42,30 @@ export function registerCreateEnvironmentProvider(provider: CreateEnvironmentPro
});
}

export const { onCreateEnvironmentStarted, onCreateEnvironmentExited, isCreatingEnvironment } = getCreationEvents();

export function registerCreateEnvironmentFeatures(
disposables: IDisposableRegistry,
discoveryApi: IDiscoveryAPI,
interpreterQuickPick: IInterpreterQuickPick,
interpreterPathService: IInterpreterPathService,
): void {
disposables.push(
registerCommand(
Commands.Create_Environment,
(options?: CreateEnvironmentOptions): Promise<string | undefined> => {
(options?: CreateEnvironmentOptions): Promise<CreateEnvironmentResult | undefined> => {
const providers = _createEnvironmentProviders.getAll();
return handleCreateEnvironmentCommand(providers, options);
},
),
);
disposables.push(registerCreateEnvironmentProvider(new VenvCreationProvider(discoveryApi, interpreterQuickPick)));
disposables.push(registerCreateEnvironmentProvider(new VenvCreationProvider(interpreterQuickPick)));
disposables.push(registerCreateEnvironmentProvider(condaCreationProvider()));
disposables.push(
onCreateEnvironmentExited(async (e: CreateEnvironmentResult | undefined) => {
if (e && e.path) {
await interpreterPathService.update(e.uri, ConfigurationTarget.WorkspaceFolder, e.path);
showInformationMessage(`${CreateEnv.informEnvCreation} ${e.path}`);
}
}),
);
}
54 changes: 0 additions & 54 deletions src/client/pythonEnvironments/creation/createEnvQuickPick.ts

This file was deleted.

Loading

0 comments on commit 51d80fe

Please sign in to comment.