summaryrefslogtreecommitdiff
path: root/cli/npm/managed/resolvers/common/lifecycle_scripts.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /cli/npm/managed/resolvers/common/lifecycle_scripts.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'cli/npm/managed/resolvers/common/lifecycle_scripts.rs')
-rw-r--r--cli/npm/managed/resolvers/common/lifecycle_scripts.rs57
1 files changed, 43 insertions, 14 deletions
diff --git a/cli/npm/managed/resolvers/common/lifecycle_scripts.rs b/cli/npm/managed/resolvers/common/lifecycle_scripts.rs
index 5735f5248..5c5755c81 100644
--- a/cli/npm/managed/resolvers/common/lifecycle_scripts.rs
+++ b/cli/npm/managed/resolvers/common/lifecycle_scripts.rs
@@ -10,6 +10,7 @@ use deno_runtime::deno_io::FromRawIoHandle;
use deno_semver::package::PackageNv;
use deno_semver::Version;
use std::borrow::Cow;
+use std::collections::HashSet;
use std::rc::Rc;
use std::path::Path;
@@ -61,7 +62,7 @@ impl<'a> LifecycleScripts<'a> {
}
}
-fn has_lifecycle_scripts(
+pub fn has_lifecycle_scripts(
package: &NpmResolutionPackage,
package_path: &Path,
) -> bool {
@@ -83,7 +84,7 @@ fn is_broken_default_install_script(script: &str, package_path: &Path) -> bool {
}
impl<'a> LifecycleScripts<'a> {
- fn can_run_scripts(&self, package_nv: &PackageNv) -> bool {
+ pub fn can_run_scripts(&self, package_nv: &PackageNv) -> bool {
if !self.strategy.can_run_scripts() {
return false;
}
@@ -98,6 +99,9 @@ impl<'a> LifecycleScripts<'a> {
PackagesAllowedScripts::None => false,
}
}
+ pub fn has_run_scripts(&self, package: &NpmResolutionPackage) -> bool {
+ self.strategy.has_run(package)
+ }
/// Register a package for running lifecycle scripts, if applicable.
///
/// `package_path` is the path containing the package's code (its root dir).
@@ -110,12 +114,12 @@ impl<'a> LifecycleScripts<'a> {
) {
if has_lifecycle_scripts(package, &package_path) {
if self.can_run_scripts(&package.id.nv) {
- if !self.strategy.has_run(package) {
+ if !self.has_run_scripts(package) {
self
.packages_with_scripts
.push((package, package_path.into_owned()));
}
- } else if !self.strategy.has_run(package)
+ } else if !self.has_run_scripts(package)
&& (self.config.explicit_install || !self.strategy.has_warned(package))
{
// Skip adding `esbuild` as it is known that it can work properly without lifecycle script
@@ -149,22 +153,32 @@ impl<'a> LifecycleScripts<'a> {
self,
snapshot: &NpmResolutionSnapshot,
packages: &[NpmResolutionPackage],
- root_node_modules_dir_path: Option<&Path>,
+ root_node_modules_dir_path: &Path,
progress_bar: &ProgressBar,
) -> Result<(), AnyError> {
self.warn_not_run_scripts()?;
let get_package_path =
|p: &NpmResolutionPackage| self.strategy.package_path(p);
let mut failed_packages = Vec::new();
+ let mut bin_entries = BinEntries::new();
if !self.packages_with_scripts.is_empty() {
+ let package_ids = self
+ .packages_with_scripts
+ .iter()
+ .map(|(p, _)| &p.id)
+ .collect::<HashSet<_>>();
// get custom commands for each bin available in the node_modules dir (essentially
// the scripts that are in `node_modules/.bin`)
- let base =
- resolve_baseline_custom_commands(snapshot, packages, get_package_path)?;
+ let base = resolve_baseline_custom_commands(
+ &mut bin_entries,
+ snapshot,
+ packages,
+ get_package_path,
+ )?;
let init_cwd = &self.config.initial_cwd;
let process_state = crate::npm::managed::npm_process_state(
snapshot.as_valid_serialized(),
- root_node_modules_dir_path,
+ Some(root_node_modules_dir_path),
);
let mut env_vars = crate::task_runner::real_env_vars();
@@ -221,7 +235,7 @@ impl<'a> LifecycleScripts<'a> {
custom_commands: custom_commands.clone(),
init_cwd,
argv: &[],
- root_node_modules_dir: root_node_modules_dir_path,
+ root_node_modules_dir: Some(root_node_modules_dir_path),
stdio: Some(crate::task_runner::TaskIo {
stderr: TaskStdio::piped(),
stdout: TaskStdio::piped(),
@@ -262,6 +276,17 @@ impl<'a> LifecycleScripts<'a> {
}
self.strategy.did_run_scripts(package)?;
}
+
+ // re-set up bin entries for the packages which we've run scripts for.
+ // lifecycle scripts can create files that are linked to by bin entries,
+ // and the only reliable way to handle this is to re-link bin entries
+ // (this is what PNPM does as well)
+ bin_entries.finish_only(
+ snapshot,
+ &root_node_modules_dir_path.join(".bin"),
+ |outcome| outcome.warn_if_failed(),
+ &package_ids,
+ )?;
}
if failed_packages.is_empty() {
Ok(())
@@ -281,9 +306,10 @@ impl<'a> LifecycleScripts<'a> {
// take in all (non copy) packages from snapshot,
// and resolve the set of available binaries to create
// custom commands available to the task runner
-fn resolve_baseline_custom_commands(
- snapshot: &NpmResolutionSnapshot,
- packages: &[NpmResolutionPackage],
+fn resolve_baseline_custom_commands<'a>(
+ bin_entries: &mut BinEntries<'a>,
+ snapshot: &'a NpmResolutionSnapshot,
+ packages: &'a [NpmResolutionPackage],
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
let mut custom_commands = crate::task_runner::TaskCustomCommands::new();
@@ -306,6 +332,7 @@ fn resolve_baseline_custom_commands(
// doing it for packages that are set up already.
// realistically, scripts won't be run very often so it probably isn't too big of an issue.
resolve_custom_commands_from_packages(
+ bin_entries,
custom_commands,
snapshot,
packages,
@@ -320,12 +347,12 @@ fn resolve_custom_commands_from_packages<
'a,
P: IntoIterator<Item = &'a NpmResolutionPackage>,
>(
+ bin_entries: &mut BinEntries<'a>,
mut commands: crate::task_runner::TaskCustomCommands,
snapshot: &'a NpmResolutionSnapshot,
packages: P,
get_package_path: impl Fn(&'a NpmResolutionPackage) -> PathBuf,
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
- let mut bin_entries = BinEntries::new();
for package in packages {
let package_path = get_package_path(package);
@@ -333,7 +360,7 @@ fn resolve_custom_commands_from_packages<
bin_entries.add(package, package_path);
}
}
- let bins = bin_entries.into_bin_files(snapshot);
+ let bins: Vec<(String, PathBuf)> = bin_entries.collect_bin_files(snapshot);
for (bin_name, script_path) in bins {
commands.insert(
bin_name.clone(),
@@ -356,7 +383,9 @@ fn resolve_custom_commands_from_deps(
snapshot: &NpmResolutionSnapshot,
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
+ let mut bin_entries = BinEntries::new();
resolve_custom_commands_from_packages(
+ &mut bin_entries,
baseline,
snapshot,
package