Skip to content

switch new project add to create method #336

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
Show file tree
Hide file tree
Changes from 2 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
3 changes: 2 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,8 @@ export interface PythonProjectCreator {
readonly iconPath?: IconPath;

/**
* Creates a new Python project or projects.
* Creates a new Python project or projects. The create method is required to add the created project if successful to the
* list of projects.
* @param options - Optional parameters for creating the Python project.
* @returns A promise that resolves to a Python project, an array of Python projects, or undefined.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { PythonEnvironmentManagers } from './features/envManagers';
import { registerLogger, traceError, traceInfo } from './common/logging';
import { EnvManagerView } from './features/views/envManagersView';
import {
addPythonProject,
addPythonProjectCommand,
createEnvironmentCommand,
createTerminalCommand,
getPackageCommandOptions,
Expand Down Expand Up @@ -164,7 +164,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
await setPackageManagerCommand(envManagers, projectManager);
}),
commands.registerCommand('python-envs.addPythonProject', async (resource) => {
await addPythonProject(resource, projectManager, envManagers, projectCreators);
await addPythonProjectCommand(resource, projectManager, envManagers, projectCreators);
}),
commands.registerCommand('python-envs.removePythonProject', async (item) => {
await resetEnvironmentCommand(item, envManagers, projectManager);
Expand Down
116 changes: 41 additions & 75 deletions src/features/envCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,10 @@ import {
PythonEnvironmentApi,
PythonProject,
PythonProjectCreator,
PythonProjectCreatorOptions,
} from '../api';
import * as path from 'path';
import {
setEnvironmentManager,
setPackageManager,
addPythonProjectSetting,
removePythonProjectSetting,
getDefaultEnvManagerSetting,
getDefaultPkgManagerSetting,
EditProjectSettings,
} from './settings/settingHelpers';

import { getAbsolutePath } from '../common/utils/fileNameUtils';
import { setEnvironmentManager, setPackageManager, removePythonProjectSetting } from './settings/settingHelpers';

import { runAsTask } from './execution/runAsTask';
import {
EnvManagerTreeItem,
Expand Down Expand Up @@ -338,84 +329,59 @@ export async function setPackageManagerCommand(em: EnvironmentManagers, wm: Pyth
}
}

export async function addPythonProject(
/**
* Creates a new Python project using a selected PythonProjectCreator.
*
* This function calls create on the selected creator and handles the creation process. Will return
* without doing anything if the resource is a ProjectItem, as the project is already created.
*
* @param resource - The resource to use for project creation (can be a Uri, ProjectItem, or undefined).
* @param wm - The PythonProjectManager instance for managing projects.
* @param em - The EnvironmentManagers instance for managing environments.
* @param pc - The ProjectCreators instance for accessing available project creators.
* @returns A promise that resolves when the project has been created, or void if cancelled or invalid.
*/
export async function addPythonProjectCommand(
resource: unknown,
wm: PythonProjectManager,
em: EnvironmentManagers,
pc: ProjectCreators,
): Promise<PythonProject | PythonProject[] | undefined> {
): Promise<void> {
if (wm.getProjects().length === 0) {
showErrorMessage('Please open a folder/project before adding a workspace');
return;
}
if (resource instanceof ProjectItem) {
// If the context is a ProjectItem, project is already created. Just add it to the package manager project list.
wm.add(resource.project);
return;
}
let options: PythonProjectCreatorOptions | undefined;

if (resource instanceof Uri) {
const uri = resource as Uri;
const envManagerId = getDefaultEnvManagerSetting(wm, uri);
const pkgManagerId = getDefaultPkgManagerSetting(
wm,
uri,
em.getEnvironmentManager(envManagerId)?.preferredPackageManagerId,
);
const pw = wm.create(path.basename(uri.fsPath), uri);
await addPythonProjectSetting([{ project: pw, envManager: envManagerId, packageManager: pkgManagerId }]);
return pw;
// Use resource as the URI for the project if it is a URI.
options = {
name: resource.fsPath,
uri: resource,
};
}

if (resource === undefined || resource instanceof ProjectItem) {
const creator: PythonProjectCreator | undefined = await pickCreator(pc.getProjectCreators());
if (!creator) {
return;
}

let results: PythonProject | PythonProject[] | undefined;
try {
results = await creator.create();
if (results === undefined) {
return;
}
} catch (ex) {
if (ex === QuickInputButtons.Back) {
return addPythonProject(resource, wm, em, pc);
}
throw ex;
}
const creator: PythonProjectCreator | undefined = await pickCreator(pc.getProjectCreators());
if (!creator) {
return;
}

if (!Array.isArray(results)) {
results = [results];
let results: PythonProject | PythonProject[] | undefined;
try {
results = await creator.create(options);
if (results === undefined) {
return;
}

if (Array.isArray(results)) {
if (results.length === 0) {
return;
}
} catch (ex) {
if (ex === QuickInputButtons.Back) {
return addPythonProjectCommand(resource, wm, em, pc);
}

const projects: PythonProject[] = [];
const edits: EditProjectSettings[] = [];

for (const result of results) {
const uri = await getAbsolutePath(result.uri.fsPath);
if (!uri) {
traceError(`Path does not belong to any opened workspace: ${result.uri.fsPath}`);
continue;
}

const envManagerId = getDefaultEnvManagerSetting(wm, uri);
const pkgManagerId = getDefaultPkgManagerSetting(
wm,
uri,
em.getEnvironmentManager(envManagerId)?.preferredPackageManagerId,
);
const pw = wm.create(path.basename(uri.fsPath), uri);
projects.push(pw);
edits.push({ project: pw, envManager: envManagerId, packageManager: pkgManagerId });
}
await addPythonProjectSetting(edits);
return projects;
} else {
// If the context is not a Uri or ProjectItem, rerun function with undefined context
await addPythonProject(undefined, wm, em, pc);
throw ex;
}
}

Expand Down
20 changes: 18 additions & 2 deletions src/features/projectManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import {
onDidChangeWorkspaceFolders,
} from '../common/workspace.apis';
import { createSimpleDebounce } from '../common/utils/debounce';
import {
addPythonProjectSetting,
EditProjectSettings,
getDefaultEnvManagerSetting,
getDefaultPkgManagerSetting,
} from './settings/settingHelpers';

type ProjectArray = PythonProject[];

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

add(projects: PythonProject | ProjectArray): void {
async add(projects: PythonProject | ProjectArray): Promise<void> {
const _projects = Array.isArray(projects) ? projects : [projects];
if (_projects.length === 0) {
return;
}
const edits: EditProjectSettings[] = [];

const envManagerId = getDefaultEnvManagerSetting(this);
const pkgManagerId = getDefaultPkgManagerSetting(this);

_projects.forEach((w) => this._projects.set(w.uri.toString(), w));
_projects.forEach((w) => {
edits.push({ project: w, envManager: envManagerId, packageManager: pkgManagerId });
return this._projects.set(w.uri.toString(), w);
});
this._onDidChangeProjects.fire(Array.from(this._projects.values()));

// handle bulk edits to avoid multiple calls to the setting
await addPythonProjectSetting(edits);
}

remove(projects: PythonProject | ProjectArray): void {
Expand Down
2 changes: 1 addition & 1 deletion src/internal.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export interface PythonProjectManager extends Disposable {
uri: Uri,
options?: { description?: string; tooltip?: string | MarkdownString; iconPath?: IconPath },
): PythonProject;
add(pyWorkspace: PythonProject | PythonProject[]): void;
add(pyWorkspace: PythonProject | PythonProject[]): Promise<void>;
remove(pyWorkspace: PythonProject | PythonProject[]): void;
getProjects(uris?: Uri[]): ReadonlyArray<PythonProject>;
get(uri: Uri): PythonProject | undefined;
Expand Down