From 96d39633eed5c2dba286b48e99e83ebad48b7187 Mon Sep 17 00:00:00 2001 From: aboyko Date: Wed, 17 Jan 2024 19:25:27 -0500 Subject: [PATCH] [vscode-spring-cli] missing piece --- .../src/boot-project/boot-project.ts | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 vscode-extensions/vscode-spring-cli/src/boot-project/boot-project.ts diff --git a/vscode-extensions/vscode-spring-cli/src/boot-project/boot-project.ts b/vscode-extensions/vscode-spring-cli/src/boot-project/boot-project.ts new file mode 100644 index 000000000..8d8f8bdf6 --- /dev/null +++ b/vscode-extensions/vscode-spring-cli/src/boot-project/boot-project.ts @@ -0,0 +1,113 @@ +import * as path from "path"; +import { BootAddMetadata, BootNewMetadata, ProjectType } from "../cli/types"; +import { CLI } from "../extension"; +import { enterText, getTargetPomXml, openDialogForFolder } from "../utils"; +import vscode, { QuickPickItem, QuickPickItemKind } from 'vscode'; +import fs from 'fs' + +const OPEN_IN_NEW_WORKSPACE = "Open"; +const OPEN_IN_CURRENT_WORKSPACE = "Add to Workspace"; + +export async function handleAdd(pom?: vscode.Uri): Promise { + const metadata: BootAddMetadata = {}; + pom = pom || await getTargetPomXml(); + if (pom) { + metadata.targetFolder = path.dirname(pom.fsPath); + } + if (!metadata.targetFolder) { + vscode.window.showErrorMessage("Spring-CLI Boot Add command requires a target project"); + return; + } + if (!metadata.catalogType) { + metadata.catalogType = (await vscode.window.showQuickPick(CLI.getProjectTypes().map(mapProjectTypetoQuickPick), { canPickMany: false }))?.label; + } + return CLI.bootAdd(metadata); +} + +export async function handleNew(targetFolder?: string): Promise { + const metadata: BootNewMetadata = {}; + + // Select parent folder + metadata.targetFolder = targetFolder || (await openDialogForFolder({title: "Select Parent Folder"})).fsPath; + + // Select project type from the list of available types + metadata.catalogType = (await vscode.window.showQuickPick(CLI.getProjectTypes().map(mapProjectTypetoQuickPick), { canPickMany: false }))?.label; + + metadata.name = await enterText({ + title: "Project Name", + prompt: "Enter Project Name", + defaultValue: metadata.name || metadata.catalogType, + validate: value => { + if (!/^[a-z_][a-z0-9_]*(-[a-z_][a-z0-9_]*)*$/.test(value)) { + return "Invalid Project Name"; + } + if (fs.existsSync(path.resolve(metadata.targetFolder, value))) { + return "Folder or file with such name exists under selected parent folder"; + } + } + }); + + metadata.artifactId = await enterText({ + title: "Artifact Id", + prompt: "Enter Artifact Id", + defaultValue: metadata.name, + validate: value => (/^[a-z_][a-z0-9_]*(-[a-z_][a-z0-9_]*)*$/.test(value)) ? undefined : "Invalid Artifact Id" + }); + + metadata.groupId = await enterText({ + title: "Group Id", + prompt: "Enter Group Id", + defaultValue: "com.example", + validate: value => (/^[a-z_][a-z0-9_]*(\.[a-z0-9_]+)*$/.test(value)) ? undefined : "Invalid Group Id" + }); + + // Root package name + metadata.rootPackage = await enterText({ + title: "Root Package Name", + prompt: "Enter Root Package Name", + defaultValue: `${metadata.groupId}.${metadata.name.replace("-", ".")}`, + validate: value => (/^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$/.test(value)) ? undefined : "Invalid Package Name" + }); + + // Create project and open in the workspace or new window + if (metadata.name && metadata.catalogType && metadata.targetFolder) { + await CLI.bootNew(metadata); + + // Open project either is the same workspace or new workspace + const hasOpenFolder = vscode.workspace.workspaceFolders !== undefined || vscode.workspace.rootPath !== undefined; + + const pathToOpen = path.resolve(metadata.targetFolder, metadata.name); + + // Don't prompt to open projectLocation if it's already a currently opened folder + if (hasOpenFolder && (vscode.workspace.workspaceFolders.some(folder => folder.uri.fsPath === pathToOpen) || vscode.workspace.rootPath === pathToOpen)) { + return; + } + const choice = await specifyOpenMethod(hasOpenFolder, vscode.Uri.file(pathToOpen)) + + if (choice === OPEN_IN_NEW_WORKSPACE) { + vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(pathToOpen), hasOpenFolder); + } else if (choice === OPEN_IN_CURRENT_WORKSPACE) { + if (!vscode.workspace.workspaceFolders.find((workspaceFolder) => workspaceFolder.uri && pathToOpen.startsWith(workspaceFolder.uri.fsPath))) { + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders.length, null, { uri: vscode.Uri.file(pathToOpen) }); + } + } + } + +} + +function mapProjectTypetoQuickPick(metadata: ProjectType): QuickPickItem { + return { + label: metadata.id, + kind: QuickPickItemKind.Default, + description: metadata.description, + detail: metadata.tags.toString() + }; +} + +async function specifyOpenMethod(hasOpenFolder: boolean, projectLocation: vscode.Uri): Promise { + const candidates: string[] = [ + OPEN_IN_NEW_WORKSPACE, + hasOpenFolder ? OPEN_IN_CURRENT_WORKSPACE : undefined, + ].filter(Boolean); + return await vscode.window.showInformationMessage(`Successfully generated. Location: ${projectLocation.fsPath}`, ...candidates); +}