Add Archify | New Model… with three C4 examples and Open Model in the Explorer menu
- templates/models: C4 - Standard Web App, C4 - E-Shop, C4 - Event-Based Integration; each a complete model (main.archify, registry, context, containers, components) that validates - archify.newModel: pick an example and a folder name, copy it, name the model after the folder, open the model page - Explorer menu: New Model… on folders, Open Model on .archify and .archify-registry files; File → New File… lists New Model… - unit test validates every example end to end; integration test runs the command; README, CHANGELOG, docs/model.md
This commit is contained in:
@@ -1,7 +1,21 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { MODEL_EXAMPLES, mainFromExample } from '../language/examples';
|
||||
import { diagramName, invalidNameReason } from '../language/templates';
|
||||
import { MAIN_FILE } from '../model/format';
|
||||
import { readText } from '../util/files';
|
||||
import { DIAGRAM_EDITOR_VIEW_TYPE } from '../views/diagramView';
|
||||
import { CommandContext, targetUri } from './context';
|
||||
import { CommandContext, exists, targetUri } from './context';
|
||||
|
||||
/** Folder the new model folder goes into: the clicked folder (or a file's folder), else a workspace folder. */
|
||||
async function parentFolder(arg?: unknown): Promise<vscode.Uri | undefined> {
|
||||
if (arg instanceof vscode.Uri) {
|
||||
const stat = await vscode.workspace.fs.stat(arg);
|
||||
return stat.type & vscode.FileType.Directory ? arg : vscode.Uri.joinPath(arg, '..');
|
||||
}
|
||||
const folders = vscode.workspace.workspaceFolders ?? [];
|
||||
if (folders.length <= 1) return folders[0]?.uri;
|
||||
return (await vscode.window.showWorkspaceFolderPick({ placeHolder: 'Folder for the new model' }))?.uri;
|
||||
}
|
||||
|
||||
export function modelCommands(ctx: CommandContext): vscode.Disposable[] {
|
||||
return [
|
||||
@@ -15,5 +29,42 @@ export function modelCommands(ctx: CommandContext): vscode.Disposable[] {
|
||||
}
|
||||
await vscode.commands.executeCommand('vscode.openWith', vscode.Uri.joinPath(root, MAIN_FILE), DIAGRAM_EDITOR_VIEW_TYPE, vscode.ViewColumn.Active);
|
||||
}),
|
||||
|
||||
// Creates a new model folder from one of the shipped examples and opens its model page.
|
||||
vscode.commands.registerCommand('archify.newModel', async (arg?: unknown) => {
|
||||
const picked = await vscode.window.showQuickPick(
|
||||
MODEL_EXAMPLES.map((example) => ({ label: example.label, description: example.description, example })),
|
||||
{ title: 'Archify | New Model', placeHolder: 'Example to start from' },
|
||||
);
|
||||
if (!picked) return;
|
||||
const { example } = picked;
|
||||
|
||||
let parent = await parentFolder(arg);
|
||||
if (!parent) {
|
||||
const chosen = await vscode.window.showOpenDialog({ title: 'Archify | New Model', canSelectFiles: false, canSelectFolders: true, openLabel: 'Create model here' });
|
||||
parent = chosen?.[0];
|
||||
if (!parent) return;
|
||||
}
|
||||
const name = await vscode.window.showInputBox({
|
||||
title: 'Archify | New Model',
|
||||
prompt: `Folder name in ${vscode.workspace.asRelativePath(parent, true)}`,
|
||||
value: example.folder,
|
||||
validateInput: async (value) =>
|
||||
invalidNameReason(value) ?? ((await exists(vscode.Uri.joinPath(parent, diagramName(value)))) ? `${diagramName(value)} already exists.` : undefined),
|
||||
});
|
||||
if (name === undefined) return;
|
||||
const folderName = diagramName(name);
|
||||
const target = vscode.Uri.joinPath(parent, folderName);
|
||||
if (await exists(target)) {
|
||||
vscode.window.showWarningMessage(`Archify: ${vscode.workspace.asRelativePath(target, true)} already exists.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const source = vscode.Uri.joinPath(ctx.extension.extensionUri, 'templates', 'models', example.folder);
|
||||
await vscode.workspace.fs.copy(source, target, { overwrite: false });
|
||||
const main = vscode.Uri.joinPath(target, MAIN_FILE);
|
||||
await vscode.workspace.fs.writeFile(main, Buffer.from(mainFromExample(await readText(main), folderName, example), 'utf8'));
|
||||
await vscode.commands.executeCommand('vscode.openWith', main, DIAGRAM_EDITOR_VIEW_TYPE);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user