wasm-micro-runtime/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts
Wang Ning 679a8ab3cb
Perfect the codebase for wamr-ide (#1817)
Fix errors and warnings reported by eslint
Add CONTRIBUTING document for vscode-extension
2022-12-27 15:04:36 +08:00

261 lines
9.1 KiB
TypeScript

/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import {
createDirectory,
copyFiles,
checkFolderName,
} from '../utilities/directoryUtilities';
import { getUri } from '../utilities/getUri';
export class NewProjectPanel {
public static userSetWorkSpace: string;
public static currentPanel: NewProjectPanel | undefined;
private readonly viewPanel: vscode.WebviewPanel;
private disposableArr: vscode.Disposable[] = [];
private static readonly executionSuccess = 0;
private static readonly dirExistedError = -1;
private static readonly userInputError = -2;
private static readonly dirPathInvalidError = -3;
constructor(extensionUri: vscode.Uri, panel: vscode.WebviewPanel) {
this.viewPanel = panel;
this.viewPanel.webview.html = this.getHtmlForWebview(
this.viewPanel.webview,
extensionUri,
'resource/webview/page/newProject.html'
);
this._setWebviewMessageListener(this.viewPanel.webview, extensionUri);
this.viewPanel.onDidDispose(this.dispose, null, this.disposableArr);
}
public static render(context: vscode.ExtensionContext): void {
NewProjectPanel.userSetWorkSpace = vscode.workspace
.getConfiguration()
.get('WAMR-IDE.configWorkspace') as string;
/* check if current panel is initialized */
if (NewProjectPanel.currentPanel) {
NewProjectPanel.currentPanel.viewPanel.reveal(
vscode.ViewColumn.One
);
} else {
const panel = vscode.window.createWebviewPanel(
'newProject',
'Create project',
vscode.ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true,
}
);
NewProjectPanel.currentPanel = new NewProjectPanel(
context.extensionUri,
panel
);
}
}
private createNewProject(
projName: string,
template: string,
extensionUri: vscode.Uri
): number {
if (projName === '' || template === '') {
return NewProjectPanel.userInputError;
}
if (!checkFolderName(projName)) {
return NewProjectPanel.dirPathInvalidError;
}
const ROOT_PATH = path.join(NewProjectPanel.userSetWorkSpace, projName);
const EXT_PATH = extensionUri.fsPath;
if (fs.existsSync(ROOT_PATH)) {
if (fs.lstatSync(ROOT_PATH).isDirectory()) {
return NewProjectPanel.dirExistedError;
}
}
createDirectory(path.join(ROOT_PATH, '.wamr'));
createDirectory(path.join(ROOT_PATH, 'include'));
createDirectory(path.join(ROOT_PATH, 'src'));
copyFiles(
path.join(EXT_PATH, 'resource/scripts/CMakeLists.txt'),
path.join(ROOT_PATH, '.wamr/CMakeLists.txt')
);
copyFiles(
path.join(EXT_PATH, 'resource/scripts/project.cmake'),
path.join(ROOT_PATH, '.wamr/project.cmake')
);
return NewProjectPanel.executionSuccess;
}
public getHtmlForWebview(
webview: vscode.Webview,
extensionUri: vscode.Uri,
templatePath: string
): string {
const toolkitUri = getUri(webview, extensionUri, [
'node_modules',
'@vscode',
'webview-ui-toolkit',
'dist',
'toolkit.js',
]);
const styleUri = getUri(webview, extensionUri, [
'resource',
'webview',
'css',
'style.css',
]);
const mainUri = getUri(webview, extensionUri, [
'resource',
'webview',
'js',
'newproj.js',
]);
const resourcePath = path.join(extensionUri.fsPath, templatePath);
let html = fs.readFileSync(resourcePath, 'utf-8');
html = html
.replace(/(\${toolkitUri})/, toolkitUri.toString())
.replace(/(\${mainUri})/, mainUri.toString())
.replace(/(\${styleUri})/, styleUri.toString());
return html;
}
private _setWebviewMessageListener(
webview: vscode.Webview,
extensionUri: vscode.Uri
) {
webview.onDidReceiveMessage(
message => {
switch (message.command) {
case 'create_new_project':
const createNewProjectStatus = this.createNewProject(
message.projectName,
message.template,
extensionUri
);
if (
createNewProjectStatus ===
NewProjectPanel.executionSuccess
) {
webview.postMessage({
command: 'proj_creation_finish',
prjName: message.projectName,
});
} else if (
createNewProjectStatus ===
NewProjectPanel.dirExistedError
) {
vscode.window.showErrorMessage(
'Project : ' +
message.projectName +
' exists in your current root path, please change project name or root path!'
);
return;
} else if (
createNewProjectStatus ===
NewProjectPanel.userInputError
) {
vscode.window.showErrorMessage(
'Please fill chart before your submit!'
);
return;
} else if (
createNewProjectStatus ===
NewProjectPanel.dirPathInvalidError
) {
if (os.platform() === 'win32') {
vscode.window.showErrorMessage(
"A file name can't contain any of the following characters: ' / \\ : * ? < > | ' and the length should be less than 255"
);
} else if (
os.platform() === 'linux' ||
os.platform() === 'darwin'
) {
vscode.window.showErrorMessage(
"A file name can't contain following characters: '/' and the length should be less than 255"
);
}
return;
}
return;
case 'open_project':
vscode.window.showInformationMessage(
'Project : ' +
message.projectName +
' will be opened!'
);
const projPath = path.join(
NewProjectPanel.userSetWorkSpace,
message.projectName
);
const uri = vscode.Uri.file(projPath);
/**
* check if the vscode workspace folder is empty,
* if yes, open new window, else open in current window
*/
const isWorkspaceEmpty = !vscode.workspace
.workspaceFolders?.[0]
? true
: false;
isWorkspaceEmpty === false
? vscode.commands.executeCommand(
'vscode.openFolder',
uri,
{
forceNewWindow: true,
}
)
: vscode.commands.executeCommand(
'vscode.openFolder',
uri
);
case 'close_webview':
this.viewPanel.dispose();
return;
default:
break;
}
},
undefined,
this.disposableArr
);
}
private dispose() {
NewProjectPanel.currentPanel = undefined;
this.viewPanel.dispose();
while (this.disposableArr.length) {
const disposable = this.disposableArr.pop();
if (disposable) {
disposable.dispose();
}
}
}
}