All checks were successful
farmcontrol/farmcontrol-server/pipeline/head This commit looks good
- Added rcedit dependency in package.json and bun.lock for embedding icons in Windows executables. - Introduced a new script to generate and apply the application icon for Windows launcher binaries, improving visual consistency. - Updated the NSIS installer script to support dynamic icon paths, enhancing flexibility in icon management during installation. - Integrated the icon application process into the finalization of desktop artifacts, ensuring the icon is embedded in the generated binaries.
84 lines
2.4 KiB
JavaScript
84 lines
2.4 KiB
JavaScript
import { existsSync } from "node:fs";
|
|
import path from "node:path";
|
|
import { spawnSync } from "node:child_process";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
|
const WINDOWS_BIN_FILES = ["launcher.exe", "bun.exe"];
|
|
|
|
function ensureIconIco() {
|
|
const iconPath = path.join(rootDir, "assets/icon.ico");
|
|
if (existsSync(iconPath)) {
|
|
return iconPath;
|
|
}
|
|
|
|
const sources = [
|
|
path.join(rootDir, "assets/farmcontrolhosticon.png"),
|
|
path.join(rootDir, "assets/icon.png"),
|
|
];
|
|
const source = sources.find((candidate) => existsSync(candidate));
|
|
if (!source) {
|
|
throw new Error(
|
|
"apply-windows-launcher-icon: assets/icon.ico not found and no source PNG to generate it",
|
|
);
|
|
}
|
|
|
|
console.log(`apply-windows-launcher-icon: generating icon.ico from ${source}`);
|
|
const result = spawnSync(
|
|
"bun",
|
|
[path.join(rootDir, "scripts/prepare-app-icons.mjs"), source],
|
|
{ cwd: rootDir, stdio: "inherit", env: process.env },
|
|
);
|
|
|
|
if (result.status !== 0 || !existsSync(iconPath)) {
|
|
throw new Error("apply-windows-launcher-icon: failed to generate assets/icon.ico");
|
|
}
|
|
|
|
return iconPath;
|
|
}
|
|
|
|
/**
|
|
* Embed the Farm Control icon into Windows launcher binaries.
|
|
* Electrobun's built-in rcedit step often fails in CI (see electrobun#429).
|
|
*/
|
|
export async function applyWindowsLauncherIcon(appDir) {
|
|
if (process.platform !== "win32") {
|
|
console.log("apply-windows-launcher-icon: skipped (not Windows)");
|
|
return;
|
|
}
|
|
|
|
const iconPath = ensureIconIco();
|
|
const binDir = path.join(appDir, "bin");
|
|
if (!existsSync(binDir)) {
|
|
throw new Error(`apply-windows-launcher-icon: bin directory not found: ${binDir}`);
|
|
}
|
|
|
|
const rcedit = (await import("rcedit")).default;
|
|
let patched = 0;
|
|
|
|
for (const fileName of WINDOWS_BIN_FILES) {
|
|
const exePath = path.join(binDir, fileName);
|
|
if (!existsSync(exePath)) {
|
|
continue;
|
|
}
|
|
|
|
console.log(`apply-windows-launcher-icon: embedding icon into ${exePath}`);
|
|
try {
|
|
await rcedit(exePath, { icon: iconPath });
|
|
patched += 1;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
throw new Error(
|
|
`apply-windows-launcher-icon: failed to embed icon into ${fileName}: ${message}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (patched === 0) {
|
|
throw new Error(
|
|
`apply-windows-launcher-icon: no launcher binaries found in ${binDir}`,
|
|
);
|
|
}
|
|
}
|