Files
spring-tools/vscode-extensions/vscode-spring-cli/src/command.ts

201 lines
6.0 KiB
TypeScript

import { QuickPickItem, Uri, WorkspaceFolder, window, workspace } from "vscode";
import { enterText } from "./utils";
import { CLI } from "./extension";
import { homedir } from "os";
import { CommandInfo } from "./cli-types";
import { CANCELLED } from "./cli";
interface SubCommandQuickPickItem extends QuickPickItem {
info?: CommandInfo;
}
interface ChoiceQuickPickItem extends QuickPickItem {
value: string;
}
const GLOBAL: QuickPickItem = {
label: "GLOBAL",
description: "Globally available for all user projects",
detail: homedir()
};
const LOCAL_SCOPE_DESCRIPTION = "Available only within selected workspace folder"
export async function handleCommandAdd(uri?: Uri) {
// Enter CWD for CLI (global vs workspace folder local command)
const cwd = await enterCwd(uri);
// Enter URL of the repo for the command to add
let url;
try {
url = await enterText({
title: "URL",
prompt: "Enter Repository URL",
placeholder: "https://github.com/my-org/my-command",
validate: async v => {
try {
Uri.parse(v, true);
} catch (error) {
return "Invalid URL value";
}
}
});
} catch (error) {
// Cancelled - ignore the error
}
if (url) {
CLI.commandAdd({url}, cwd);
}
}
export async function handleCommandRemove(uri?: Uri) {
try {
// Enter CWD for CLI (global vs workspace folder local command)
const cwd = await enterCwd(uri);
// Select the command
const command = await pickCommand(cwd);
if (!command) {
return;
}
// Select the subcommand
const subcommand = (await pickSubCommand(cwd, command))?.label;
if (!subcommand) {
return;
}
return CLI.commandRemove({
command,
subcommand,
cwd
});
} catch (error) {
if (error !== CANCELLED) {
window.showErrorMessage(error);
}
}
}
export async function handleCommandNew(uri?: Uri) {
const cwd = await enterCwd(uri);
const cmdName = await enterText({
prompt: "Enter Command Name",
title: "Command Name",
defaultValue: "hello"
});
if (!cmdName) {
return;
}
const subCmdName = await enterText({
prompt: "Enter Sub-Command Name",
title: "Sub-Command Name",
defaultValue: "new"
});
if (!subCmdName) {
return;
}
return CLI.commandNew(cwd, cmdName, subCmdName);
}
export async function handleCommandExecute(uri?: Uri) {
// Enter CWD for CLI (global vs workspace folder local command)
const cwd = await enterCwd(uri);
if (!cwd) {
window.showErrorMessage("No folder available for a user-defined command");
return;
}
// Select the command
const command = await pickCommand(cwd);
if (!command) {
return;
}
// Select the subcommand
const subcommand = (await pickSubCommand(cwd, command));
if (!subcommand) {
return;
}
const params = {};
try {
if (Array.isArray(subcommand?.info?.options)) {
for (const o of subcommand.info.options) {
let value;
if (o.choices) {
const quickPickItems = Object.keys(o.choices).map(s => ({
label: s,
value: o.choices[s]
}) as ChoiceQuickPickItem);
value = (await window.showQuickPick(quickPickItems, { canPickMany: false, ignoreFocusOut: true })).value;
} else {
value = await enterText({
title: o.paramLabel || o.name,
defaultValue: o.defaultValue,
placeholder: o.defaultValue,
prompt: `Enter ${o.paramLabel || o.name}${o.description ? " - " : ""}${o.description}`
});
}
if (value) {
params[o.name] = value;
}
}
}
return CLI.commandExecute({
command,
subcommand: subcommand.label,
params
}, cwd);
} catch (error) {
if (error !== CANCELLED) {
window.showErrorMessage(error);
}
}
}
function mapFolderToQuickPickItem(folder: WorkspaceFolder): QuickPickItem {
return {
label: folder.name,
description: LOCAL_SCOPE_DESCRIPTION,
detail: folder.uri.fsPath
};
}
async function enterCwd(uri?: Uri): Promise<string> {
const commandScopes = [ /*GLOBAL*/ ];
if (uri) {
const folder = workspace.getWorkspaceFolder(uri);
if (folder) {
commandScopes.push(mapFolderToQuickPickItem(folder));
}
} else {
commandScopes.push(...workspace.workspaceFolders.map(mapFolderToQuickPickItem));
}
if (commandScopes.length) {
return commandScopes.length > 1 ? (await window.showQuickPick(commandScopes, { canPickMany: false, ignoreFocusOut: true }))?.detail : commandScopes[0].detail;
}
}
async function pickCommand(cwd: string): Promise<string> {
return await window.showQuickPick(CLI.commandList(cwd), { canPickMany: false, ignoreFocusOut: true});
}
async function pickSubCommand(cwd: string, command: string): Promise<SubCommandQuickPickItem> {
const deferredItems = CLI.commandList(cwd, command).then(async subcommands => {
return await Promise.all(subcommands.map(async sc => {
const qp: SubCommandQuickPickItem = {
label: sc,
};
try {
qp.info = await CLI.commandInfo(cwd, command, sc);
qp.description = qp.info.description;
} catch (error) {
window.showWarningMessage(`Could not fetch info for CLI command: '${command} ${sc}'`);
}
return qp;
}));
});
return await window.showQuickPick(deferredItems, {canPickMany: false, ignoreFocusOut: true});
}