mirror of
https://github.com/Pandipipas/scoreko-electron-dev.git
synced 2026-06-06 05:32:06 +00:00
Improving Installer and Updater Process
This commit is contained in:
@@ -41,6 +41,22 @@ export async function askToInstallUpdate(update: ReleaseUpdate, parentWindow: Br
|
||||
return result.response === 0;
|
||||
}
|
||||
|
||||
export async function showDownloadFailedDialog(
|
||||
update: ReleaseUpdate,
|
||||
error: unknown,
|
||||
parentWindow: BrowserWindow | null,
|
||||
): Promise<void> {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
await showMessageBox(parentWindow, {
|
||||
type: "error",
|
||||
title: "Error de descarga",
|
||||
message: `No se pudo descargar la actualización para Scoreko ${update.version}.`,
|
||||
detail: `Detalles del error: ${errorMessage}\n\nPor favor, comprueba tu conexión a internet e inténtalo de nuevo.`,
|
||||
buttons: ["Aceptar"],
|
||||
defaultId: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function showMessageBox(
|
||||
parentWindow: BrowserWindow | null,
|
||||
options: MessageBoxOptions,
|
||||
|
||||
@@ -23,6 +23,13 @@ export async function downloadInstaller(update: ReleaseUpdate, config: UpdateDow
|
||||
const targetPath = getSafeChildPath(downloadDirectory, safeFileName);
|
||||
const stagingPath = getSafeChildPath(downloadDirectory, `${safeFileName}.${process.pid}.${Date.now()}.download`);
|
||||
|
||||
if (fs.existsSync(targetPath)) {
|
||||
const stats = fs.statSync(targetPath);
|
||||
if (typeof update.installer.size === "number" && stats.size === update.installer.size) {
|
||||
return targetPath;
|
||||
}
|
||||
}
|
||||
|
||||
fs.mkdirSync(downloadDirectory, { recursive: true });
|
||||
fs.rmSync(stagingPath, { force: true });
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { app, BrowserWindow, shell } from "electron";
|
||||
|
||||
import { AppRuntimeConfig } from "../config/runtime-config";
|
||||
import { askToDownloadUpdate, askToInstallUpdate } from "./update-dialogs";
|
||||
import { askToDownloadUpdate, askToInstallUpdate, showDownloadFailedDialog } from "./update-dialogs";
|
||||
import { loadUpdateSettings, UpdateSettings } from "./update-config";
|
||||
import { downloadInstaller } from "./update-download";
|
||||
import { buildReleaseUpdate, GiteaRelease, parseGiteaRelease } from "./update-schema";
|
||||
@@ -76,10 +76,17 @@ async function checkForUpdates({
|
||||
return;
|
||||
}
|
||||
|
||||
const installerPath = await downloadInstaller(update, {
|
||||
tempDirectory: app.getPath("temp"),
|
||||
allowInsecureHttp: protocolPolicy.allowInsecureHttp,
|
||||
});
|
||||
let installerPath: string;
|
||||
try {
|
||||
installerPath = await downloadInstaller(update, {
|
||||
tempDirectory: app.getPath("temp"),
|
||||
allowInsecureHttp: protocolPolicy.allowInsecureHttp,
|
||||
});
|
||||
} catch (error) {
|
||||
log("Update installer download failed.", error);
|
||||
await showDownloadFailedDialog(update, error, getParentWindow());
|
||||
return;
|
||||
}
|
||||
const shouldInstall = await askToInstallUpdate(update, getParentWindow());
|
||||
if (!shouldInstall) {
|
||||
await shell.showItemInFolder(installerPath);
|
||||
|
||||
@@ -56,3 +56,38 @@ test("downloadInstaller rejects insecure production download URLs", async () =>
|
||||
/unsupported protocol/,
|
||||
);
|
||||
});
|
||||
|
||||
test("downloadInstaller reuses existing file if size matches and does not download again", async () => {
|
||||
const tempDirectory = fs.mkdtempSync(path.join(os.tmpdir(), "scoreko-update-download-"));
|
||||
const downloadDirectory = path.join(tempDirectory, "scoreko-updates");
|
||||
fs.mkdirSync(downloadDirectory, { recursive: true });
|
||||
|
||||
const installerPath = path.join(downloadDirectory, "Scoreko_setup_0.2.0.exe");
|
||||
fs.writeFileSync(installerPath, "cached-installer-bytes");
|
||||
const cachedSize = fs.statSync(installerPath).size;
|
||||
|
||||
const previousFetch = globalThis.fetch;
|
||||
globalThis.fetch = async () => {
|
||||
throw new Error("Should not fetch when using cached file!");
|
||||
};
|
||||
|
||||
try {
|
||||
const resultPath = await downloadInstaller(
|
||||
{
|
||||
version: "0.2.0",
|
||||
title: "Scoreko 0.2.0",
|
||||
installer: {
|
||||
name: "Scoreko/setup:0.2.0.exe",
|
||||
downloadUrl: "https://updates.local/Scoreko-setup-0.2.0.exe",
|
||||
size: cachedSize,
|
||||
},
|
||||
},
|
||||
{ tempDirectory, allowInsecureHttp: false },
|
||||
);
|
||||
|
||||
assert.equal(resultPath, installerPath);
|
||||
assert.equal(fs.readFileSync(resultPath, "utf8"), "cached-installer-bytes");
|
||||
} finally {
|
||||
globalThis.fetch = previousFetch;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user