diff options
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src')
11 files changed, 2352 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/constants.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/constants.ts new file mode 100644 index 000000000..cf8bb7103 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/constants.ts @@ -0,0 +1,7 @@ +export const enum SelectionOfPrompt { + skip = 'skip', + setUp = 'setup', +} +export const enum Status { + done = 'done', +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/debugConfigurationProvider.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/debugConfigurationProvider.ts new file mode 100644 index 000000000..e7b42bf03 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/debugConfigurationProvider.ts @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import * as os from 'os'; + +export class WasmDebugConfigurationProvider + implements vscode.DebugConfigurationProvider { + private wasmDebugConfig = { + type: 'wamr-debug', + name: 'Attach', + request: 'attach', + stopOnEntry: true, + initCommands: os.platform() === 'win32' || os.platform() === 'darwin' ? + /* linux and windows has different debug configuration */ + ['platform select remote-linux'] : + undefined, + attachCommands: [ + /* default port 1234 */ + 'process connect -p wasm connect://127.0.0.1:1234', + ] + }; + + public resolveDebugConfiguration( + _: vscode.WorkspaceFolder | undefined, + debugConfiguration: vscode.DebugConfiguration, + ): vscode.ProviderResult<vscode.DebugConfiguration> { + + this.wasmDebugConfig = { + ...this.wasmDebugConfig, + ...debugConfiguration + }; + + return this.wasmDebugConfig; + } + + public getDebugConfig(): vscode.DebugConfiguration { + return this.wasmDebugConfig; + } +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts new file mode 100644 index 000000000..46efcc90c --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/decorationProvider.ts @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import { readFromFile } from './utilities/directoryUtilities'; +import * as path from 'path'; +import * as os from 'os'; + +const DECORATION_INCLUDE_PATHS: vscode.FileDecoration = + new vscode.FileDecoration( + '✔', + 'Included', + new vscode.ThemeColor('list.highlightForeground') + ); +const DECORATION_EXCLUDE_FILES: vscode.FileDecoration = + new vscode.FileDecoration( + '✗', + 'Excluded', + new vscode.ThemeColor('list.errorForeground') + ); + +export class DecorationProvider implements vscode.FileDecorationProvider { + private disposables: vscode.Disposable[] = []; + public onDidChangeFileDecorations: vscode.Event< + vscode.Uri | vscode.Uri[] | undefined + >; + private eventEmitter: vscode.EventEmitter<vscode.Uri | vscode.Uri[]>; + + constructor() { + this.eventEmitter = new vscode.EventEmitter(); + this.onDidChangeFileDecorations = this.eventEmitter.event; + this.disposables.push( + vscode.window.registerFileDecorationProvider(this) + ); + } + + public provideFileDecoration( + uri: vscode.Uri + ): vscode.ProviderResult<vscode.FileDecoration> { + const currentPrjDir = + os.platform() === 'win32' + ? (vscode.workspace.workspaceFolders?.[0].uri.fsPath as string) + : os.platform() === 'linux' || os.platform() === 'darwin' + ? (vscode.workspace.workspaceFolders?.[0].uri.path as string) + : ''; + + const pathRelative = (uri.fsPath ? uri.fsPath : uri.toString()).replace( + currentPrjDir, + '..' + ); + + const prjConfigDir = path.join(currentPrjDir, '.wamr'); + const configFilePath = path.join( + prjConfigDir, + 'compilation_config.json' + ); + if (readFromFile(configFilePath) !== '') { + const configData = JSON.parse(readFromFile(configFilePath)); + const includePathArr = configData['includePaths']; + const excludeFileArr = configData['excludeFiles']; + + if (includePathArr.indexOf(pathRelative) > -1) { + return DECORATION_INCLUDE_PATHS; + } else if (excludeFileArr.indexOf(pathRelative) > -1) { + return DECORATION_EXCLUDE_FILES; + } + } + } + + public dispose(): void { + this.disposables.forEach(d => d.dispose()); + } + + public updateDecorationsForSource(uri: vscode.Uri): void { + this.eventEmitter.fire(uri); + } +} + +export const decorationProvider: DecorationProvider = new DecorationProvider(); diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/extension.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/extension.ts new file mode 100644 index 000000000..523b26b83 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/extension.ts @@ -0,0 +1,1027 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as fileSystem from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import * as vscode from 'vscode'; + +import { WasmTaskProvider } from './taskProvider'; +import { TargetConfigPanel } from './view/TargetConfigPanel'; +import { NewProjectPanel } from './view/NewProjectPanel'; +import { + checkIfDirectoryExists, + writeIntoFile, + readFromFile, +} from './utilities/directoryUtilities'; +import { decorationProvider } from './decorationProvider'; +import { WasmDebugConfigurationProvider } from './debugConfigurationProvider'; +import { + isLLDBInstalled, + promptInstallLLDB, + getWAMRExtensionVersion, +} from './utilities/lldbUtilities'; + +import { + checkIfDockerStarted, + checkIfDockerImagesExist, + promptSetupDockerImages, +} from './utilities/dockerUtilities'; +import { SelectionOfPrompt } from './constants'; + +let wasmTaskProvider: WasmTaskProvider; +let wasmDebugConfigProvider: WasmDebugConfigurationProvider; +let currentPrjDir = ''; +let isWasmProject = false; + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export async function activate(context: vscode.ExtensionContext) { + const extensionPath = context.extensionPath; + const osPlatform = os.platform(); + const wamrVersion = getWAMRExtensionVersion(context); + const typeMap = new Map<string, string>(); + const scriptMap = new Map<string, string>(); + /* set relative path of build.bat|sh script */ + const scriptPrefix = 'resource/scripts/'; + + let buildScript = '', + runScript = '', + debugScript = '', + destroyScript = '', + buildScriptFullPath = '', + runScriptFullPath = '', + debugScriptFullPath = '', + destroyScriptFullPath = '', + /* include paths array used for written into config file */ + includePathArr = new Array<string>(), + /* exclude files array used for written into config file */ + excludeFileArr = new Array<string>(); + + /** + * Provide Build & Run Task with Task Provider instead of "tasks.json" + */ + + if (osPlatform === 'win32') { + buildScript = scriptPrefix.concat('build.bat'); + runScript = scriptPrefix.concat('run.bat'); + debugScript = scriptPrefix.concat('boot_debugger_server.bat'); + destroyScript = scriptPrefix.concat('destroy.bat'); + } else if (osPlatform === 'linux' || osPlatform === 'darwin') { + buildScript = scriptPrefix.concat('build.sh'); + runScript = scriptPrefix.concat('run.sh'); + debugScript = scriptPrefix.concat('boot_debugger_server.sh'); + destroyScript = scriptPrefix.concat('destroy.sh'); + } + + buildScriptFullPath = path.join(extensionPath, buildScript); + runScriptFullPath = path.join(extensionPath, runScript); + debugScriptFullPath = path.join(extensionPath, debugScript); + destroyScriptFullPath = path.join(extensionPath, destroyScript); + + scriptMap.set('buildScript', buildScriptFullPath); + scriptMap.set('runScript', runScriptFullPath); + scriptMap.set('debugScript', debugScriptFullPath); + scriptMap.set('destroyScript', destroyScriptFullPath); + + typeMap.set('Build', 'Build'); + typeMap.set('Run', 'Run'); + typeMap.set('Debug', 'Debug'); + typeMap.set('Destroy', 'Destroy'); + + wasmTaskProvider = new WasmTaskProvider(typeMap, scriptMap, wamrVersion); + + vscode.tasks.registerTaskProvider('wasm', wasmTaskProvider); + + if (vscode.workspace.workspaceFolders?.[0]) { + if (osPlatform === 'win32') { + currentPrjDir = vscode.workspace.workspaceFolders?.[0].uri + .fsPath as string; + } else if (osPlatform === 'linux' || osPlatform === 'darwin') { + currentPrjDir = vscode.workspace.workspaceFolders?.[0].uri + .path as string; + } + + /** + * check whether current project opened in vscode workspace is wasm project + * it not, `build`, `run` and `debug` will be disabled + */ + if (currentPrjDir !== '') { + const wamrFolder = fileSystem + .readdirSync(currentPrjDir, { + withFileTypes: true, + }) + .filter( + folder => folder.isDirectory() && folder.name === '.wamr' + ); + + if (wamrFolder.length !== 0) { + isWasmProject = true; + vscode.commands.executeCommand( + 'setContext', + 'ext.isWasmProject', + isWasmProject + ); + if ( + vscode.workspace + .getConfiguration() + .has('C_Cpp.default.systemIncludePath') + ) { + let newIncludeInCppArr: string[] | undefined | null; + + newIncludeInCppArr = vscode.workspace + .getConfiguration() + .get('C_Cpp.default.systemIncludePath'); + + const libcBuiltinHeaderPath = path.join( + extensionPath, + 'resource/wamr-sdk/libc-builtin-sysroot/include' + ); + + if (newIncludeInCppArr !== undefined) { + /* in case the configuration has not been set up, push directly */ + if (newIncludeInCppArr === null) { + newIncludeInCppArr = []; + newIncludeInCppArr.push(libcBuiltinHeaderPath); + } else { + /* if the configuration has been set up, check the condition */ + if ( + /* include libc-builtin-sysroot */ + newIncludeInCppArr.indexOf( + libcBuiltinHeaderPath + ) < 0 + ) { + newIncludeInCppArr.push(libcBuiltinHeaderPath); + } + } + + vscode.workspace + .getConfiguration() + .update( + 'C_Cpp.default.systemIncludePath', + newIncludeInCppArr, + vscode.ConfigurationTarget.Workspace + ); + } + } + } + } + } + + /* register debug configuration */ + wasmDebugConfigProvider = new WasmDebugConfigurationProvider(); + + vscode.debug.registerDebugConfigurationProvider( + 'wamr-debug', + wasmDebugConfigProvider + ); + + /* update ext.includePaths to show or hide 'Remove' button in menus */ + vscode.commands.executeCommand('setContext', 'ext.supportedFileType', [ + '.c', + '.cpp', + '.cxx', + ]); + + if (readFromConfigFile() !== '') { + const configData = JSON.parse(readFromConfigFile()); + includePathArr = configData['includePaths']; + excludeFileArr = configData['excludeFiles']; + + if (Object.keys(configData['buildArgs']).length !== 0) { + TargetConfigPanel.buildArgs = configData['buildArgs']; + } + } + + const disposableNewProj = vscode.commands.registerCommand( + 'wamride.newProject', + () => { + const okStr = 'Set up now'; + const cancelStr = 'Maybe later'; + const curWorkspace = vscode.workspace + .getConfiguration() + .get('WAMR-IDE.configWorkspace'); + + /* if user has not set up workspace yet, prompt to set up */ + if (curWorkspace === '' || curWorkspace === undefined) { + vscode.window + .showWarningMessage( + 'Please setup your workspace firstly.', + okStr, + cancelStr + ) + .then(item => { + if (item === okStr) { + vscode.commands.executeCommand( + 'wamride.changeWorkspace' + ); + } else { + return; + } + }); + } else if (!checkIfDirectoryExists(curWorkspace as string)) { + vscode.window + .showWarningMessage( + 'Invalid workspace:', + { + modal: true, + detail: + '' + + vscode.workspace + .getConfiguration() + .get('WAMR-IDE.configWorkspace') + + '', + }, + okStr + ) + .then(item => { + if (item === okStr) { + vscode.commands.executeCommand( + 'wamride.changeWorkspace' + ); + } else { + return; + } + }); + } else { + NewProjectPanel.render(context); + } + } + ); + + const disposableTargetConfig = vscode.commands.registerCommand( + 'wamride.targetConfig', + () => { + if (currentPrjDir !== '') { + TargetConfigPanel.render(context); + } else { + vscode.window.showWarningMessage( + 'Please create and open project firstly.', + 'OK' + ); + } + } + ); + + const disposableChangeWorkspace = vscode.commands.registerCommand( + 'wamride.changeWorkspace', + async () => { + const options: vscode.OpenDialogOptions = { + canSelectFiles: false, + canSelectFolders: true, + openLabel: 'Select Workspace', + }; + + const workSpace = await vscode.window + .showOpenDialog(options) + .then(res => { + if (res) { + return res[0].fsPath as string; + } else { + return ''; + } + }); + + /* update workspace value to vscode global settings */ + if (workSpace !== '' && workSpace !== undefined) { + await vscode.workspace + .getConfiguration() + .update( + 'WAMR-IDE.configWorkspace', + workSpace.trim(), + vscode.ConfigurationTarget.Global + ) + .then( + () => { + vscode.window.showInformationMessage( + 'Workspace has been set up successfully!' + ); + }, + () => { + vscode.window.showErrorMessage( + 'Set up Workspace failed!' + ); + } + ); + } + } + ); + + const disposableBuild = vscode.commands.registerCommand( + 'wamride.build', + async () => { + if (!isWasmProject) { + vscode.window.showErrorMessage('Build failed', { + modal: true, + detail: 'Current project is not wasm project, please open wasm project and try again.', + }); + return; + } + + try { + /* check if docker images are ready before building */ + if ( + (await checkIfDockerStarted()) && + !(await checkIfDockerImagesExist(context)) + ) { + /**NOTE - if users select to skip install, + * we should return rather than continue + * the execution + */ + if ( + (await promptSetupDockerImages(context)) === + SelectionOfPrompt.skip + ) { + return; + } + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + return; + } + + generateCMakeFile(includePathArr, excludeFileArr); + /* destroy the wasm-toolchain-ctr if it exists */ + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Destroy: Wasm-Container-Before-Build' + ) + .then(() => { + const disposable = vscode.tasks.onDidEndTaskProcess(t => { + if ( + t.execution.task.name === + 'Wasm-Container-Before-Build' + ) { + if (t.exitCode !== 0) { + disposable.dispose(); + return; + } + + /* execute the build task */ + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Build: Wasm' + ) + .then(() => { + /* destroy the wasm-toolchain-ctr after building */ + const disposableAft = + vscode.tasks.onDidEndTask(a => { + if ( + a.execution.task.name === + 'Wasm' && + a.execution.task.source === + 'Build' + ) { + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Destroy: Wasm-Container-After-Build' + ) + .then(() => { + /* dispose the event after this building process + */ + disposableAft.dispose(); + }); + } + }); + }); + /* dispose the event after this building process */ + disposable.dispose(); + } + }); + }); + } + ); + + const disposableDebug = vscode.commands.registerCommand( + 'wamride.debug', + async () => { + if (!isWasmProject) { + vscode.window.showErrorMessage('debug failed', { + modal: true, + detail: 'Current project is not wasm project, please open wasm project and try again.', + }); + return; + } + + /* we should check again whether the user installed lldb, as this can be skipped during activation */ + try { + if (!isLLDBInstalled(context)) { + /**NOTE - if users select to skip install, + * we should return rather than continue + * the execution + */ + if ( + (await promptInstallLLDB(context)) === + SelectionOfPrompt.skip + ) { + return; + } + } + + if ( + (await checkIfDockerStarted()) && + !(await checkIfDockerImagesExist(context)) + ) { + /**NOTE - save as above lldb, should return if + * users select to skip set up + */ + if ( + (await promptSetupDockerImages(context)) === + SelectionOfPrompt.skip + ) { + return; + } + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + return; + } + + /* refuse to debug if build process failed */ + if (!checkIfBuildSuccess()) { + vscode.window.showErrorMessage('Debug failed', { + modal: true, + detail: 'Can not find WASM binary, please build WASM firstly.', + }); + return; + } + + /* show debug view */ + vscode.commands.executeCommand('workbench.view.debug'); + + /* should destroy the wasm-debug-server-ctr before debugging */ + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Destroy: Wasm-Container-Before-Debug' + ) + .then(() => { + /* execute the debug task when destroy task finish */ + const disposableBfr = vscode.tasks.onDidEndTask(t => { + if ( + t.execution.task.name === + 'Wasm-Container-Before-Debug' + ) { + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Debug: Wasm' + ) + .then(() => { + vscode.debug + .startDebugging( + undefined, + wasmDebugConfigProvider.getDebugConfig() + ) + .then(() => { + /* register to listen debug session finish event */ + const disposableAft = + vscode.debug.onDidTerminateDebugSession( + s => { + if ( + s.type !== + 'wamr-debug' + ) { + return; + } + + /* execute the task to destroy + * wasm-debug-server-ctr */ + vscode.commands.executeCommand( + 'workbench.action.tasks.runTask', + 'Destroy: Wasm-Container-After-Debug' + ); + + /* execute the task to kill the terminal */ + vscode.commands.executeCommand( + 'workbench.action.terminal.kill', + 'Debug: Wasm' + ); + + disposableAft.dispose(); + } + ); + }); + }); + } + disposableBfr.dispose(); + }); + }); + } + ); + + const disposableRun = vscode.commands.registerCommand( + 'wamride.run', + async () => { + if (!isWasmProject) { + vscode.window.showErrorMessage('run failed', { + modal: true, + detail: 'Current project is not wasm project, please open wasm project and try again.', + }); + return; + } + + try { + /* check if docker images are set up before building */ + if ( + (await checkIfDockerStarted()) && + !(await checkIfDockerImagesExist(context)) + ) { + await promptSetupDockerImages(context); + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + return; + } + + /* refuse to debug if build process failed */ + if (!checkIfBuildSuccess()) { + vscode.window.showErrorMessage('Debug failed', { + modal: true, + detail: 'Can not find WASM binary, please build WASM firstly.', + }); + return; + } + + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Destroy: Wasm-Container-Before-Run' + ) + .then(() => { + const disposableAft = vscode.tasks.onDidEndTaskProcess( + e => { + if ( + e.execution.task.name === + 'Wasm-Container-Before-Run' + ) { + /* make sure that run wasm task will be executed when destroy task finish */ + vscode.commands + .executeCommand( + 'workbench.action.tasks.runTask', + 'Run: Wasm' + ) + .then(() => { + if (e.exitCode !== 0) { + disposableAft.dispose(); + return; + } + }); + disposableAft.dispose(); + } + } + ); + }); + } + ); + + const disposableToggleIncludePath = vscode.commands.registerCommand( + 'wamride.build.toggleStateIncludePath', + fileUri => { + const path = + fileUri._fsPath !== null && fileUri._fsPath !== undefined + ? fileUri._fsPath + : vscode.Uri.parse(fileUri.path as string).fsPath; + const pathRelative = path.replace(currentPrjDir, '..'); + + if (includePathArr.indexOf(pathRelative) > -1) { + /* this folder has been added to include path, remove it */ + includePathArr = includePathArr.filter(value => { + return value !== pathRelative; + }); + } else { + includePathArr.push(pathRelative); + } + + writeIntoConfigFile( + includePathArr, + excludeFileArr, + TargetConfigPanel.buildArgs + ); + + decorationProvider.updateDecorationsForSource(fileUri); + } + ); + + const disposableToggleExcludeFile = vscode.commands.registerCommand( + 'wamride.build.toggleStateExclude', + fileUri => { + const path = + fileUri._fsPath !== null && fileUri._fsPath !== undefined + ? fileUri._fsPath + : vscode.Uri.parse(fileUri.path as string).fsPath; + + /* replace the current project absolute path with .. to change to relative path */ + const pathRelative = path.replace(currentPrjDir, '..'); + + if (excludeFileArr.indexOf(pathRelative) > -1) { + excludeFileArr = excludeFileArr.filter(val => { + return val !== pathRelative; + }); + } else { + excludeFileArr.push(pathRelative); + } + + writeIntoConfigFile( + includePathArr, + excludeFileArr, + TargetConfigPanel.buildArgs + ); + + /* update decoration for this source file */ + decorationProvider.updateDecorationsForSource(fileUri); + } + ); + + const disposableOpenFolder = vscode.commands.registerCommand( + 'wamride.openFolder', + () => { + /* get projects list under current workspace */ + const okStr = 'Set up now'; + const cancelStr = 'Maybe later'; + const createStr = 'Create now'; + const curWorkspace = vscode.workspace + .getConfiguration() + .get('WAMR-IDE.configWorkspace') as string; + + /* if user has not set up workspace yet, prompt to set up */ + if (curWorkspace === '' || curWorkspace === undefined) { + vscode.window + .showWarningMessage( + 'Please setup your workspace firstly.', + okStr, + cancelStr + ) + .then(item => { + if (item === okStr) { + vscode.commands.executeCommand( + 'wamride.changeWorkspace' + ); + } else { + return; + } + }); + } else if (!checkIfDirectoryExists(curWorkspace as string)) { + vscode.window + .showWarningMessage( + 'Invalid workspace:', + { + modal: true, + detail: + '' + + vscode.workspace + .getConfiguration() + .get('WAMR-IDE.configWorkspace') + + '', + }, + okStr + ) + .then(item => { + if (item === okStr) { + vscode.commands.executeCommand( + 'wamride.changeWorkspace' + ); + } else { + return; + } + }); + } else { + /* get all directories within directory, ignore files */ + let directoryArrDirent, directoryArr; + try { + directoryArrDirent = fileSystem.readdirSync(curWorkspace, { + withFileTypes: true, + }); + } catch (err) { + vscode.window.showErrorMessage( + 'Read projects from current workspace failed.' + ); + } + + if (directoryArrDirent !== undefined) { + directoryArr = directoryArrDirent + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + const projFilesArr = directoryArr.filter(obj => { + if (checkIfWasmProj(path.join(curWorkspace, obj))) { + return true; + } + }); + + if (projFilesArr.length === 0) { + vscode.window + .showWarningMessage( + 'Current workspace is empty, please create your project firstly.', + createStr, + cancelStr + ) + .then(item => { + if (item === createStr) { + vscode.commands.executeCommand( + 'wamride.newProject' + ); + } else { + return; + } + }); + } else { + vscode.window + .showQuickPick(projFilesArr, { + title: 'Select project', + placeHolder: 'Please select project', + }) + .then(option => { + if (!option) { + return; + } + + const path = curWorkspace.concat( + osPlatform === 'win32' + ? '\\' + : osPlatform === 'linux' || + osPlatform === 'darwin' + ? '/' + : '', + option + ); + + /* open the selected wasm project */ + openWindowWithSituation(vscode.Uri.file(path)); + }); + } + } + } + } + ); + + context.subscriptions.push( + disposableNewProj, + disposableTargetConfig, + disposableChangeWorkspace, + disposableBuild, + disposableRun, + disposableToggleIncludePath, + disposableOpenFolder, + disposableToggleExcludeFile, + disposableDebug + ); + + try { + if (!isLLDBInstalled(context)) { + await promptInstallLLDB(context); + } + + if ( + (await checkIfDockerStarted()) && + !(await checkIfDockerImagesExist(context)) + ) { + await promptSetupDockerImages(context); + } + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + } +} + +function openWindowWithSituation(uri: vscode.Uri) { + /** + * check if the 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); + + return; +} + +interface BuildArgs { + outputFileName: string; + initMemorySize: string; + maxMemorySize: string; + stackSize: string; + exportedSymbols: string; +} + +/** + * @param: includePathArr + * @param: excludeFileArr + * Get current includePathArr and excludeFileArr from the json string that + * will be written into compilation_config.json + */ +export function writeIntoConfigFile( + includePathArr: string[], + excludeFileArr: string[], + buildArgs?: BuildArgs +): void { + const jsonStr = JSON.stringify( + { + includePaths: includePathArr, + excludeFiles: excludeFileArr, + buildArgs: buildArgs ? buildArgs : '{}', + }, + null, + '\t' + ); + + const prjConfigDir = path.join(currentPrjDir, '.wamr'); + const configFilePath = path.join(prjConfigDir, 'compilation_config.json'); + writeIntoFile(configFilePath, jsonStr); +} + +export function readFromConfigFile(): string { + const prjConfigDir = path.join(currentPrjDir, '.wamr'); + const configFilePath = path.join(prjConfigDir, 'compilation_config.json'); + return readFromFile(configFilePath); +} + +/** + * will be triggered when the user clicking `build` button + */ +function generateCMakeFile( + includePathArr: string[], + excludeFileArr: string[] +): void { + // -Wl,--export=${EXPORT_SYMBOLS} + const srcFilePath = path.join(currentPrjDir, 'src'); + const prjConfigDir = path.join(currentPrjDir, '.wamr'); + const cmakeFilePath = path.join(prjConfigDir, 'project.cmake'); + + let strIncludeList = 'set (PROJECT_INCLUDES'; + let strSrcList = 'set (PROJECT_SRC_LIST'; + + let strOutputFileName = 'set (OUTPUT_FILE_NAME'; + let strInitMemSize = 'set (INIT_MEM_SIZE'; + let strMaxMemSize = 'set (MAX_MEM_SIZE'; + let strStackSize = 'set (STACK_SIZE'; + let strExportedSymbols = 'set (EXPORTED_SYMBOLS'; + + let fullStr = ''; + let i, s, e: number; + + /* change the absolute path into relative path */ + const _re = currentPrjDir; + const _substr = '${CMAKE_CURRENT_SOURCE_DIR}/..'; + + /** + * set PROJECT_SRC_LIST + * default ADD every c OR c++ OR cpp under the src/ path + * except the files saved in the excludeFiles array + */ + + const srcPathArr = getAllSrcFiles(srcFilePath); + + if (srcPathArr === undefined) { + return; + } + + for (s = 0; s < srcPathArr.length; s++) { + if ( + excludeFileArr.indexOf( + srcPathArr[s].path.replace(currentPrjDir, '..') + ) === -1 + ) { + /* replace currentPrjDir with ${CMAKE_CURRENT_SOURCE_DIR} */ + const newStr = srcPathArr[s].path + .replace(_re, _substr) + .replace(/\\/g, '/'); + + strSrcList = strSrcList.concat(' ', newStr); + } + } + strSrcList = strSrcList.concat(' )'); + + for (i = 0; i < includePathArr.length; i++) { + const newStr = includePathArr[i] + .replace(/../, _substr) + .replace(/\\/g, '/'); + strIncludeList = strIncludeList.concat(' ', newStr); + } + strIncludeList = strIncludeList.concat(' )'); + + /* set up user customized input in configBuildArgs webview */ + strOutputFileName = strOutputFileName.concat( + ' ', + TargetConfigPanel.buildArgs.outputFileName + ')' + ); + + strInitMemSize = strInitMemSize.concat( + ' ', + TargetConfigPanel.buildArgs.initMemorySize + ')' + ); + + strMaxMemSize = strMaxMemSize.concat( + ' ', + TargetConfigPanel.buildArgs.maxMemorySize + ')' + ); + + strStackSize = strStackSize.concat( + ' ', + TargetConfigPanel.buildArgs.stackSize + ')' + ); + + const exportedSymbolArr = + TargetConfigPanel.buildArgs.exportedSymbols.split(','); + + strExportedSymbols = strExportedSymbols.concat(' "'); + + for (e = 0; e < exportedSymbolArr.length; e++) { + strExportedSymbols = strExportedSymbols.concat( + ' -Wl,', + '--export=', + exportedSymbolArr[e] + ); + } + + strExportedSymbols = strExportedSymbols.concat('")'); + + fullStr = strOutputFileName + .concat('\n', strInitMemSize) + .concat('\n', strMaxMemSize) + .concat('\n', strStackSize) + .concat('\n', strExportedSymbols) + .concat('\n', strSrcList) + .concat('\n', strIncludeList); + + writeIntoFile(cmakeFilePath, fullStr); +} + +function getAllSrcFiles(_path: string) { + try { + const entries = fileSystem.readdirSync(_path, { + withFileTypes: true, + }); + + const files = entries + .filter( + /* filter files mismatch .c |.cpp |.cxx */ + file => + !file.isDirectory() && file.name.match('(.c|.cpp|.cxx)$') + ) + .map(file => ({ + path: path.join(_path, file.name), + })); + + const folders = entries.filter(folder => folder.isDirectory()); + + for (const folder of folders) { + const fileArr = getAllSrcFiles(path.join(_path, folder.name)); + fileArr ? files.push(...fileArr) : ''; + } + + return files; + } catch (error) { + vscode.window.showErrorMessage(error as string); + } +} + +function checkIfBuildSuccess(): boolean { + try { + let wasmExist = false; + const entries = fileSystem.readdirSync( + path.join(currentPrjDir, 'build'), + { + withFileTypes: true, + } + ); + + entries.map(e => { + if (e.name.match('(.wasm)$')) { + wasmExist = true; + } + }); + + return wasmExist; + } catch { + return false; + } +} + +function checkIfWasmProj(path: string): boolean { + try { + let isWasmProj = false; + const entries = fileSystem.readdirSync(path, { + withFileTypes: true, + }); + + entries.map(e => { + if (e.isDirectory() && e.name === '.wamr') { + isWasmProj = true; + } + }); + + return isWasmProj; + } catch { + return false; + } +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/taskProvider.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/taskProvider.ts new file mode 100644 index 000000000..9b9b75f9a --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/taskProvider.ts @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import * as os from 'os'; +import { TargetConfigPanel } from './view/TargetConfigPanel'; + +export interface OwnShellOption { + cmd: string; + options: vscode.ShellExecutionOptions; +} + +export class WasmTaskProvider implements vscode.TaskProvider { + constructor( + public _type: Map<string, string>, + public _script: Map<string, string>, + public _wamrVersion: string + ) {} + + buildShellOption: OwnShellOption | undefined; + runShellOption: OwnShellOption | undefined; + debugShellOption: OwnShellOption | undefined; + destroyShellOption: OwnShellOption | undefined; + + private wasmPromise: Thenable<vscode.Task[]> | undefined = undefined; + + public provideTasks(): Thenable<vscode.Task[]> | undefined { + if (!this.wasmPromise) { + /* target name is used for generated aot target */ + const targetName = + TargetConfigPanel.buildArgs.outputFileName.split('.')[0]; + + if ( + os.platform() === 'linux' || + os.platform() === 'darwin' || + os.platform() === 'win32' + ) { + /* build */ + this.buildShellOption = { + cmd: + os.platform() === 'linux' || os.platform() === 'darwin' + ? 'bash' + : (this._script.get('buildScript') as string), + options: { + executable: this._script.get('buildScript'), + shellArgs: [targetName, this._wamrVersion], + }, + }; + + /* debug */ + this.debugShellOption = { + cmd: + os.platform() === 'linux' || os.platform() === 'darwin' + ? 'bash' + : (this._script.get('debugScript') as string), + options: { + executable: this._script.get('debugScript'), + shellArgs: [targetName, this._wamrVersion], + }, + }; + + /* run */ + this.runShellOption = { + cmd: + os.platform() === 'linux' || os.platform() === 'darwin' + ? 'bash' + : (this._script.get('runScript') as string), + options: { + executable: this._script.get('runScript'), + shellArgs: [targetName, this._wamrVersion], + }, + }; + + /* destroy */ + /* run */ + this.destroyShellOption = { + cmd: + os.platform() === 'linux' || os.platform() === 'darwin' + ? 'bash' + : (this._script.get('destroyScript') as string), + options: { + executable: this._script.get('destroyScript'), + shellArgs: [targetName], + }, + }; + } else { + this.buildShellOption = { + cmd: "echo 'os platform is not supported yet'", + options: {}, + }; + + this.debugShellOption = { + cmd: "echo 'os platform is not supported yet'", + options: {}, + }; + + this.runShellOption = { + cmd: "echo 'os platform is not supported yet'", + options: {}, + }; + + this.destroyShellOption = { + cmd: "echo 'os platform is not supported yet'", + options: {}, + }; + } + + this.wasmPromise = Promise.resolve([ + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm', + this._type.get('Build') as string, + new vscode.ShellExecution( + this.buildShellOption.cmd, + this.buildShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm', + this._type.get('Run') as string, + new vscode.ShellExecution( + this.runShellOption.cmd, + this.runShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm', + this._type.get('Debug') as string, + new vscode.ShellExecution( + this.debugShellOption.cmd, + this.debugShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-Before-Build', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-Before-Debug', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-Before-Run', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-After-Build', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-After-Debug', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + + new vscode.Task( + { type: 'wasm' }, + vscode.TaskScope.Workspace, + 'Wasm-Container-After-Run', + this._type.get('Destroy') as string, + new vscode.ShellExecution( + this.destroyShellOption.cmd, + this.destroyShellOption.options + ) + ), + ]); + } + + return this.wasmPromise; + } + + /** + * if the task or task in tasks.json does not set command, ` + * resolveTask` will be invoked, + * otherwise, `provideTasks` will be invoked + * @param _task + * @returns + */ + public resolveTask(task: vscode.Task): vscode.Task | undefined { + if (task) { + return task; + } + return undefined; + } +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts new file mode 100644 index 000000000..0efbea5d9 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/directoryUtilities.ts @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import fileSystem = require('fs'); +import vscode = require('vscode'); +import path = require('path'); +import os = require('os'); +import request = require('request'); +import yauzl = require('yauzl'); + +/** + * + * @param path destination path + */ +export function createDirectory( + dest: string, + mode: string | number | null | undefined = undefined +): boolean { + try { + if (fileSystem.existsSync(dest)) { + if (fileSystem.lstatSync(dest).isDirectory()) { + return true; + } else { + return false; + } + } + + if (!path) { + return false; + } + + const parent = path.dirname(dest); + if (!createDirectory(parent, mode)) { + return false; + } + + fileSystem.mkdirSync(dest, mode); + return true; + } catch (error) { + vscode.window.showErrorMessage(error as string); + return false; + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function copyFiles(src: string, dest: string, flags?: number): boolean { + try { + fileSystem.copyFileSync(src, dest); + return true; + } catch (error) { + vscode.window.showErrorMessage(error as string); + return false; + } +} + +export function writeIntoFile(path: string, data: string): void { + try { + fileSystem.writeFileSync(path, data, null); + } catch (err) { + vscode.window.showErrorMessage(err as string); + } +} + +export function readFromFile(path: string): string { + try { + const data = fileSystem.readFileSync(path, { encoding: 'utf-8' }); + return data as string; + } catch (err) { + vscode.window.showErrorMessage(err as string); + return ''; + } +} + +export function writeIntoFileAsync( + path: string, + data: string, + callback: fileSystem.NoParamCallback +): void { + try { + fileSystem.writeFile(path, data, callback); + } catch (err) { + vscode.window.showErrorMessage(err as string); + return; + } +} + +export function checkIfPathExists(path: string): boolean { + try { + if (fileSystem.existsSync(path)) { + return true; + } else { + return false; + } + } catch (err) { + vscode.window.showErrorMessage(err as string); + return false; + } +} + +export function checkIfDirectoryExists(path: string): boolean { + const doesPathExist = checkIfPathExists(path); + if (doesPathExist) { + return fileSystem.lstatSync(path).isDirectory(); + } + return false; +} + +export function checkIfFileExists(path: string): boolean { + const doesPathExist = checkIfPathExists(path); + if (doesPathExist) { + return fileSystem.lstatSync(path).isFile(); + } + return false; +} + +export function checkFolderName(folderName: string): boolean { + let invalidCharacterArr: string[] = []; + let valid = true; + + if (folderName.length > 255) { + valid = false; + } + + if (os.platform() === 'win32') { + invalidCharacterArr = ['\\', '/', ':', '?', '*', '"', '|', '<', '>']; + } else if (os.platform() === 'linux' || os.platform() === 'darwin') { + invalidCharacterArr = ['/']; + } + + invalidCharacterArr.forEach(function (c) { + if (folderName.indexOf(c) !== -1) { + valid = false; + } + }); + + return valid; +} + +export function downloadFile( + url: string, + destinationPath: string +): Promise<void> { + return new Promise((resolve, reject) => { + const file = fileSystem.createWriteStream(destinationPath); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const stream = request(url, undefined, (error, response, body) => { + if (response.statusCode !== 200) { + reject( + new Error( + `Download from ${url} failed with ${response.statusMessage}` + ) + ); + } + }).pipe(file); + stream.on('close', resolve); + stream.on('error', reject); + }); +} + +export function unzipFile( + sourcePath: string, + getDestinationFileName: (entryName: string) => string +): Promise<string[]> { + return new Promise((resolve, reject) => { + const unzippedFilePaths: string[] = []; + yauzl.open( + sourcePath, + { lazyEntries: true }, + function (error, zipfile) { + if (error) { + reject(error); + return; + } + zipfile.readEntry(); + zipfile.on('entry', function (entry) { + // This entry is a directory so skip it + if (/\/$/.test(entry.fileName)) { + zipfile.readEntry(); + return; + } + + zipfile.openReadStream(entry, function (error, readStream) { + if (error) { + reject(error); + return; + } + readStream.on('end', () => zipfile.readEntry()); + const destinationFileName = getDestinationFileName( + entry.fileName + ); + fileSystem.mkdirSync( + path.dirname(destinationFileName), + { recursive: true } + ); + + const file = + fileSystem.createWriteStream(destinationFileName); + readStream.pipe(file).on('error', reject); + unzippedFilePaths.push(destinationFileName); + }); + }); + zipfile.on('end', function () { + zipfile.close(); + resolve(unzippedFilePaths); + }); + } + ); + }); +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/dockerUtilities.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/dockerUtilities.ts new file mode 100644 index 000000000..0a749ba19 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/dockerUtilities.ts @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import * as cp from 'child_process'; +import * as path from 'path'; +import * as fs from 'fs'; +import { getWAMRExtensionVersion } from './lldbUtilities'; +import { downloadFile, unzipFile } from './directoryUtilities'; +import { SelectionOfPrompt, Status } from '../constants'; + +const DOCKER_IMAGES_TEM_FOLDER_NAME = 'docker-resource'; + +type SelectionStatus = SelectionOfPrompt | Status; + +const execShell = (cmd: string) => + new Promise<string>((resolve, reject) => { + cp.exec(cmd, (error, result) => { + if (error) { + return reject(error); + } + return resolve(result); + }); + }); + +export async function promptSetupDockerImages( + context: vscode.ExtensionContext +): Promise<SelectionStatus> { + const extensionPath = context.extensionPath; + const response = await vscode.window.showWarningMessage( + 'Necessary docker images are not found. Setup now?', + SelectionOfPrompt.setUp, + SelectionOfPrompt.skip + ); + + if (response === SelectionOfPrompt.skip) { + return response; + } + + const downloadUrlArray = getDockerImagesDownloadUrl(context); + + const destinationFolder = path.resolve( + extensionPath, + 'resource', + DOCKER_IMAGES_TEM_FOLDER_NAME + ); + + if (!fs.existsSync(destinationFolder)) { + fs.mkdirSync(destinationFolder); + } + + vscode.window.showInformationMessage(`Downloading Docker Images...`); + + for (const url of downloadUrlArray) { + const imageZipName = path.basename(url); + const imageStorePath = path.join(destinationFolder, imageZipName); + await downloadFile(url, imageStorePath); + + /** + * extract docker image tar package to + * '${destinationFolder}' + */ + const dockerImageFile = await unzipFile(imageStorePath, filename => + path.join(destinationFolder, filename) + ); + /* give access before loading */ + dockerImageFile.forEach(file => fs.chmodSync(file, '0775')); + + /**NOTE - load docker image tar package to host + * right now there are just one file + * `docker-image-name.tar` inside so we can + * directly use files[0] here, should be modified + * if the package's files change + */ + await execShell(`docker load -i ${dockerImageFile[0]}`); + } + + /* remove the DOCKER_IMAGES_TEM_FOLDER */ + fs.rmSync(destinationFolder, { recursive: true, force: true }); + + vscode.window.showInformationMessage( + `Docker images are ready, please run '$docker images' to check.` + ); + + return Status.done; +} + +export async function checkIfDockerStarted(): Promise<boolean> { + try { + await execShell('docker images'); + return true; + } catch (e) { + vscode.window.showWarningMessage((e as Error).message); + return false; + } +} + +export async function checkIfDockerImagesExist( + context: vscode.ExtensionContext +): Promise<boolean> { + try { + /* the tag of images is equal to extension's version */ + const imageTag = getWAMRExtensionVersion(context); + await execShell( + `docker image inspect wasm-debug-server:${imageTag} wasm-toolchain:${imageTag}` + ); + return true; + } catch (e) { + return false; + } +} + +function getDockerImagesDownloadUrl( + context: vscode.ExtensionContext +): string[] { + const wamrVersion = getWAMRExtensionVersion(context); + const wamrReleaseUrl = `https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR`; + + return [ + `${wamrReleaseUrl}-${wamrVersion}/wasm-debug-server-${wamrVersion}.zip`, + `${wamrReleaseUrl}-${wamrVersion}/wasm-toolchain-${wamrVersion}.zip`, + ]; +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/getUri.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/getUri.ts new file mode 100644 index 000000000..93a7eef30 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/getUri.ts @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import { Uri, Webview } from 'vscode'; + +export function getUri( + webview: Webview, + extensionUri: Uri, + pathList: string[] +): Uri { + return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList)); +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts new file mode 100644 index 000000000..9170a75d3 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +import * as vscode from 'vscode'; +import * as os from 'os'; +import * as path from 'path'; +import * as fs from 'fs'; +import { + checkIfFileExists, + downloadFile, + unzipFile, +} from './directoryUtilities'; +import { SelectionOfPrompt } from '../constants'; + +const LLDB_RESOURCE_DIR = 'resource/debug'; +const LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP: Partial< + Record<NodeJS.Platform, string> +> = { + linux: 'x86_64-ubuntu-20.04', + darwin: 'universal-macos-latest', +}; + +const WAMR_LLDB_NOT_SUPPORTED_ERROR = new Error( + 'WAMR LLDB is not supported on this platform' +); + +function getLLDBUnzipFilePath(destinationFolder: string, filename: string) { + const dirs = filename.split('/'); + if (dirs[0] === 'wamr-lldb') { + dirs.shift(); + } + + return path.join(destinationFolder, ...dirs); +} + +export function getWAMRExtensionVersion( + context: vscode.ExtensionContext +): string { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require(path.join(context.extensionPath, 'package.json')).version; +} + +function getLLDBDownloadUrl(context: vscode.ExtensionContext): string { + const wamrVersion = getWAMRExtensionVersion(context); + const lldbOsUrlSuffix = LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP[os.platform()]; + + if (!lldbOsUrlSuffix) { + throw WAMR_LLDB_NOT_SUPPORTED_ERROR; + } + + return `https://github.com/bytecodealliance/wasm-micro-runtime/releases/download/WAMR-${wamrVersion}/wamr-lldb-${wamrVersion}-${lldbOsUrlSuffix}.zip`; +} + +export function isLLDBInstalled(context: vscode.ExtensionContext): boolean { + const extensionPath = context.extensionPath; + const lldbOSDir = os.platform(); + const lldbBinaryPath = path.join( + extensionPath, + LLDB_RESOURCE_DIR, + lldbOSDir, + 'bin', + 'lldb' + ); + return checkIfFileExists(lldbBinaryPath); +} + +export async function promptInstallLLDB( + context: vscode.ExtensionContext +): Promise<SelectionOfPrompt> { + const extensionPath = context.extensionPath; + + const response = await vscode.window.showWarningMessage( + 'No LLDB instance found. Setup now?', + SelectionOfPrompt.setUp, + SelectionOfPrompt.skip + ); + + if (response === SelectionOfPrompt.skip) { + return response; + } + + const downloadUrl = getLLDBDownloadUrl(context); + const destinationDir = os.platform(); + + if (!downloadUrl) { + throw WAMR_LLDB_NOT_SUPPORTED_ERROR; + } + + const lldbDestinationFolder = path.join( + extensionPath, + LLDB_RESOURCE_DIR, + destinationDir + ); + const lldbZipPath = path.join(lldbDestinationFolder, 'bundle.zip'); + + vscode.window.showInformationMessage(`Downloading LLDB...`); + + await downloadFile(downloadUrl, lldbZipPath); + + vscode.window.showInformationMessage( + `LLDB downloaded to ${lldbZipPath}. Installing...` + ); + + const lldbFiles = await unzipFile(lldbZipPath, filename => + getLLDBUnzipFilePath(lldbDestinationFolder, filename) + ); + // Allow execution of lldb + lldbFiles.forEach(file => fs.chmodSync(file, '0775')); + + vscode.window.showInformationMessage( + `LLDB installed at ${lldbDestinationFolder}` + ); + + // Remove the bundle.zip + fs.unlinkSync(lldbZipPath); + return SelectionOfPrompt.setUp; +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts new file mode 100644 index 000000000..79671f68c --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/NewProjectPanel.ts @@ -0,0 +1,260 @@ +/* + * 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(); + } + } + } +} diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/TargetConfigPanel.ts b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/TargetConfigPanel.ts new file mode 100644 index 000000000..f2e1343a5 --- /dev/null +++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/test-tools/wamr-ide/VSCode-Extension/src/view/TargetConfigPanel.ts @@ -0,0 +1,238 @@ +/* + * 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 { readFromConfigFile, writeIntoConfigFile } from '../extension'; +import { getUri } from '../utilities/getUri'; + +export class TargetConfigPanel { + public static currentPanel: TargetConfigPanel | undefined; + private readonly viewPanel: vscode.WebviewPanel; + + private _disposables: vscode.Disposable[] = []; + public static buildArgs = { + outputFileName: 'main.wasm', + initMemorySize: '131072', + maxMemorySize: '131072', + stackSize: '4096', + exportedSymbols: 'main', + }; + + private static readonly userInputError: number = -2; + private static readonly executionSuccess: number = 0; + + /** + * + * @param context extension context from extension.ts active func + * @param panelName + */ + constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) { + this.viewPanel = panel; + this.viewPanel.webview.html = this._getHtmlForWebview( + this.viewPanel.webview, + extensionUri, + 'resource/webview/page/configBuildTarget.html' + ); + this.viewPanel.onDidDispose(this.dispose, null, this._disposables); + this._setWebviewMessageListener(this.viewPanel.webview); + } + + /** + * + * @param context + */ + public static render(context: vscode.ExtensionContext): void { + /* check if current panel is initialized */ + if (TargetConfigPanel.currentPanel) { + TargetConfigPanel.currentPanel.viewPanel.reveal( + vscode.ViewColumn.One + ); + } else { + const panel = vscode.window.createWebviewPanel( + 'targetConfig', + 'Config building target', + vscode.ViewColumn.One, + { + enableScripts: true, + retainContextWhenHidden: true, + } + ); + + TargetConfigPanel.currentPanel = new TargetConfigPanel( + panel, + context.extensionUri + ); + } + } + + private configBuildArgs( + outputFileName: string, + initMemSize: string, + maxMemSize: string, + stackSize: string, + exportedSymbols: string + ): number { + if ( + outputFileName === '' || + initMemSize === '' || + maxMemSize === '' || + stackSize === '' || + exportedSymbols === '' + ) { + return TargetConfigPanel.userInputError; + } + + let includePathArr = []; + let excludeFileArr = []; + + const configObj = { + outputFileName: outputFileName, + initMemorySize: initMemSize, + maxMemorySize: maxMemSize, + stackSize: stackSize, + exportedSymbols: exportedSymbols, + }; + const configStr = readFromConfigFile(); + + TargetConfigPanel.buildArgs = configObj; + + if (configStr !== '' && configStr !== undefined) { + const configJson = JSON.parse(configStr); + includePathArr = + configJson['includePaths'] === undefined + ? [] + : configJson['includePaths']; + excludeFileArr = + configJson['excludeFiles'] === undefined + ? [] + : configJson['excludeFiles']; + } + + writeIntoConfigFile( + includePathArr, + excludeFileArr, + TargetConfigPanel.buildArgs + ); + + return TargetConfigPanel.executionSuccess; + } + + private _getHtmlForWebview( + webview: vscode.Webview, + extensionUri: vscode.Uri, + templatePath: string + ) { + /* get toolkit uri */ + 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', + 'configbuildtarget.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()) + .replace( + /(\${output_file_val})/, + TargetConfigPanel.buildArgs.outputFileName + ) + .replace( + /(\${initial_mem_size_val})/, + TargetConfigPanel.buildArgs.initMemorySize + ) + .replace( + /(\${max_mem_size_val})/, + TargetConfigPanel.buildArgs.maxMemorySize + ) + .replace( + /(\${stack_size_val})/, + TargetConfigPanel.buildArgs.stackSize + ) + .replace( + /(\${exported_symbols_val})/, + TargetConfigPanel.buildArgs.exportedSymbols + ); + + return html; + } + + private _setWebviewMessageListener(webview: vscode.Webview) { + webview.onDidReceiveMessage( + message => { + switch (message.command) { + case 'config_build_target': + if ( + message.outputFileName === '' || + message.initMemSize === '' || + message.maxMemSize === '' || + message.stackSize === '' || + message.exportedSymbols === '' + ) { + vscode.window.showErrorMessage( + 'Please fill chart before your submit!' + ); + return; + } else if ( + this.configBuildArgs( + message.outputFileName, + message.initMemSize, + message.maxMemSize, + message.stackSize, + message.exportedSymbols + ) === TargetConfigPanel.executionSuccess + ) { + vscode.window + .showInformationMessage( + 'Configurations have been saved!', + 'OK' + ) + .then(() => { + this.viewPanel.dispose(); + return; + }); + } + + default: + break; + } + }, + undefined, + this._disposables + ); + } + + private dispose() { + TargetConfigPanel.currentPanel = undefined; + this.viewPanel.dispose(); + + while (this._disposables.length) { + const disposable = this._disposables.pop(); + if (disposable) { + disposable.dispose(); + } + } + } +} |