diff options
author | Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> | 2024-07-09 20:06:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-10 03:06:08 +0000 |
commit | ce7dc2be92499f15b4b0315bfca3ee9d61fc3c5e (patch) | |
tree | f2463a8026d6f68d288c04b8671ce26f310de9fe /cli/npm/managed/resolvers/local | |
parent | eb46296e974c686896486350bb00bf428a84e9fd (diff) |
feat(node): Support executing npm package lifecycle scripts (preinstall/install/postinstall) (#24487)
Adds support for running npm package lifecycle scripts, opted into via a
new `--allow-scripts` flag.
With this PR, when running `deno cache` (or `DENO_FUTURE=1 deno
install`) you can specify the `--allow-scripts=pkg1,pkg2` flag to run
lifecycle scripts attached to the given packages.
Note at the moment this only works when `nodeModulesDir` is true (using
the local resolver).
When a package with un-run lifecycle scripts is encountered, we emit a
warning suggesting things may not work and to try running lifecycle
scripts. Additionally, if a package script implicitly requires
`node-gyp` and it's not found on the system, we emit a warning.
Extra things in this PR:
- Extracted out bits of `task.rs` into a separate module for reuse
- Added a couple fields to `process.config` in order to support
`node-gyp` (it relies on a few variables being there)
- Drive by fix to downloading new npm packages to test registry
---
TODO:
- [x] validation for allow-scripts args (make sure it looks like an npm
package)
- [x] make allow-scripts matching smarter
- [ ] figure out what issues this closes
---
Review notes:
- This adds a bunch of deps to our test registry due to using
`node-gyp`, so it's pretty noisy
Diffstat (limited to 'cli/npm/managed/resolvers/local')
-rw-r--r-- | cli/npm/managed/resolvers/local/bin_entries.rs | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/cli/npm/managed/resolvers/local/bin_entries.rs b/cli/npm/managed/resolvers/local/bin_entries.rs index 4a3c5ce4f..980a2653b 100644 --- a/cli/npm/managed/resolvers/local/bin_entries.rs +++ b/cli/npm/managed/resolvers/local/bin_entries.rs @@ -71,19 +71,16 @@ impl BinEntries { self.entries.push((package, package_path)); } - /// Finish setting up the bin entries, writing the necessary files - /// to disk. - pub(super) fn finish( - mut self, + fn for_each_entry( + &mut self, snapshot: &NpmResolutionSnapshot, - bin_node_modules_dir_path: &Path, + mut f: impl FnMut( + &NpmResolutionPackage, + &Path, + &str, // bin name + &str, // bin script + ) -> Result<(), AnyError>, ) -> Result<(), AnyError> { - if !self.entries.is_empty() && !bin_node_modules_dir_path.exists() { - std::fs::create_dir_all(bin_node_modules_dir_path).with_context( - || format!("Creating '{}'", bin_node_modules_dir_path.display()), - )?; - } - if !self.collisions.is_empty() { // walking the dependency tree to find out the depth of each package // is sort of expensive, so we only do it if there's a collision @@ -101,13 +98,7 @@ impl BinEntries { // we already set up a bin entry with this name continue; } - set_up_bin_entry( - package, - name, - script, - package_path, - bin_node_modules_dir_path, - )?; + f(package, package_path, name, script)?; } deno_npm::registry::NpmPackageVersionBinEntry::Map(entries) => { for (name, script) in entries { @@ -115,13 +106,7 @@ impl BinEntries { // we already set up a bin entry with this name continue; } - set_up_bin_entry( - package, - name, - script, - package_path, - bin_node_modules_dir_path, - )?; + f(package, package_path, name, script)?; } } } @@ -130,6 +115,47 @@ impl BinEntries { Ok(()) } + + /// Collect the bin entries into a vec of (name, script path) + pub(super) fn into_bin_files( + mut self, + snapshot: &NpmResolutionSnapshot, + ) -> Vec<(String, PathBuf)> { + let mut bins = Vec::new(); + self + .for_each_entry(snapshot, |_, package_path, name, script| { + bins.push((name.to_string(), package_path.join(script))); + Ok(()) + }) + .unwrap(); + bins + } + + /// Finish setting up the bin entries, writing the necessary files + /// to disk. + pub(super) fn finish( + mut self, + snapshot: &NpmResolutionSnapshot, + bin_node_modules_dir_path: &Path, + ) -> Result<(), AnyError> { + if !self.entries.is_empty() && !bin_node_modules_dir_path.exists() { + std::fs::create_dir_all(bin_node_modules_dir_path).with_context( + || format!("Creating '{}'", bin_node_modules_dir_path.display()), + )?; + } + + self.for_each_entry(snapshot, |package, package_path, name, script| { + set_up_bin_entry( + package, + name, + script, + package_path, + bin_node_modules_dir_path, + ) + })?; + + Ok(()) + } } // walk the dependency tree to find out the depth of each package |