From 2de5e1dbd7a0caf43c678235cd7efd3f7c2752c7 Mon Sep 17 00:00:00 2001 From: Samuel Kyletoft Date: Sun, 20 Mar 2022 21:56:02 +0100 Subject: [PATCH] Feature: Download progress bar --- vsc_gui/package.json | 4 ++ vsc_gui/src/download_native.ts | 70 +++++++++++++++++++++++----------- vsc_gui/src/extension.ts | 3 +- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/vsc_gui/package.json b/vsc_gui/package.json index 05d1d1e..359b053 100644 --- a/vsc_gui/package.json +++ b/vsc_gui/package.json @@ -58,6 +58,10 @@ { "command": "md407.new_crt", "title": "Create new project from the CRT template" + }, + { + "command": "md407.download-gcc", + "title": "Download and install the complier toolchain" } ], "viewsContainers": { diff --git a/vsc_gui/src/download_native.ts b/vsc_gui/src/download_native.ts index 7051df6..d1094b5 100644 --- a/vsc_gui/src/download_native.ts +++ b/vsc_gui/src/download_native.ts @@ -26,7 +26,7 @@ export function download() { fs.mkdirSync(NATIVE_FOLDER); } - let url; + let url: string; switch (process.platform) { case "linux": url = LINUX_URL; @@ -38,34 +38,58 @@ export function download() { url = WINDOWS_URL; break; } + url = WINDOWS_URL; console.log(`Downloading: ${url}`); - vscode.window.showInformationMessage("Download starting (~200MB, and I don't have a progress bar yet)"); - progress(request(url)) - .on('progress', function (state: any) { - console.log('progress', state.percent); - }) - .on('error', function (err: any) { - vscode.window.showErrorMessage("Download failed"); - console.log("Error: ", err.message); - }) - .on('end', () => { - vscode.window.showInformationMessage("Download complete"); - const zip = new unzip(TMP_FILE); - zip.extractAllTo(NATIVE_FOLDER, true); - console.log(`File extracted!`); - vscode.window.showInformationMessage("File extracted"); - - mark_executables(NATIVE_FOLDER); - - fs.createWriteStream(DONE).close(); // Create file to mark that we don't need to redownload - vscode.window.showInformationMessage("Setup complete"); - }) - .pipe(fs.createWriteStream(TMP_FILE)); + + return vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: "Downloading GCC toolchain", + cancellable: true + }, (vsc_progress, token) => { + token.onCancellationRequested(() => { + console.log("Download cancelled"); + }); + + vsc_progress.report({ increment: 0 }); + + const p = new Promise(resolve => { + let last = 0; + progress(request(url)) + .on('progress', function (state: any) { + console.log('progress', state.percent); + const delta = state.percent - last; + last = state.percent; + vsc_progress.report({ increment: delta * 100 }); + }) + .on('error', function (err: any) { + vscode.window.showErrorMessage("Download failed"); + console.log("Error: ", err.message); + }) + .on('end', () => { + vscode.window.showInformationMessage("Download complete"); + const zip = new unzip(TMP_FILE); + zip.extractAllTo(NATIVE_FOLDER, true); + console.log(`File extracted!`); + vscode.window.showInformationMessage("File extracted"); + + mark_executables(NATIVE_FOLDER); + + fs.createWriteStream(DONE).close(); // Create file to mark that we don't need to redownload + vscode.window.showInformationMessage("Setup complete"); + + resolve(); + }) + .pipe(fs.createWriteStream(TMP_FILE)); + }); + + return p; + }); } /// Returns true if the name ends with ".exe" or doesn't contain a "." at all function is_executable(file: string) { + // Better solution: Check if a file starts with the magic values for ELF, EXE or a Shebang if (file.endsWith(".exe") || file.endsWith(".elf")) { return true; } const name_starts_at = Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\")); const name = file.substring(name_starts_at); diff --git a/vsc_gui/src/extension.ts b/vsc_gui/src/extension.ts index b94551e..d47821d 100644 --- a/vsc_gui/src/extension.ts +++ b/vsc_gui/src/extension.ts @@ -33,7 +33,8 @@ export function activate(context: vscode.ExtensionContext) { const path_separator = process.platform === "win32" ? "\\" : "/"; context.environmentVariableCollection.append("PATH", `${var_separator}${extension_root}${path_separator}native_dependencies${path_separator}bin`); - download(); + context.subscriptions.push(vscode.commands.registerCommand('md407.download-gcc', download)); + vscode.commands.executeCommand("md407.download-gcc"); const build_task = new CustomBuildTaskProvider(workspace_root); vscode.tasks.registerTaskProvider(CustomBuildTaskProvider.CustomBuildScriptType, build_task);