Skip to content

Commit

Permalink
Add option to control if environment is selected after creation.
Browse files Browse the repository at this point in the history
  • Loading branch information
karthiknadig committed Feb 23, 2023
1 parent fc72be9 commit 756aeb5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 23 deletions.
15 changes: 10 additions & 5 deletions src/client/pythonEnvironments/creation/createEnvApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import { IInterpreterQuickPick } from '../../interpreter/configuration/types';
import { getCreationEvents, handleCreateEnvironmentCommand } from './createEnvironment';
import { condaCreationProvider } from './provider/condaCreationProvider';
import { VenvCreationProvider } from './provider/venvCreationProvider';
import { CreateEnvironmentOptions, CreateEnvironmentProvider, CreateEnvironmentResult } from './types';
import {
CreateEnvironmentExitedEventArgs,
CreateEnvironmentOptions,
CreateEnvironmentProvider,
CreateEnvironmentResult,
} from './types';
import { showInformationMessage } from '../../common/vscodeApis/windowApis';
import { CreateEnv } from '../../common/utils/localize';

Expand Down Expand Up @@ -62,10 +67,10 @@ export function registerCreateEnvironmentFeatures(
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} ${pathUtils.getDisplayName(e.path)}`);
onCreateEnvironmentExited(async (e: CreateEnvironmentExitedEventArgs) => {
if (e.result?.path && e.options?.selectEnvironment) {
await interpreterPathService.update(e.result.uri, ConfigurationTarget.WorkspaceFolder, e.result.path);
showInformationMessage(`${CreateEnv.informEnvCreation} ${pathUtils.getDisplayName(e.result.path)}`);
}
}),
);
Expand Down
52 changes: 34 additions & 18 deletions src/client/pythonEnvironments/creation/createEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,36 @@ import {
showQuickPickWithBack,
} from '../../common/vscodeApis/windowApis';
import { traceError, traceVerbose } from '../../logging';
import { CreateEnvironmentOptions, CreateEnvironmentProvider, CreateEnvironmentResult } from './types';
import {
CreateEnvironmentExitedEventArgs,
CreateEnvironmentOptions,
CreateEnvironmentProvider,
CreateEnvironmentResult,
CreateEnvironmentStartedEventArgs,
} from './types';

const onCreateEnvironmentStartedEvent = new EventEmitter<void>();
const onCreateEnvironmentExitedEvent = new EventEmitter<CreateEnvironmentResult | undefined>();
const onCreateEnvironmentStartedEvent = new EventEmitter<CreateEnvironmentStartedEventArgs>();
const onCreateEnvironmentExitedEvent = new EventEmitter<CreateEnvironmentExitedEventArgs>();

let startedEventCount = 0;

function isBusyCreatingEnvironment(): boolean {
return startedEventCount > 0;
}

function fireStartedEvent(): void {
onCreateEnvironmentStartedEvent.fire();
function fireStartedEvent(options?: CreateEnvironmentOptions): void {
onCreateEnvironmentStartedEvent.fire({ options });
startedEventCount += 1;
}

function fireExitedEvent(result: CreateEnvironmentResult | undefined): void {
onCreateEnvironmentExitedEvent.fire(result);
function fireExitedEvent(result?: CreateEnvironmentResult, options?: CreateEnvironmentOptions, error?: unknown): void {
onCreateEnvironmentExitedEvent.fire({ result, options, error });
startedEventCount -= 1;
}

export function getCreationEvents(): {
onCreateEnvironmentStarted: Event<void>;
onCreateEnvironmentExited: Event<CreateEnvironmentResult | undefined>;
onCreateEnvironmentStarted: Event<CreateEnvironmentStartedEventArgs>;
onCreateEnvironmentExited: Event<CreateEnvironmentExitedEventArgs>;
isCreatingEnvironment: () => boolean;
} {
return {
Expand All @@ -45,14 +51,12 @@ export function getCreationEvents(): {

async function createEnvironment(
provider: CreateEnvironmentProvider,
options: CreateEnvironmentOptions = {
ignoreSourceControl: true,
installPackages: true,
},
options: CreateEnvironmentOptions,
): Promise<CreateEnvironmentResult | undefined> {
let result: CreateEnvironmentResult | undefined;
let err: unknown | undefined;
try {
fireStartedEvent();
fireStartedEvent(options);
result = await provider.createEnvironment(options);
} catch (ex) {
if (ex === QuickInputButtons.Back) {
Expand All @@ -61,9 +65,10 @@ async function createEnvironment(
return undefined;
}
}
throw ex;
err = ex;
throw err;
} finally {
fireExitedEvent(result);
fireExitedEvent(result, options, err);
}
return result;
}
Expand Down Expand Up @@ -110,17 +115,28 @@ async function showCreateEnvironmentQuickPick(
return undefined;
}

function getOptionsWithDefaults(options?: CreateEnvironmentOptions): CreateEnvironmentOptions {
return {
installPackages: true,
ignoreSourceControl: true,
showBackButton: false,
selectEnvironment: true,
...options,
};
}

export async function handleCreateEnvironmentCommand(
providers: readonly CreateEnvironmentProvider[],
options?: CreateEnvironmentOptions,
): Promise<CreateEnvironmentResult | undefined> {
const optionsWithDefaults = getOptionsWithDefaults(options);
let selectedProvider: CreateEnvironmentProvider | undefined;
const envTypeStep = new MultiStepNode(
undefined,
async (context?: MultiStepAction) => {
if (providers.length > 0) {
try {
selectedProvider = await showCreateEnvironmentQuickPick(providers, options);
selectedProvider = await showCreateEnvironmentQuickPick(providers, optionsWithDefaults);
} catch (ex) {
if (ex === MultiStepAction.Back || ex === MultiStepAction.Cancel) {
return ex;
Expand Down Expand Up @@ -152,7 +168,7 @@ export async function handleCreateEnvironmentCommand(
}
if (selectedProvider) {
try {
result = await createEnvironment(selectedProvider, options);
result = await createEnvironment(selectedProvider, optionsWithDefaults);
} catch (ex) {
if (ex === MultiStepAction.Back || ex === MultiStepAction.Cancel) {
return ex;
Expand Down
19 changes: 19 additions & 0 deletions src/client/pythonEnvironments/creation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ import { Progress, Uri } from 'vscode';
export interface CreateEnvironmentProgress extends Progress<{ message?: string; increment?: number }> {}

export interface CreateEnvironmentOptions {
// Default `true`. If `true`, the environment creation handler is expected to install packages.
installPackages?: boolean;

// Default `true`. If `true`, the environment creation provider is expected to add the environment to ignore list
// for the source control.
ignoreSourceControl?: boolean;

// Default `false`. If `true` the creation provider should show back button when showing QuickPick or QuickInput.
showBackButton?: boolean;

// Default `true`. If `true`, the environment will be selected as the environment to be used for the workspace.
selectEnvironment?: boolean;
}

export interface CreateEnvironmentResult {
Expand All @@ -17,6 +26,16 @@ export interface CreateEnvironmentResult {
action?: 'Back' | 'Cancel';
}

export interface CreateEnvironmentStartedEventArgs {
options: CreateEnvironmentOptions | undefined;
}

export interface CreateEnvironmentExitedEventArgs {
result: CreateEnvironmentResult | undefined;
error?: unknown;
options: CreateEnvironmentOptions | undefined;
}

export interface CreateEnvironmentProvider {
createEnvironment(options?: CreateEnvironmentOptions): Promise<CreateEnvironmentResult | undefined>;
name: string;
Expand Down

0 comments on commit 756aeb5

Please sign in to comment.