From dffc36208654a0236de446ba552ddee0768a9baa Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:41:48 -0500 Subject: [PATCH 1/8] chore(docs): update maintainer guidelines --- README.md | 1 + src/get/index.js | 0 2 files changed, 1 insertion(+) create mode 100644 src/get/index.js diff --git a/README.md b/README.md index 5216b45a4..73b43d2ef 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,7 @@ nwbuild({ - A commit's first line should be formatted as `[optional scope]: `. - A commit's body should have a description of changes in bullet points followed by any links it references or issues it fixes or closes. It may include an optional `Notes: ...` section to provide additional context on why the PR is being merged when it doesn't seem like it should. - Google's Release Please Action is used to update the changelog, bump the package version and generate GitHub releases. +- NPM Publish Action publishes to `npm` if there is a version bump. ## Roadmap diff --git a/src/get/index.js b/src/get/index.js new file mode 100644 index 000000000..e69de29bb From 7e7ba26e6f42af06b02aa2fa302b782b0e386d4a Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:13:36 -0500 Subject: [PATCH 2/8] chore(get): factor get impl --- src/get.js | 232 ------------------------------------------ src/get/decompress.js | 5 +- src/get/index.js | 179 ++++++++++++++++++++++++++++++++ src/index.js | 2 +- 4 files changed, 182 insertions(+), 236 deletions(-) delete mode 100644 src/get.js diff --git a/src/get.js b/src/get.js deleted file mode 100644 index 455da9872..000000000 --- a/src/get.js +++ /dev/null @@ -1,232 +0,0 @@ -import fs from "node:fs"; -import https from "node:https"; -import path from "node:path"; - -import progress from "cli-progress"; -import tar from "tar"; - -import decompress, { unzip } from "./get/decompress.js"; -import nw from "./get/nw.js"; - -import util from "./util.js"; - -/** - * @typedef {object} GetOptions - * @property {string | "latest" | "stable" | "lts"} [version = "latest"] Runtime version - * @property {"normal" | "sdk"} [flavor = "normal"] Build flavor - * @property {"linux" | "osx" | "win"} [platform] Target platform - * @property {"ia32" | "x64" | "arm64"} [arch] Target arch - * @property {string} [downloadUrl = "https://dl.nwjs.io"] Download server - * @property {string} [cacheDir = "./cache"] Cache directory - * @property {boolean} [cache = true] If false, remove cache and redownload. - * @property {boolean} [ffmpeg = false] If true, ffmpeg is not downloaded. - * @property {false | "gyp"} [nativeAddon = false] Rebuild native modules - */ - -/** - * Get binaries. - * - * @async - * @function - * @param {GetOptions} options Get mode options - * @return {Promise} - */ -async function get(options) { - - const cacheDirExists = await util.fileExists(options.cacheDir); - if (cacheDirExists === false) { - await fs.promises.mkdir(options.cacheDir, { recursive: true }); - } - - let nwFilePath = path.resolve( - options.cacheDir, - `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.${options.platform === "linux" ? "tar.gz" : "zip" - }`, - ); - - let nwDirPath = path.resolve( - options.cacheDir, - `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, - ); - - if (options.cache === false) { - await fs.promises.rm(nwFilePath, { - recursive: true, - force: true, - }); - } - - if (util.fileExists(nwFilePath)) { - nwFilePath = await nw(options.downloadUrl, options.version, options.flavor, options.platform, options.arch, options.cacheDir); - } - - await fs.promises.rm(nwDirPath, { recursive: true, force: true }); - - await decompress(nwFilePath, options.cacheDir); - - if (options.platform === "osx") { - await createSymlinks(options); - } - - if (options.ffmpeg === true) { - await getFfmpeg(options); - } - if (options.nativeAddon === "gyp") { - await getNodeHeaders(options); - } -} - -const getFfmpeg = async (options) => { - const nwDir = path.resolve( - options.cacheDir, - `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, - ); - const bar = new progress.SingleBar({}, progress.Presets.rect); - - // If options.ffmpeg is true, then download ffmpeg. - options.downloadUrl = "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"; - let url = `${options.downloadUrl}/${options.version}/${options.version}-${options.platform}-${options.arch}.zip`; - const out = path.resolve(options.cacheDir, `ffmpeg-v${options.version}-${options.platform}-${options.arch}.zip`); - - // If options.cache is false, remove cache. - if (options.cache === false) { - await fs.promises.rm(out, { - recursive: true, - force: true, - }); - } - - // Check if cache exists. - if (fs.existsSync(out) === true) { - await util.unzip(out, nwDir); - return; - } - - const stream = fs.createWriteStream(out); - const request = new Promise((res, rej) => { - https.get(url, (response) => { - // For GitHub releases and mirrors, we need to follow the redirect. - url = response.headers.location; - - https.get(url, (response) => { - let chunks = 0; - bar.start(Number(response.headers["content-length"]), 0); - response.on("data", (chunk) => { - chunks += chunk.length; - bar.increment(); - bar.update(chunks); - }); - - response.on("error", (error) => { - rej(error); - }); - - response.on("end", () => { - bar.stop(); - res(); - }); - - response.pipe(stream); - }); - - response.on("error", (error) => { - rej(error); - }); - }); - }); - - // Remove compressed file after download and decompress. - await request; - await unzip(out, nwDir); - await util.replaceFfmpeg(options.platform, nwDir); -} - -const getNodeHeaders = async (options) => { - const bar = new progress.SingleBar({}, progress.Presets.rect); - const out = path.resolve( - options.cacheDir, - `headers-v${options.version}-${options.platform}-${options.arch}.tar.gz`, - ); - - // If options.cache is false, remove cache. - if (options.cache === false) { - await fs.promises.rm(out, { - recursive: true, - force: true, - }); - } - - if (fs.existsSync(out) === true) { - await tar.extract({ - file: out, - C: options.cacheDir - }); - await fs.promises.rm(path.resolve(options.cacheDir, `node-v${options.version}-${options.platform}-${options.arch}`), { - recursive: true, - force: true, - }); - await fs.promises.rename( - path.resolve(options.cacheDir, "node"), - path.resolve(options.cacheDir, `node-v${options.version}-${options.platform}-${options.arch}`), - ); - return; - } - - const stream = fs.createWriteStream(out); - const request = new Promise((res, rej) => { - const url = `${options.downloadUrl}/v${options.version}/nw-headers-v${options.version}.tar.gz`; - https.get(url, (response) => { - let chunks = 0; - bar.start(Number(response.headers["content-length"]), 0); - response.on("data", (chunk) => { - chunks += chunk.length; - bar.increment(); - bar.update(chunks); - }); - - response.on("error", (error) => { - rej(error); - }); - - response.on("end", () => { - bar.stop(); - res(); - }); - - response.pipe(stream); - }); - }); - - await request; - await tar.extract({ - file: out, - C: options.cacheDir - }); - await fs.promises.rename( - path.resolve(options.cacheDir, "node"), - path.resolve(options.cacheDir, `node-v${options.version}-${options.platform}-${options.arch}`), - ); -} - -const createSymlinks = async (options) => { - let frameworksPath = path.resolve(process.cwd(), options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") - // Allow resolve cacheDir from another directory for prevent crash - if (!fs.lstatSync(frameworksPath).isDirectory()) { - frameworksPath = path.resolve(options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") - } - const symlinks = [ - path.join(frameworksPath, "Helpers"), - path.join(frameworksPath, "Libraries"), - path.join(frameworksPath, "nwjs Framework"), - path.join(frameworksPath, "Resources"), - path.join(frameworksPath, "Versions", "Current"), - ]; - for await (const symlink of symlinks) { - const buffer = await fs.promises.readFile(symlink); - const link = buffer.toString(); - await fs.promises.rm(symlink); - await fs.promises.symlink(link, symlink); - } -}; - -export default get; diff --git a/src/get/decompress.js b/src/get/decompress.js index 821401428..c8c7e81c1 100644 --- a/src/get/decompress.js +++ b/src/get/decompress.js @@ -32,18 +32,17 @@ export default async function decompress(filePath, cacheDir) { * @param {string} cacheDir - directory to unzip in * @return {Promise} */ -export async function unzip(zippedFile, cacheDir) { +async function unzip(zippedFile, cacheDir) { await unzipInternal(zippedFile, cacheDir, false).then(() => { unzipInternal(zippedFile, cacheDir, true); }) } /** - * Method for unzip with symlink in theoretical + * Method for unzip with symlink. * * @async * @function - * @param unzipSymlink * @param {string} zippedFile - file path to .zip file * @param {string} cacheDir - directory to unzip in * @param {boolean} unzipSymlink - Using or not symlink diff --git a/src/get/index.js b/src/get/index.js index e69de29bb..c2f1aea9b 100644 --- a/src/get/index.js +++ b/src/get/index.js @@ -0,0 +1,179 @@ +import fs from "node:fs"; +import path from "node:path"; + +import decompress from "./decompress.js"; +import ffmpeg from "./ffmpeg.js"; +import node from "./node.js"; +import nw from "./nw.js"; + +import util from "../util.js"; + +/** + * @typedef {object} GetOptions + * @property {string | "latest" | "stable" | "lts"} [version = "latest"] Runtime version + * @property {"normal" | "sdk"} [flavor = "normal"] Build flavor + * @property {"linux" | "osx" | "win"} [platform] Target platform + * @property {"ia32" | "x64" | "arm64"} [arch] Target arch + * @property {string} [downloadUrl = "https://dl.nwjs.io"] Download server + * @property {string} [cacheDir = "./cache"] Cache directory + * @property {boolean} [cache = true] If false, remove cache and redownload. + * @property {boolean} [ffmpeg = false] If true, ffmpeg is not downloaded. + * @property {false | "gyp"} [nativeAddon = false] Rebuild native modules + */ + +/** + * Get binaries. + * + * @async + * @function + * @param {GetOptions} options Get mode options + * @return {Promise} + */ +async function get(options) { + + const cacheDirExists = await util.fileExists(options.cacheDir); + if (cacheDirExists === false) { + await fs.promises.mkdir(options.cacheDir, { recursive: true }); + } + + /** + * @type {string} + */ + let nwFilePath = path.resolve( + options.cacheDir, + `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.${options.platform === "linux" ? "tar.gz" : "zip" + }`, + ); + + /** + * @type {string} + */ + let nwDirPath = path.resolve( + options.cacheDir, + `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, + ); + + if (options.cache === false) { + await fs.promises.rm(nwFilePath, { + recursive: true, + force: true, + }); + } + + // We remove the nwDir to prevent the edge case where you download with ffmpeg flag enabled + // but want a subsequent build with ffmpeg flag disabled. By removing the directory and + // decompressing it again, we prevent the community ffmpeg files from being left over. + // This is important since the community ffmpeg builds have specific licensing constraints. + await fs.promises.rm(nwDirPath, { recursive: true, force: true }); + + const nwFilePathExists = await util.fileExists(nwFilePath); + if (nwFilePathExists === false) { + nwFilePath = await nw(options.downloadUrl, options.version, options.flavor, options.platform, options.arch, options.cacheDir); + } + + await decompress(nwFilePath, options.cacheDir); + + if (options.platform === "osx") { + await createSymlinks(options); + } + + if (options.ffmpeg === true) { + + let ffmpegFilePath = path.resolve( + options.cacheDir, + `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.zip`, + ); + + if (options.cache === false) { + await fs.promises.rm(ffmpegFilePath, { + recursive: true, + force: true, + }); + } + + const ffmpegFilePathExists = await util.fileExists(ffmpegFilePath); + if (ffmpegFilePathExists === false) { + ffmpegFilePath = await ffmpeg(options.downloadUrl, options.version, options.platform, options.arch, options.cacheDir); + } + + await decompress(ffmpegFilePath, options.cacheDir); + + let ffmpegFileName = ""; + + if (options.platform === "linux") { + ffmpegFileName = "libffmpeg.so"; + } else if (options.platform === "win") { + ffmpegFileName = "ffmpeg.dll"; + } else if (options.platform === "osx") { + ffmpegFileName = "libffmpeg.dylib"; + } + + let ffmpegBinaryPath = path.resolve(nwDirPath, ffmpegFileName); + let ffmpegBinaryDest = ""; + if (options.platform === "linux") { + ffmpegBinaryDest = path.resolve(nwDirPath, "lib", ffmpegFileName); + } else if (options.platform === "win") { + // Extracted file is already in the correct path + } else if (options.platform === "osx") { + ffmpegBinaryDest = path.resolve( + nwDirPath, + "nwjs.app", + "Contents", + "Frameworks", + "nwjs Framework.framework", + "Versions", + "Current", + ffmpegFileName, + ); + } + + await fs.promises.copyFile(ffmpegBinaryPath, ffmpegBinaryDest); + + } + + if (options.nativeAddon === "gyp") { + + let nodeFilePath = path.resolve( + options.cacheDir, + `headers-v${options.version}.tar.gz`, + ); + + if (options.cache === false) { + await fs.promises.rm(nodeFilePath, { + recursive: true, + force: true, + }); + } + + const nodeFilePathExists = await util.fileExists(nodeFilePath); + if (nodeFilePathExists === false) { + nodeFilePath = await node(options.downloadUrl, options.version, options.cacheDir); + } + + await decompress(nodeFilePath, options.cacheDir); + + } +} + +const createSymlinks = async (options) => { + let frameworksPath = path.resolve(process.cwd(), options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") + // Allow resolve cacheDir from another directory for prevent crash + if (!fs.lstatSync(frameworksPath).isDirectory()) { + frameworksPath = path.resolve(options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") + } + const symlinks = [ + path.join(frameworksPath, "Helpers"), + path.join(frameworksPath, "Libraries"), + path.join(frameworksPath, "nwjs Framework"), + path.join(frameworksPath, "Resources"), + path.join(frameworksPath, "Versions", "Current"), + ]; + for await (const symlink of symlinks) { + const buffer = await fs.promises.readFile(symlink); + const link = buffer.toString(); + await fs.promises.rm(symlink); + await fs.promises.symlink(link, symlink); + } +}; + +export default get; diff --git a/src/index.js b/src/index.js index d166f5dce..ea47c6c83 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ import fs from "node:fs"; import fsm from "node:fs/promises"; import bld from "./bld.js"; -import get from "./get.js"; +import get from "./get/index.js"; import run from "./run.js"; import util from "./util.js"; From 97568bbac2892d0a819bcfe0fe6c654bde668477 Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:17:38 -0500 Subject: [PATCH 3/8] fix(test): update imports --- test/specs/bld.test.js | 2 +- test/specs/get.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/specs/bld.test.js b/test/specs/bld.test.js index 8de7999f8..d1a64bbfe 100644 --- a/test/specs/bld.test.js +++ b/test/specs/bld.test.js @@ -7,7 +7,7 @@ import chrome from "selenium-webdriver/chrome.js"; import { beforeAll, describe, it } from "vitest"; import build from "../../src/bld.js"; -import get from "../../src/get.js"; +import get from "../../src/get/index.js"; import util from "../../src/util.js"; const { Driver, ServiceBuilder, Options } = chrome; diff --git a/test/specs/get.test.js b/test/specs/get.test.js index 66428dd0b..f1ec05ab3 100644 --- a/test/specs/get.test.js +++ b/test/specs/get.test.js @@ -5,7 +5,7 @@ import process from "node:process"; import { beforeAll, describe, it } from "vitest"; -import get from '../../src/get.js'; +import get from '../../src/get/index.js'; describe("get", async () => { const nwOptions = { From a605cf84623838c81466f835dd5200b96458fbb7 Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:20:44 -0500 Subject: [PATCH 4/8] chore(util): remove redudant ffmpeg method --- src/util.js | 55 +---------------------------------------------------- 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/src/util.js b/src/util.js index 00550483a..be806b24f 100644 --- a/src/util.js +++ b/src/util.js @@ -104,59 +104,6 @@ const EXE_NAME = { linux: "nw", }; -/** - * Replaces the ffmpeg file in the nwjs directory with the one provided - * - * @param {string} platform The platform to replace the ffmpeg file for - * @param {string} nwDir The directory of the nwjs installation - */ -const replaceFfmpeg = async (platform, nwDir) => { - let ffmpegFile; - if (platform === "linux") { - ffmpegFile = "libffmpeg.so"; - } else if (platform === "win") { - ffmpegFile = "ffmpeg.dll"; - } else if (platform === "osx") { - ffmpegFile = "libffmpeg.dylib"; - } - const src = path.resolve(nwDir, ffmpegFile); - if (platform === "linux") { - const dest = path.resolve(nwDir, "lib", ffmpegFile); - await fs.promises.copyFile(src, dest); - } else if (platform === "win") { - // don't do anything for windows because the extracted file is already in the correct path - // await copyFile(src, path.resolve(nwDir, ffmpegFile)); - } else if (platform === "osx") { - let dest = path.resolve( - nwDir, - "nwjs.app", - "Contents", - "Frameworks", - "nwjs Framework.framework", - "Versions", - "Current", - ffmpegFile, - ); - - try { - await fs.promises.copyFile(src, dest); - } catch (e) { - //some versions of node/macOS complain about destination being a file, and others complain when it is only a directory. - //the only thing I can think to do is to try both - dest = path.resolve( - nwDir, - "nwjs.app", - "Contents", - "Frameworks", - "nwjs Framework.framework", - "Versions", - "Current", - ); - await fs.promises.copyFile(src, dest); - } - } -}; - /** * Glob files * @@ -482,4 +429,4 @@ async function fileExists(filePath) { return exists; } -export default { fileExists, getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, replaceFfmpeg, globFiles, getNodeManifest, parse, validate }; +export default { fileExists, getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate }; From ff34c9f0976fa15f8ca9e6fba15f401abdb3ccdd Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 19:53:48 -0500 Subject: [PATCH 5/8] chore(get): annotate variables and functions --- README.md | 3 ++- src/get/decompress.js | 5 ++++ src/get/index.js | 57 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 73b43d2ef..fe734c4f9 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ nwbuild({ - chore(cli): migrate from `yargs` to `commander` - chore(get): verify sha checksum for downloads -- chore(util): factor out file paths as constant variables +- chore: annotate file paths as `fs.PathLike` instead of `string`. - chore(bld): factor out core build step - chore(bld): factor out linux config - chore(bld): factor out macos config @@ -308,6 +308,7 @@ nwbuild({ - chore(bld): factor out compressing - chore(bld): factor out managed manifest - chore(bld): move `.desktop` entry file logic to `create-desktop-shortcuts` package +- chore(util): factor out file paths as constant variables ## FAQ diff --git a/src/get/decompress.js b/src/get/decompress.js index c8c7e81c1..a2a4a08a8 100644 --- a/src/get/decompress.js +++ b/src/get/decompress.js @@ -40,6 +40,11 @@ async function unzip(zippedFile, cacheDir) { /** * Method for unzip with symlink. + * + * Workaround for not being able to handle symlinks. + * Tracking in linked issue. + * + * @link https://github.com/overlookmotel/yauzl-promise/issues/39 * * @async * @function diff --git a/src/get/index.js b/src/get/index.js index c2f1aea9b..c62cec97b 100644 --- a/src/get/index.js +++ b/src/get/index.js @@ -31,12 +31,19 @@ import util from "../util.js"; */ async function get(options) { + /** + * If `options.cacheDir` exists, then `true`. Otherwise, it is `false`. + * + * @type {boolean} + */ const cacheDirExists = await util.fileExists(options.cacheDir); if (cacheDirExists === false) { await fs.promises.mkdir(options.cacheDir, { recursive: true }); } /** + * File path to compressed binary. + * * @type {string} */ let nwFilePath = path.resolve( @@ -46,6 +53,8 @@ async function get(options) { ); /** + * File path to directory which contain NW.js and related binaries. + * * @type {string} */ let nwDirPath = path.resolve( @@ -53,6 +62,7 @@ async function get(options) { `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, ); + // If `options.cache` is false, then remove the compressed binary. if (options.cache === false) { await fs.promises.rm(nwFilePath, { recursive: true, @@ -66,6 +76,11 @@ async function get(options) { // This is important since the community ffmpeg builds have specific licensing constraints. await fs.promises.rm(nwDirPath, { recursive: true, force: true }); + /** + * If the compressed binary exists, then `true`. Otherwise, it is `false`. + * + * @type {boolean} + */ const nwFilePathExists = await util.fileExists(nwFilePath); if (nwFilePathExists === false) { nwFilePath = await nw(options.downloadUrl, options.version, options.flavor, options.platform, options.arch, options.cacheDir); @@ -73,17 +88,25 @@ async function get(options) { await decompress(nwFilePath, options.cacheDir); + // TODO: remove once linked issue is resolved. + // https://github.com/overlookmotel/yauzl-promise/issues/39 if (options.platform === "osx") { await createSymlinks(options); } if (options.ffmpeg === true) { + /** + * File path to compressed binary which contains community FFmpeg binary. + * + * @type {string} + */ let ffmpegFilePath = path.resolve( options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.zip`, ); + // If `options.cache` is false, then remove the compressed binary. if (options.cache === false) { await fs.promises.rm(ffmpegFilePath, { recursive: true, @@ -98,6 +121,11 @@ async function get(options) { await decompress(ffmpegFilePath, options.cacheDir); + /** + * Platform dependant file name of FFmpeg binary. + * + * @type {string} + */ let ffmpegFileName = ""; if (options.platform === "linux") { @@ -108,8 +136,20 @@ async function get(options) { ffmpegFileName = "libffmpeg.dylib"; } + /** + * File path to platform specific FFmpeg file. + * + * @type {string} + */ let ffmpegBinaryPath = path.resolve(nwDirPath, ffmpegFileName); + + /** + * File path of where FFmpeg will be copied to. + * + * @type {string} + */ let ffmpegBinaryDest = ""; + if (options.platform === "linux") { ffmpegBinaryDest = path.resolve(nwDirPath, "lib", ffmpegFileName); } else if (options.platform === "win") { @@ -133,11 +173,17 @@ async function get(options) { if (options.nativeAddon === "gyp") { + /** + * File path to NW'js Node headers tarball. + * + * @type {string} + */ let nodeFilePath = path.resolve( options.cacheDir, `headers-v${options.version}.tar.gz`, ); + // If `options.cache` is false, then remove the compressed binary. if (options.cache === false) { await fs.promises.rm(nodeFilePath, { recursive: true, @@ -145,6 +191,11 @@ async function get(options) { }); } + /** + * If the compressed binary exists, then `true`. Otherwise, it is `false`. + * + * @type {boolean} + */ const nodeFilePathExists = await util.fileExists(nodeFilePath); if (nodeFilePathExists === false) { nodeFilePath = await node(options.downloadUrl, options.version, options.cacheDir); @@ -155,6 +206,12 @@ async function get(options) { } } +/** + * Workaround for manually creating symbolic links for MacOS builds. + * Tracking in linked issue. + * @link https://github.com/overlookmotel/yauzl-promise/issues/39 + * @param {*} options + */ const createSymlinks = async (options) => { let frameworksPath = path.resolve(process.cwd(), options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") // Allow resolve cacheDir from another directory for prevent crash From 1555eeb91778738decd2ef58a23618835ef39d43 Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 20:00:47 -0500 Subject: [PATCH 6/8] chore(get): correct annotations --- src/get/decompress.js | 7 +------ src/get/index.js | 33 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/get/decompress.js b/src/get/decompress.js index a2a4a08a8..53ddc1b5e 100644 --- a/src/get/decompress.js +++ b/src/get/decompress.js @@ -39,12 +39,7 @@ async function unzip(zippedFile, cacheDir) { } /** - * Method for unzip with symlink. - * - * Workaround for not being able to handle symlinks. - * Tracking in linked issue. - * - * @link https://github.com/overlookmotel/yauzl-promise/issues/39 + * Method for unzip with symlink. Workaround for not being able to handle symlinks. Tracking in linked issue. * * @async * @function diff --git a/src/get/index.js b/src/get/index.js index c62cec97b..3111d9a05 100644 --- a/src/get/index.js +++ b/src/get/index.js @@ -33,7 +33,7 @@ async function get(options) { /** * If `options.cacheDir` exists, then `true`. Otherwise, it is `false`. - * + * * @type {boolean} */ const cacheDirExists = await util.fileExists(options.cacheDir); @@ -43,7 +43,7 @@ async function get(options) { /** * File path to compressed binary. - * + * * @type {string} */ let nwFilePath = path.resolve( @@ -54,7 +54,7 @@ async function get(options) { /** * File path to directory which contain NW.js and related binaries. - * + * * @type {string} */ let nwDirPath = path.resolve( @@ -78,7 +78,7 @@ async function get(options) { /** * If the compressed binary exists, then `true`. Otherwise, it is `false`. - * + * * @type {boolean} */ const nwFilePathExists = await util.fileExists(nwFilePath); @@ -96,11 +96,11 @@ async function get(options) { if (options.ffmpeg === true) { - /** - * File path to compressed binary which contains community FFmpeg binary. - * - * @type {string} - */ + /** + * File path to compressed binary which contains community FFmpeg binary. + * + * @type {string} + */ let ffmpegFilePath = path.resolve( options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.zip`, @@ -123,7 +123,7 @@ async function get(options) { /** * Platform dependant file name of FFmpeg binary. - * + * * @type {string} */ let ffmpegFileName = ""; @@ -138,14 +138,14 @@ async function get(options) { /** * File path to platform specific FFmpeg file. - * + * * @type {string} */ let ffmpegBinaryPath = path.resolve(nwDirPath, ffmpegFileName); /** * File path of where FFmpeg will be copied to. - * + * * @type {string} */ let ffmpegBinaryDest = ""; @@ -175,7 +175,7 @@ async function get(options) { /** * File path to NW'js Node headers tarball. - * + * * @type {string} */ let nodeFilePath = path.resolve( @@ -193,7 +193,7 @@ async function get(options) { /** * If the compressed binary exists, then `true`. Otherwise, it is `false`. - * + * * @type {boolean} */ const nodeFilePathExists = await util.fileExists(nodeFilePath); @@ -208,9 +208,8 @@ async function get(options) { /** * Workaround for manually creating symbolic links for MacOS builds. - * Tracking in linked issue. - * @link https://github.com/overlookmotel/yauzl-promise/issues/39 - * @param {*} options + * + * @param {object} options - options config */ const createSymlinks = async (options) => { let frameworksPath = path.resolve(process.cwd(), options.cacheDir, `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`, "nwjs.app", "Contents", "Frameworks", "nwjs Framework.framework") From a7c3c4ce09940d52df48066a1a90415c4a242e6a Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 22:17:27 -0500 Subject: [PATCH 7/8] chore(test): update demo --- test/fixture/demo.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/fixture/demo.js b/test/fixture/demo.js index 1abc0101f..5355b123c 100644 --- a/test/fixture/demo.js +++ b/test/fixture/demo.js @@ -3,6 +3,5 @@ import nwbuild from "../../src/index.js"; await nwbuild({ mode: "get", flavor: "sdk", - platform: "osx", - srcDir: "app" + srcDir: "app", }); From 3452ae0cd6d37161d1eb98e482b0060f63ecbd01 Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Fri, 2 Feb 2024 22:21:47 -0500 Subject: [PATCH 8/8] chore(get): update annotations --- README.md | 1 + src/get/index.js | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe734c4f9..aac1113b5 100644 --- a/README.md +++ b/README.md @@ -298,6 +298,7 @@ nwbuild({ ### Chores - chore(cli): migrate from `yargs` to `commander` +- chore(get): investigate [how symlinks are identified](https://github.com/overlookmotel/yauzl-promise/issues/39) and remove the workaround where they are created manually - chore(get): verify sha checksum for downloads - chore: annotate file paths as `fs.PathLike` instead of `string`. - chore(bld): factor out core build step diff --git a/src/get/index.js b/src/get/index.js index 3111d9a05..302de160a 100644 --- a/src/get/index.js +++ b/src/get/index.js @@ -114,6 +114,11 @@ async function get(options) { }); } + /** + * If the compressed binary exists, then `true`. Otherwise, it is `false`. + * + * @type {boolean} + */ const ffmpegFilePathExists = await util.fileExists(ffmpegFilePath); if (ffmpegFilePathExists === false) { ffmpegFilePath = await ffmpeg(options.downloadUrl, options.version, options.platform, options.arch, options.cacheDir); @@ -142,7 +147,7 @@ async function get(options) { * @type {string} */ let ffmpegBinaryPath = path.resolve(nwDirPath, ffmpegFileName); - + /** * File path of where FFmpeg will be copied to. *