From 98abcafeb884a42c34208a6a83f37eb7d518122c Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Sun, 24 Nov 2024 13:29:06 +0530 Subject: [PATCH] feat(get): add options.shaSum to enable/disable shasum checks (#1307) * Fix a manifest not found error * Correctly parse options.* values --- README.md | 1 + src/cli.js | 1 + src/get/index.js | 4 ++++ src/get/verify.js | 13 ++++++++++--- src/index.js | 3 +++ src/util.js | 32 ++++++++++++++++++++++++++------ 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ea80db3e..6e2e85d3 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,7 @@ Options | cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. | | ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. | | logLevel | `"error" \| "warn" \| "info" \| "debug"` | `"info"`| Specify level of logging. | +| shaSum | `boolean` | `true` | Flag to enable/disable shasum checks. | | srcDir | `string` | `"./"` | File paths to application code | | argv | `string[]` | `[]` | Command line arguments to pass to NW executable in run mode. You can also define these in `chromium-args` in NW.js manifest. | | glob | `boolean` | `true`| If true file globbing is enabled when parsing `srcDir`. | diff --git a/src/cli.js b/src/cli.js index 13d1a2b9..f905ff24 100755 --- a/src/cli.js +++ b/src/cli.js @@ -20,6 +20,7 @@ program .option('--ffmpeg ', 'Flag to enable/disable downloading community ffmpeg', false) .option('--glob ', 'Flag to enable/disable globbing', true) .option('--logLevel ', 'Specify log level') + .option('--shaSum ', 'Flag to enable/disable shasum', true) .option('--zip ', 'Flag to enable/disable compression', false) .option('--managedManifest ', 'Managed manifest mode', false) .option('--nodeAddon ', 'Download NW.js Node headers', false); diff --git a/src/get/index.js b/src/get/index.js index f1bb2460..4f14e9fc 100644 --- a/src/get/index.js +++ b/src/get/index.js @@ -21,6 +21,8 @@ import util from '../util.js'; * @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 + * @property {string} [logLevel = 'info'] User defined log level. + * @property {boolean} [shaSum = true] If true shasum is enabled, otherwise disabled. */ /** @@ -98,6 +100,8 @@ async function get(options) { `${options.cacheDir}/shasum/${options.version}.txt`, options.cacheDir, options.ffmpeg, + options.logLevel, + options.shaSum, ); if (options.ffmpeg === true) { diff --git a/src/get/verify.js b/src/get/verify.js index 821c6977..4d9b3f3d 100644 --- a/src/get/verify.js +++ b/src/get/verify.js @@ -11,11 +11,13 @@ import util from '../util.js'; * @param {string} shaUrl - URL to get the shasum text file from. * @param {string} shaOut - File path to shasum text file. * @param {string} cacheDir - File path to cache directory. - * @param {ffmpeg} ffmpeg - Toggle between community (true) and official (false) ffmpeg binary + * @param {boolean} ffmpeg - Toggle between community (true) and official (false) ffmpeg binary + * @param {string} logLevel - User defined log level. + * @param {boolean} shaSum - Throws error if true, otherwise logs a warning. * @throws {Error} * @returns {Promise} - Returns true if the checksums match. */ -export default async function verify(shaUrl, shaOut, cacheDir, ffmpeg) { +export default async function verify(shaUrl, shaOut, cacheDir, ffmpeg, logLevel, shaSum) { const shaOutExists = await util.fileExists(shaOut); if (shaOutExists === false) { @@ -42,7 +44,12 @@ export default async function verify(shaUrl, shaOut, cacheDir, ffmpeg) { if (filePath.includes('ffmpeg') && ffmpeg) { console.warn(`The generated shasum for the community ffmpeg at ${filePath} is ${generatedSha}. The integrity of this file should be manually verified.`); } else { - throw new Error(`SHA256 checksums do not match. The file ${filePath} expected shasum is ${storedSha} but the actual shasum is ${generatedSha}.`); + const message = `SHA256 checksums do not match. The file ${filePath} expected shasum is ${storedSha} but the actual shasum is ${generatedSha}.`; + if (shaSum) { + throw new Error(message); + } else { + util.log('warn', logLevel, message); + } } } } diff --git a/src/index.js b/src/index.js index 29e7431f..4032af0f 100644 --- a/src/index.js +++ b/src/index.js @@ -24,6 +24,7 @@ import util from './util.js'; * @property {boolean} [ffmpeg=false] If true the chromium ffmpeg is replaced by community version * @property {boolean} [glob=true] If true file globbing is enabled when parsing srcDir. * @property {"error" | "warn" | "info" | "debug"} [logLevel="info"] Specify level of logging. + * @property {boolean} [shaSum = true] If true, shasum is enabled. Otherwise, disabled. * @property {boolean | "zip" | "tar" | "tgz"} [zip=false] If true, "zip", "tar" or "tgz" the outDir directory is compressed. * @property {boolean | string | object} [managedManifest = false] Managed manifest mode * @property {false | "gyp"} [nodeAddon = false] Rebuild Node native addons @@ -101,6 +102,8 @@ async function nwbuild(options) { cache: options.cache, ffmpeg: options.ffmpeg, nativeAddon: options.nativeAddon, + shaSum: options.shaSum, + logLevel: options.logLevel, }); if (options.mode === 'get') { diff --git a/src/util.js b/src/util.js index e8609c82..808d8ff7 100644 --- a/src/util.js +++ b/src/util.js @@ -116,9 +116,16 @@ async function globFiles({ glob, }) { let files; + let patterns; if (glob) { files = []; - const patterns = srcDir.split(' '); + patterns = []; + if (Array.isArray(srcDir)) { + patterns = srcDir; + } else { + patterns = srcDir.split(' '); + } + for (const pattern of patterns) { let filePath = await GlobModule.glob(pattern); files.push(...filePath); @@ -149,7 +156,7 @@ async function getNodeManifest({ if (glob) { files = await globFiles({ srcDir, glob }); for (const file of files) { - if (path.basename(file) === 'package.json' && manifest === undefined) { + if (path.basename(file) === 'package.json' && manifest.json === undefined) { manifest.path = file; manifest.json = JSON.parse(await fs.promises.readFile(file)); } @@ -204,6 +211,7 @@ export const parse = async (options, pkg) => { options.cache = str2Bool(options.cache ?? true); options.ffmpeg = str2Bool(options.ffmpeg ?? false); options.logLevel = options.logLevel ?? 'info'; + options.shaSum = options.shaSum ?? true; if (options.mode === 'get') { return { ...options }; @@ -231,7 +239,10 @@ export const parse = async (options, pkg) => { options.app.name = options.app.name.replace(/[<>:"/\\|?*\u0000-\u001F]/g, ''); } /* Path to where the icon currently is in the filesystem */ - options.app.icon = path.resolve(options.app.icon) ?? undefined; + options.app.icon = options.app.icon ?? undefined; + if (options.app.icon) { + options.app.icon = path.resolve(options.app.icon); + } // TODO(#737): move this out if (options.platform === 'linux') { @@ -244,7 +255,10 @@ export const parse = async (options, pkg) => { options.app.notShowIn = options.app.notShowIn ?? undefined; options.app.dBusActivatable = options.app.dBusActivatable ?? undefined; options.app.tryExec = options.app.tryExec ?? undefined; - options.app.exec = path.resolve(options.app.exec) ?? undefined; + options.app.exec = options.app.exec ?? undefined; + if (options.app.exec) { + options.app.exec = path.resolve(options.app.exec); + } options.app.path = options.app.path ?? undefined; options.app.terminal = options.app.terminal ?? undefined; options.app.actions = options.app.actions ?? undefined; @@ -368,11 +382,17 @@ export const validate = async (options, releaseInfo) => { ); } + if (typeof options.shaSum !== 'boolean') { + throw new Error( + 'Expected options.shaSum to be a boolean. Got ' + typeof options.shaSum, + ); + } + if (options.mode === 'get') { return undefined; } - if (typeof options.srcDir !== 'string') { - throw new Error('Expected options.srcDir to be a string. Got ' + typeof options.srcDir); + if (typeof options.srcDir !== 'string' && !Array.isArray(options.srcDir)) { + throw new Error('Expected options.srcDir to be a string or Array. Got ' + typeof options.srcDir); } if (!Array.isArray(options.argv)) { throw new Error(