From e4919a50e66088b63887535970bbb94a3e3a16bc Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:23:47 -0500 Subject: [PATCH] refactor(bld): extract out features as functions --- src/bld.js | 448 ++++++++++++++++++++++++++++------------------------- 1 file changed, 240 insertions(+), 208 deletions(-) diff --git a/src/bld.js b/src/bld.js index 099258db7..233a8ec12 100644 --- a/src/bld.js +++ b/src/bld.js @@ -15,6 +15,11 @@ import compressing from "compressing"; import rcedit from "rcedit"; import plist from "plist"; +/** + * @typedef {object} BuildOptions + * @param + */ + /** * References: * https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html @@ -97,7 +102,7 @@ import plist from "plist"; * * Note: If you are using the MacOS ARM unofficial builds, you will need to [remove the `com.apple.qurantine` flag](https://github.com/corwin-of-amber/nw.js/releases/tag/nw-v0.75.0): * - * `sudo xattr -r -d com.apple.quarantine nwjs.app` + * `sudo xattr -r -d com.apple.quarantine /path/to/nwjs.app` * * @example * // Minimal Usage (uses default values) @@ -203,240 +208,267 @@ export async function bld( } } - let manifest = undefined; - if ( managedManifest === true || typeof managedManifest === "object" || typeof managedManifest === "string" ) { - if (managedManifest === true) { - manifest = nwPkg; - } - - if (typeof managedManifest === "object") { - manifest = managedManifest; - } + enableManagedManifest({ nwPkg, managedManifest, outDir, platform }); + } - if (typeof managedManifest === "string") { - manifest = JSON.parse(await readFile(managedManifest)); - } + if (platform === "linux") { + await setLinuxConfig({ app, outDir }); + } else if (platform === "win") { + await setWinConfig({ app, outDir }); + } else if (platform === "osx") { + await setOsxConfig({ platform, outDir, app }); + } - if (manifest.devDependencies) { - manifest.devDependencies = undefined; - } - manifest.packageManager = manifest.packageManager ?? "npm@*"; + if (nativeAddon === "gyp") { + buildNativeAddon({ cacheDir, version, platform, arch, outDir, nodeVersion }); + } - await writeFile( - resolve( - outDir, - platform !== "osx" - ? "package.nw" - : "nwjs.app/Contents/Resources/app.nw", - "package.json", - ), - JSON.stringify(manifest, null, 2), - "utf8", - ); + if (zip !== false) { + await compress({ zip, outDir }); + } +} - chdir( - resolve( - outDir, - platform !== "osx" - ? "package.nw" - : "nwjs.app/Contents/Resources/app.nw", - ), - ); +const enableManagedManifest = async ({ nwPkg, managedManifest, outDir, platform }) => { + let manifest = undefined; - if (manifest.packageManager.startsWith("npm")) { - exec(`npm install`); - } else if (manifest.packageManager.startsWith("yarn")) { - exec(`yarn install`); - } else if (manifest.packageManager.startsWith("pnpm")) { - exec(`pnpm install`); - } + if (managedManifest === true) { + manifest = nwPkg; } - if (platform === "linux") { - if (PLATFORM === "win32") { - console.warn( - "Linux apps built on Windows platform do not preserve all file permissions. See #716", - ); - } - let desktopEntryFile = { - Type: "Application", - Version: "1.5", - Name: app.name, - GenericName: app.genericName, - NoDisplay: app.noDisplay, - Comment: app.comment, - Icon: app.icon, - Hidden: app.hidden, - OnlyShowIn: app.onlyShowIn, - NotShowIn: app.notShowIn, - DBusActivatable: app.dBusActivatable, - TryExec: app.tryExec, - Exec: app.name, - Path: app.path, - Terminal: app.terminal, - Actions: app.actions, - MimeType: app.mimeType, - Categories: app.categories, - Implements: app.implements, - Keywords: app.keywords, - StartupNotify: app.startupNotify, - StartupWMClass: app.startupWMClass, - PrefersNonDefaultGPU: app.prefersNonDefaultGPU, - SingleMainWindow: app.singleMainWindow, - }; - - await rename(`${outDir}/nw`, `${outDir}/${app.name}`); - - let fileContent = `[Desktop Entry]\n`; - Object.keys(desktopEntryFile).forEach((key) => { - if (desktopEntryFile[key] !== undefined) { - fileContent += `${key}=${desktopEntryFile[key]}\n`; - } - }); - let filePath = `${outDir}/${app.name}.desktop`; - await writeFile(filePath, fileContent); - } else if (platform === "win") { - let versionString = { - Comments: app.comments, - CompanyName: app.author, - FileDescription: app.fileDescription, - FileVersion: app.fileVersion, - InternalName: app.name, - LegalCopyright: app.legalCopyright, - LegalTrademarks: app.legalTrademark, - OriginalFilename: app.name, - PrivateBuild: app.name, - ProductName: app.name, - ProductVersion: app.version, - SpecialBuild: app.name, - }; - - Object.keys(versionString).forEach((option) => { - if (versionString[option] === undefined) { - delete versionString[option]; - } - }); + if (typeof managedManifest === "object") { + manifest = managedManifest; + } - const rcEditOptions = { - "file-version": app.version, - "product-version": app.version, - "version-string": versionString, - }; + if (typeof managedManifest === "string") { + manifest = JSON.parse(await readFile(managedManifest)); + } - if (app.icon) { - rcEditOptions.icon = app.icon; - } + if (manifest.devDependencies) { + manifest.devDependencies = undefined; + } + manifest.packageManager = manifest.packageManager ?? "npm@*"; + + await writeFile( + resolve( + outDir, + platform !== "osx" + ? "package.nw" + : "nwjs.app/Contents/Resources/app.nw", + "package.json", + ), + JSON.stringify(manifest, null, 2), + "utf8", + ); + + chdir( + resolve( + outDir, + platform !== "osx" + ? "package.nw" + : "nwjs.app/Contents/Resources/app.nw", + ), + ); + + if (manifest.packageManager.startsWith("npm")) { + exec(`npm install`); + } else if (manifest.packageManager.startsWith("yarn")) { + exec(`yarn install`); + } else if (manifest.packageManager.startsWith("pnpm")) { + exec(`pnpm install`); + } +}; - try { - const outDirAppExe = resolve(outDir, `${app.name}.exe`); - await rename(resolve(outDir, "nw.exe"), outDirAppExe); - await rcedit(outDirAppExe, rcEditOptions); - } catch (error) { - console.warn( - "Renaming EXE failed or unable to modify EXE. If it's the latter, ensure WINE is installed or build your application Windows platform", - ); - console.error(error); +const setLinuxConfig = async ({ app, outDir }) => { + if (PLATFORM === "win32") { + console.warn( + "Linux apps built on Windows platform do not preserve all file permissions. See #716", + ); + } + let desktopEntryFile = { + Type: "Application", + Version: "1.5", + Name: app.name, + GenericName: app.genericName, + NoDisplay: app.noDisplay, + Comment: app.comment, + Icon: app.icon, + Hidden: app.hidden, + OnlyShowIn: app.onlyShowIn, + NotShowIn: app.notShowIn, + DBusActivatable: app.dBusActivatable, + TryExec: app.tryExec, + Exec: app.name, + Path: app.path, + Terminal: app.terminal, + Actions: app.actions, + MimeType: app.mimeType, + Categories: app.categories, + Implements: app.implements, + Keywords: app.keywords, + StartupNotify: app.startupNotify, + StartupWMClass: app.startupWMClass, + PrefersNonDefaultGPU: app.prefersNonDefaultGPU, + SingleMainWindow: app.singleMainWindow, + }; + + await rename(`${outDir}/nw`, `${outDir}/${app.name}`); + + let fileContent = `[Desktop Entry]\n`; + Object.keys(desktopEntryFile).forEach((key) => { + if (desktopEntryFile[key] !== undefined) { + fileContent += `${key}=${desktopEntryFile[key]}\n`; } - } else if (platform === "osx") { - if (PLATFORM === "win32") { - console.warn( - "MacOS apps built on Windows platform do not preserve all file permissions. See #716", - ); + }); + let filePath = `${outDir}/${app.name}.desktop`; + await writeFile(filePath, fileContent); +}; + +const setWinConfig = async ({ app, outDir }) => { + let versionString = { + Comments: app.comments, + CompanyName: app.author, + FileDescription: app.fileDescription, + FileVersion: app.fileVersion, + InternalName: app.name, + LegalCopyright: app.legalCopyright, + LegalTrademarks: app.legalTrademark, + OriginalFilename: app.name, + PrivateBuild: app.name, + ProductName: app.name, + ProductVersion: app.version, + SpecialBuild: app.name, + }; + + Object.keys(versionString).forEach((option) => { + if (versionString[option] === undefined) { + delete versionString[option]; } + }); - try { - const outApp = resolve(outDir, `${app.name}.app`); - await rename(resolve(outDir, "nwjs.app"), outApp); - if (app.icon !== undefined) { - await copyFile( - resolve(app.icon), - resolve(outApp, "Contents", "Resources", "app.icns"), - ); - } + const rcEditOptions = { + "file-version": app.version, + "product-version": app.version, + "version-string": versionString, + }; - const infoPlistPath = resolve(outApp, "Contents", "Info.plist"); - const infoPlistJson = plist.parse(await readFile(infoPlistPath, "utf-8")); + if (app.icon) { + rcEditOptions.icon = app.icon; + } - const infoPlistStringsPath = resolve( - outApp, - "Contents", - "Resources", - "en.lproj", - "InfoPlist.strings", - ); - const infoPlistStringsData = await readFile( - infoPlistStringsPath, - "utf-8", - ); + try { + const outDirAppExe = resolve(outDir, `${app.name}.exe`); + await rename(resolve(outDir, "nw.exe"), outDirAppExe); + await rcedit(outDirAppExe, rcEditOptions); + } catch (error) { + console.warn( + "Renaming EXE failed or unable to modify EXE. If it's the latter, ensure WINE is installed or build your application Windows platform", + ); + console.error(error); + } +}; - let infoPlistStringsDataArray = infoPlistStringsData.split("\n"); - - infoPlistStringsDataArray.forEach((line, idx, arr) => { - if (line.includes("NSHumanReadableCopyright")) { - arr[idx] = - `NSHumanReadableCopyright = "${app.NSHumanReadableCopyright}";`; - } - }); - - infoPlistJson.LSApplicationCategoryType = app.LSApplicationCategoryType; - infoPlistJson.CFBundleIdentifier = app.CFBundleIdentifier; - infoPlistJson.CFBundleName = app.CFBundleName; - infoPlistJson.CFBundleDisplayName = app.CFBundleDisplayName; - infoPlistJson.CFBundleSpokenName = app.CFBundleSpokenName; - infoPlistJson.CFBundleVersion = app.CFBundleVersion; - infoPlistJson.CFBundleShortVersionString = app.CFBundleShortVersionString; - - Object.keys(infoPlistJson).forEach((option) => { - if (infoPlistJson[option] === undefined) { - delete infoPlistJson[option]; - } - }); - - await writeFile(infoPlistPath, plist.build(infoPlistJson)); - await writeFile( - infoPlistStringsPath, - infoPlistStringsDataArray.toString().replace(/,/g, "\n"), +const setOsxConfig = async ({ outDir, app }) => { + if (PLATFORM === "win32") { + console.warn( + "MacOS apps built on Windows platform do not preserve all file permissions. See #716", + ); + } + + try { + const outApp = resolve(outDir, `${app.name}.app`); + await rename(resolve(outDir, "nwjs.app"), outApp); + if (app.icon !== undefined) { + await copyFile( + resolve(app.icon), + resolve(outApp, "Contents", "Resources", "app.icns"), ); - } catch (error) { - console.error(error); } - } - if (nativeAddon === "gyp") { - let nodePath = resolve(cacheDir, `node-v${version}-${platform}-${arch}`); - chdir( - resolve( - outDir, - platform !== "osx" - ? "package.nw" - : "nwjs.app/Contents/Resources/app.nw", - ), + const infoPlistPath = resolve(outApp, "Contents", "Info.plist"); + const infoPlistJson = plist.parse(await readFile(infoPlistPath, "utf-8")); + + const infoPlistStringsPath = resolve( + outApp, + "Contents", + "Resources", + "en.lproj", + "InfoPlist.strings", + ); + const infoPlistStringsData = await readFile( + infoPlistStringsPath, + "utf-8", ); - exec( - `node-gyp rebuild --target=${nodeVersion} --nodedir=${nodePath}`, - (error) => { - if (error !== null) { - console.error(error); - } - }, + let infoPlistStringsDataArray = infoPlistStringsData.split("\n"); + + infoPlistStringsDataArray.forEach((line, idx, arr) => { + if (line.includes("NSHumanReadableCopyright")) { + arr[idx] = + `NSHumanReadableCopyright = "${app.NSHumanReadableCopyright}";`; + } + }); + + infoPlistJson.LSApplicationCategoryType = app.LSApplicationCategoryType; + infoPlistJson.CFBundleIdentifier = app.CFBundleIdentifier; + infoPlistJson.CFBundleName = app.CFBundleName; + infoPlistJson.CFBundleDisplayName = app.CFBundleDisplayName; + infoPlistJson.CFBundleSpokenName = app.CFBundleSpokenName; + infoPlistJson.CFBundleVersion = app.CFBundleVersion; + infoPlistJson.CFBundleShortVersionString = app.CFBundleShortVersionString; + + Object.keys(infoPlistJson).forEach((option) => { + if (infoPlistJson[option] === undefined) { + delete infoPlistJson[option]; + } + }); + + await writeFile(infoPlistPath, plist.build(infoPlistJson)); + await writeFile( + infoPlistStringsPath, + infoPlistStringsDataArray.toString().replace(/,/g, "\n"), ); + } catch (error) { + console.error(error); } +}; + +const buildNativeAddon = ({ cacheDir, version, platform, arch, outDir, nodeVersion }) => { + let nodePath = resolve(cacheDir, `node-v${version}-${platform}-${arch}`); + chdir( + resolve( + outDir, + platform !== "osx" + ? "package.nw" + : "nwjs.app/Contents/Resources/app.nw", + ), + ); + + exec( + `node-gyp rebuild --target=${nodeVersion} --nodedir=${nodePath}`, + (error) => { + if (error !== null) { + console.error(error); + } + }, + ); +}; - if (zip !== false) { - if (zip === true || zip === "zip") { - await compressing.zip.compressDir(outDir, `${outDir}.zip`); - } else if (zip === "tar") { - await compressing.tar.compressDir(outDir, `${outDir}.tar`); - } else if (zip === "tgz") { - await compressing.tgz.compressDir(outDir, `${outDir}.tgz`); - } - - await rm(outDir, { recursive: true, force: true }); +const compress = async ({ + zip, + outDir, +}) => { + if (zip === true || zip === "zip") { + await compressing.zip.compressDir(outDir, `${outDir}.zip`); + } else if (zip === "tar") { + await compressing.tar.compressDir(outDir, `${outDir}.tar`); + } else if (zip === "tgz") { + await compressing.tgz.compressDir(outDir, `${outDir}.tgz`); } -} + + await rm(outDir, { recursive: true, force: true }); +}; \ No newline at end of file