From e943610e689a40d2ea759ee0724f50a0794eb34e Mon Sep 17 00:00:00 2001 From: Dan Bornstein Date: Tue, 21 May 2024 14:10:43 -0700 Subject: [PATCH] Run `postinstall` scripts defined by _local_ modules. (We trust local modules, not the npm-sourced riff-raff.) --- .../bashy-node/node-project/build-main-module | 29 +++++++++++++++++++ .../node-project/find-module-dependencies.mjs | 20 ++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/scripts/lib/bashy-node/node-project/build-main-module b/scripts/lib/bashy-node/node-project/build-main-module index 74f8020..a77f515 100755 --- a/scripts/lib/bashy-node/node-project/build-main-module +++ b/scripts/lib/bashy-node/node-project/build-main-module @@ -153,6 +153,7 @@ function build-project { && copy-scripts "${srcMainModule}" "${destDir}" \ && copy-local-modules "${destLocalModules}" "${deps}" \ && remove-dead-local-modules "${destLocalModules}" "${deps}" \ + && run-postinstall-scripts "${destLocalModules}" "$(jget "${deps}" '.postinstallScripts')" \ || return "$?" # Do `npm install`, but only if it hasn't yet been done _or_ the top-level @@ -403,6 +404,34 @@ function remove-dead-local-modules { fi } +# Runs any `postinstall` scripts defined by local modules. +function run-postinstall-scripts { + local destLocalModules="$1" + local scriptModules="$2" + + if [[ ${scriptModules} == '[]' ]]; then + return + fi + + progress-msg 'Running local-module postinstall scripts...' + + local modArray=() + jset-array --raw modArray "${scriptModules}" + + # `(...)` to preserve the `cwd` in this process. + ( + cd "${destLocalModules}" + local m + for m in "${modArray[@]}"; do + progress-msg "Postinstall ${m}..." + npm explore "${m}" -- npm run postinstall \ + || return "$?" + done + ) + + progress-msg 'Done running local-module postinstall scripts.' +} + # Checks a `node_modules` directory (or similar) for "suspect" files, given a # desire to have a platform-agnostic build. function suspect-file-check { diff --git a/scripts/lib/bashy-node/node-project/find-module-dependencies.mjs b/scripts/lib/bashy-node/node-project/find-module-dependencies.mjs index 37aa26c..0d1a444 100644 --- a/scripts/lib/bashy-node/node-project/find-module-dependencies.mjs +++ b/scripts/lib/bashy-node/node-project/find-module-dependencies.mjs @@ -84,6 +84,9 @@ const processed = new Set(); /** The graph of local module dependencies, as a list of edges. */ let graph = []; +/** Map from module names to corresponding parsed package files. */ +const packageFiles = new Map(); + /** Map from external dependency names to sets of all encountered versions. */ const extDeps = new Map(); @@ -126,6 +129,7 @@ while (unprocessed.size > 0) { } localDirs.set(oneDep, moduleDir); + packageFiles.set(oneDep, packageObj); for (const [key, value] of Object.entries(packageObj.dependencies ?? {})) { if (key.startsWith('@this/')) { @@ -146,11 +150,19 @@ while (unprocessed.size > 0) { // Build up the final result. +const postinstallScripts = []; +for (const [name, obj] of packageFiles) { + if (obj.scripts?.postinstall) { + postinstallScripts.push(name); + } +} + const result = { - main: `@this/${mainModule}`, - localDeps: [...localDeps].sort(), - localDirs: sortObject(Object.fromEntries(localDirs.entries())), - extDeps: sortObject(Object.fromEntries(extDeps.entries())) + main: `@this/${mainModule}`, + localDeps: [...localDeps].sort(), + localDirs: sortObject(Object.fromEntries(localDirs.entries())), + extDeps: sortObject(Object.fromEntries(extDeps.entries())), + postinstallScripts }; // `extDeps` has sets for values. Reduce them to single elements, and report an