Skip to content

Commit 3c70767

Browse files
committed
switch new project add to create method
1 parent 5eaf48e commit 3c70767

5 files changed

Lines changed: 63 additions & 81 deletions

File tree

src/api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,8 @@ export interface PythonProjectCreator {
702702
readonly iconPath?: IconPath;
703703

704704
/**
705-
* Creates a new Python project or projects.
705+
* Creates a new Python project or projects. The create method is required to add the created project if successful to the
706+
* list of projects.
706707
* @param options - Optional parameters for creating the Python project.
707708
* @returns A promise that resolves to a Python project, an array of Python projects, or undefined.
708709
*/

src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { PythonEnvironmentManagers } from './features/envManagers';
44
import { registerLogger, traceError, traceInfo } from './common/logging';
55
import { EnvManagerView } from './features/views/envManagersView';
66
import {
7-
addPythonProject,
7+
addPythonProjectCommand,
88
createEnvironmentCommand,
99
createTerminalCommand,
1010
getPackageCommandOptions,
@@ -164,7 +164,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
164164
await setPackageManagerCommand(envManagers, projectManager);
165165
}),
166166
commands.registerCommand('python-envs.addPythonProject', async (resource) => {
167-
await addPythonProject(resource, projectManager, envManagers, projectCreators);
167+
await addPythonProjectCommand(resource, projectManager, envManagers, projectCreators);
168168
}),
169169
commands.registerCommand('python-envs.removePythonProject', async (item) => {
170170
await resetEnvironmentCommand(item, envManagers, projectManager);

src/features/envCommands.ts

Lines changed: 40 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,10 @@ import {
1313
PythonEnvironmentApi,
1414
PythonProject,
1515
PythonProjectCreator,
16+
PythonProjectCreatorOptions,
1617
} from '../api';
17-
import * as path from 'path';
18-
import {
19-
setEnvironmentManager,
20-
setPackageManager,
21-
addPythonProjectSetting,
22-
removePythonProjectSetting,
23-
getDefaultEnvManagerSetting,
24-
getDefaultPkgManagerSetting,
25-
EditProjectSettings,
26-
} from './settings/settingHelpers';
27-
28-
import { getAbsolutePath } from '../common/utils/fileNameUtils';
18+
import { setEnvironmentManager, setPackageManager, removePythonProjectSetting } from './settings/settingHelpers';
19+
2920
import { runAsTask } from './execution/runAsTask';
3021
import {
3122
EnvManagerTreeItem,
@@ -338,84 +329,58 @@ export async function setPackageManagerCommand(em: EnvironmentManagers, wm: Pyth
338329
}
339330
}
340331

341-
export async function addPythonProject(
332+
/**
333+
* Creates a new Python project using a selected PythonProjectCreator.
334+
*
335+
* This function calls create on the selected creator and handles the creation process. Will return
336+
* without doing anything if the resource is a ProjectItem, as the project is already created.
337+
*
338+
* @param resource - The resource to use for project creation (can be a Uri, ProjectItem, or undefined).
339+
* @param wm - The PythonProjectManager instance for managing projects.
340+
* @param em - The EnvironmentManagers instance for managing environments.
341+
* @param pc - The ProjectCreators instance for accessing available project creators.
342+
* @returns A promise that resolves when the project has been created, or void if cancelled or invalid.
343+
*/
344+
export async function addPythonProjectCommand(
342345
resource: unknown,
343346
wm: PythonProjectManager,
344347
em: EnvironmentManagers,
345348
pc: ProjectCreators,
346-
): Promise<PythonProject | PythonProject[] | undefined> {
349+
): Promise<void> {
347350
if (wm.getProjects().length === 0) {
348351
showErrorMessage('Please open a folder/project before adding a workspace');
349352
return;
350353
}
354+
if (resource instanceof ProjectItem) {
355+
// If the context is a ProjectItem, project is already created.
356+
return;
357+
}
358+
let options: PythonProjectCreatorOptions | undefined;
351359

352360
if (resource instanceof Uri) {
353-
const uri = resource as Uri;
354-
const envManagerId = getDefaultEnvManagerSetting(wm, uri);
355-
const pkgManagerId = getDefaultPkgManagerSetting(
356-
wm,
357-
uri,
358-
em.getEnvironmentManager(envManagerId)?.preferredPackageManagerId,
359-
);
360-
const pw = wm.create(path.basename(uri.fsPath), uri);
361-
await addPythonProjectSetting([{ project: pw, envManager: envManagerId, packageManager: pkgManagerId }]);
362-
return pw;
361+
// Use resource as the URI for the project if it is a URI.
362+
options = {
363+
name: resource.fsPath,
364+
uri: resource,
365+
};
363366
}
364367

365-
if (resource === undefined || resource instanceof ProjectItem) {
366-
const creator: PythonProjectCreator | undefined = await pickCreator(pc.getProjectCreators());
367-
if (!creator) {
368-
return;
369-
}
370-
371-
let results: PythonProject | PythonProject[] | undefined;
372-
try {
373-
results = await creator.create();
374-
if (results === undefined) {
375-
return;
376-
}
377-
} catch (ex) {
378-
if (ex === QuickInputButtons.Back) {
379-
return addPythonProject(resource, wm, em, pc);
380-
}
381-
throw ex;
382-
}
368+
const creator: PythonProjectCreator | undefined = await pickCreator(pc.getProjectCreators());
369+
if (!creator) {
370+
return;
371+
}
383372

384-
if (!Array.isArray(results)) {
385-
results = [results];
373+
let results: PythonProject | PythonProject[] | undefined;
374+
try {
375+
results = await creator.create(options);
376+
if (results === undefined) {
377+
return;
386378
}
387-
388-
if (Array.isArray(results)) {
389-
if (results.length === 0) {
390-
return;
391-
}
379+
} catch (ex) {
380+
if (ex === QuickInputButtons.Back) {
381+
return addPythonProjectCommand(resource, wm, em, pc);
392382
}
393-
394-
const projects: PythonProject[] = [];
395-
const edits: EditProjectSettings[] = [];
396-
397-
for (const result of results) {
398-
const uri = await getAbsolutePath(result.uri.fsPath);
399-
if (!uri) {
400-
traceError(`Path does not belong to any opened workspace: ${result.uri.fsPath}`);
401-
continue;
402-
}
403-
404-
const envManagerId = getDefaultEnvManagerSetting(wm, uri);
405-
const pkgManagerId = getDefaultPkgManagerSetting(
406-
wm,
407-
uri,
408-
em.getEnvironmentManager(envManagerId)?.preferredPackageManagerId,
409-
);
410-
const pw = wm.create(path.basename(uri.fsPath), uri);
411-
projects.push(pw);
412-
edits.push({ project: pw, envManager: envManagerId, packageManager: pkgManagerId });
413-
}
414-
await addPythonProjectSetting(edits);
415-
return projects;
416-
} else {
417-
// If the context is not a Uri or ProjectItem, rerun function with undefined context
418-
await addPythonProject(undefined, wm, em, pc);
383+
throw ex;
419384
}
420385
}
421386

src/features/projectManager.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import {
99
onDidChangeWorkspaceFolders,
1010
} from '../common/workspace.apis';
1111
import { createSimpleDebounce } from '../common/utils/debounce';
12+
import {
13+
addPythonProjectSetting,
14+
EditProjectSettings,
15+
getDefaultEnvManagerSetting,
16+
getDefaultPkgManagerSetting,
17+
} from './settings/settingHelpers';
1218

1319
type ProjectArray = PythonProject[];
1420

@@ -92,14 +98,24 @@ export class PythonProjectManagerImpl implements PythonProjectManager {
9298
return new PythonProjectsImpl(name, uri, options);
9399
}
94100

95-
add(projects: PythonProject | ProjectArray): void {
101+
async add(projects: PythonProject | ProjectArray): Promise<void> {
96102
const _projects = Array.isArray(projects) ? projects : [projects];
97103
if (_projects.length === 0) {
98104
return;
99105
}
106+
const edits: EditProjectSettings[] = [];
107+
108+
const envManagerId = getDefaultEnvManagerSetting(this);
109+
const pkgManagerId = getDefaultPkgManagerSetting(this);
100110

101-
_projects.forEach((w) => this._projects.set(w.uri.toString(), w));
111+
_projects.forEach((w) => {
112+
edits.push({ project: w, envManager: envManagerId, packageManager: pkgManagerId });
113+
return this._projects.set(w.uri.toString(), w);
114+
});
102115
this._onDidChangeProjects.fire(Array.from(this._projects.values()));
116+
117+
// handle bulk edits to avoid multiple calls to the setting
118+
await addPythonProjectSetting(edits);
103119
}
104120

105121
remove(projects: PythonProject | ProjectArray): void {

src/internal.api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export interface PythonProjectManager extends Disposable {
284284
uri: Uri,
285285
options?: { description?: string; tooltip?: string | MarkdownString; iconPath?: IconPath },
286286
): PythonProject;
287-
add(pyWorkspace: PythonProject | PythonProject[]): void;
287+
add(pyWorkspace: PythonProject | PythonProject[]): Promise<void>;
288288
remove(pyWorkspace: PythonProject | PythonProject[]): void;
289289
getProjects(uris?: Uri[]): ReadonlyArray<PythonProject>;
290290
get(uri: Uri): PythonProject | undefined;

0 commit comments

Comments
 (0)