Skip to content
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

Fix bugs found during TPI #19925

Merged
merged 8 commits into from
Oct 3, 2022
Merged
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
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