aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/net.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/net.ts')
-rw-r--r--editors/code/src/net.ts39
1 files changed, 24 insertions, 15 deletions
diff --git a/editors/code/src/net.ts b/editors/code/src/net.ts
index 492213937..866092882 100644
--- a/editors/code/src/net.ts
+++ b/editors/code/src/net.ts
@@ -1,8 +1,10 @@
1import fetch from "node-fetch"; 1import fetch from "node-fetch";
2import * as vscode from "vscode"; 2import * as vscode from "vscode";
3import * as fs from "fs";
4import * as stream from "stream"; 3import * as stream from "stream";
4import * as crypto from "crypto";
5import * as fs from "fs";
5import * as util from "util"; 6import * as util from "util";
7import * as path from "path";
6import { log, assert } from "./util"; 8import { log, assert } from "./util";
7 9
8const pipeline = util.promisify(stream.pipeline); 10const pipeline = util.promisify(stream.pipeline);
@@ -58,22 +60,29 @@ export interface GithubRelease {
58 }>; 60 }>;
59} 61}
60 62
63interface DownloadOpts {
64 progressTitle: string;
65 url: string;
66 dest: string;
67 mode?: number;
68}
69
70export async function download(opts: DownloadOpts) {
71 // Put artifact into a temporary file (in the same dir for simplicity)
72 // to prevent partially downloaded files when user kills vscode
73 const dest = path.parse(opts.dest);
74 const randomHex = crypto.randomBytes(5).toString("hex");
75 const tempFile = path.join(dest.dir, `${dest.name}${randomHex}`);
61 76
62export async function download(
63 downloadUrl: string,
64 destinationPath: string,
65 progressTitle: string,
66 { mode }: { mode?: number } = {},
67) {
68 await vscode.window.withProgress( 77 await vscode.window.withProgress(
69 { 78 {
70 location: vscode.ProgressLocation.Notification, 79 location: vscode.ProgressLocation.Notification,
71 cancellable: false, 80 cancellable: false,
72 title: progressTitle 81 title: opts.progressTitle
73 }, 82 },
74 async (progress, _cancellationToken) => { 83 async (progress, _cancellationToken) => {
75 let lastPercentage = 0; 84 let lastPercentage = 0;
76 await downloadFile(downloadUrl, destinationPath, mode, (readBytes, totalBytes) => { 85 await downloadFile(opts.url, tempFile, opts.mode, (readBytes, totalBytes) => {
77 const newPercentage = (readBytes / totalBytes) * 100; 86 const newPercentage = (readBytes / totalBytes) * 100;
78 progress.report({ 87 progress.report({
79 message: newPercentage.toFixed(0) + "%", 88 message: newPercentage.toFixed(0) + "%",
@@ -84,10 +93,12 @@ export async function download(
84 }); 93 });
85 } 94 }
86 ); 95 );
96
97 await fs.promises.rename(tempFile, opts.dest);
87} 98}
88 99
89/** 100/**
90 * Downloads file from `url` and stores it at `destFilePath` with `destFilePermissions`. 101 * Downloads file from `url` and stores it at `destFilePath` with `mode` (unix permissions).
91 * `onProgress` callback is called on recieveing each chunk of bytes 102 * `onProgress` callback is called on recieveing each chunk of bytes
92 * to track the progress of downloading, it gets the already read and total 103 * to track the progress of downloading, it gets the already read and total
93 * amount of bytes to read as its parameters. 104 * amount of bytes to read as its parameters.
@@ -119,13 +130,11 @@ async function downloadFile(
119 }); 130 });
120 131
121 const destFileStream = fs.createWriteStream(destFilePath, { mode }); 132 const destFileStream = fs.createWriteStream(destFilePath, { mode });
122
123 await pipeline(res.body, destFileStream); 133 await pipeline(res.body, destFileStream);
124 return new Promise<void>(resolve => { 134 await new Promise<void>(resolve => {
125 destFileStream.on("close", resolve); 135 destFileStream.on("close", resolve);
126 destFileStream.destroy(); 136 destFileStream.destroy();
127 137 // This workaround is awaiting to be removed when vscode moves to newer nodejs version:
128 // Details on workaround: https://github.com/rust-analyzer/rust-analyzer/pull/3092#discussion_r378191131 138 // https://github.com/rust-analyzer/rust-analyzer/issues/3167
129 // Issue at nodejs repo: https://github.com/nodejs/node/issues/31776
130 }); 139 });
131} 140}