Skip to content

Commit 3da3641

Browse files
committed
VS Code updater improvements
1 parent aad3cc8 commit 3da3641

1 file changed

Lines changed: 60 additions & 5 deletions

File tree

vscode/src/updater.ts

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
13
import * as vscode from "vscode";
24

35
const REPO = "DivineDragonFanClub/engage-il2cpp";
@@ -58,7 +60,7 @@ async function checkForUpdates(context: vscode.ExtensionContext, output: vscode.
5860
}
5961

6062
if (autoApply) {
61-
await applyUpdate(vsix.browser_download_url, output);
63+
await applyUpdate(context, vsix.browser_download_url, output);
6264
return;
6365
}
6466

@@ -69,7 +71,7 @@ async function checkForUpdates(context: vscode.ExtensionContext, output: vscode.
6971
);
7072

7173
if (choice === "Update") {
72-
await applyUpdate(vsix.browser_download_url, output);
74+
await applyUpdate(context, vsix.browser_download_url, output);
7375
}
7476
}
7577

@@ -105,15 +107,31 @@ async function fetchLatestRelease(etag: string | undefined): Promise<FetchedRele
105107
return { release, etag: newEtag };
106108
}
107109

108-
async function applyUpdate(vsixUrl: string, output: vscode.OutputChannel): Promise<void> {
109-
output.appendLine(`installing update from ${vsixUrl}`);
110+
async function applyUpdate(context: vscode.ExtensionContext, vsixUrl: string, output: vscode.OutputChannel): Promise<void> {
111+
output.appendLine(`downloading update from ${vsixUrl}`);
112+
113+
let localPath: string;
114+
115+
try {
116+
localPath = await downloadVsix(context, vsixUrl);
117+
} catch (err) {
118+
const message = err instanceof Error ? err.message : String(err);
119+
120+
output.appendLine(`download failed: ${message}`);
121+
vscode.window.showErrorMessage(`engage: download failed. ${message}`);
122+
123+
return;
124+
}
125+
126+
output.appendLine(`installing from ${localPath}`);
110127

111128
try {
112-
await vscode.commands.executeCommand("workbench.extensions.installExtension", vscode.Uri.parse(vsixUrl));
129+
await vscode.commands.executeCommand("workbench.extensions.installExtension", vscode.Uri.file(localPath));
113130
} catch (err) {
114131
const message = err instanceof Error ? err.message : String(err);
115132

116133
vscode.window.showErrorMessage(`engage: install failed. ${message}`);
134+
117135
return;
118136
}
119137

@@ -124,6 +142,43 @@ async function applyUpdate(vsixUrl: string, output: vscode.OutputChannel): Promi
124142
}
125143
}
126144

145+
async function downloadVsix(context: vscode.ExtensionContext, url: string): Promise<string> {
146+
const cacheDir = path.join(context.globalStorageUri.fsPath, "updates");
147+
await fs.promises.mkdir(cacheDir, { recursive: true });
148+
149+
const filename = inferFilename(url);
150+
const target = path.join(cacheDir, filename);
151+
152+
const response = await fetch(url, {
153+
redirect: "follow",
154+
headers: { "User-Agent": "engage-vscode" },
155+
});
156+
157+
if (!response.ok) {
158+
throw new Error(`HTTP ${response.status} fetching ${url}`);
159+
}
160+
161+
const data = Buffer.from(await response.arrayBuffer());
162+
await fs.promises.writeFile(target, data);
163+
164+
return target;
165+
}
166+
167+
function inferFilename(url: string): string {
168+
try {
169+
const u = new URL(url);
170+
const last = u.pathname.split("/").filter((p) => p.length > 0).pop();
171+
172+
if (last && last.endsWith(".vsix")) {
173+
return last;
174+
}
175+
} catch {
176+
// ignore
177+
}
178+
179+
return `engage-update-${Date.now()}.vsix`;
180+
}
181+
127182
function matchesPlatform(assetName: string): boolean {
128183
const platform = process.platform;
129184
const arch = process.arch;

0 commit comments

Comments
 (0)