summaryrefslogtreecommitdiff
path: root/cli/npm/managed/resolvers/local.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2024-05-24 00:43:38 +0100
committerGitHub <noreply@github.com>2024-05-23 23:43:38 +0000
commit92a8d09e498712aec2ba0e54a1ad85194ebd83af (patch)
treed26e89bb46850665b2ed357a11718d8148850880 /cli/npm/managed/resolvers/local.rs
parent959739f609dddacde3bbe9ecede2f409214fb34c (diff)
fix(npm): set up node_modules/.bin/ entries for package that provide bin entrypoints (#23496)
Closes https://github.com/denoland/deno/issues/23036 --------- Co-authored-by: Nathan Whitaker <nathan@deno.com>
Diffstat (limited to 'cli/npm/managed/resolvers/local.rs')
-rw-r--r--cli/npm/managed/resolvers/local.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs
index 9d0ca3f8c..055fdfb23 100644
--- a/cli/npm/managed/resolvers/local.rs
+++ b/cli/npm/managed/resolvers/local.rs
@@ -2,6 +2,8 @@
//! Code for local node_modules resolution.
+mod bin_entries;
+
use std::borrow::Cow;
use std::cmp::Ordering;
use std::collections::HashMap;
@@ -24,6 +26,7 @@ use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
+use deno_core::parking_lot::Mutex;
use deno_core::unsync::spawn;
use deno_core::unsync::JoinHandle;
use deno_core::url::Url;
@@ -262,6 +265,10 @@ async fn sync_resolution_with_fs(
fs::create_dir_all(&deno_node_modules_dir).with_context(|| {
format!("Creating '{}'", deno_local_registry_dir.display())
})?;
+ let bin_node_modules_dir_path = root_node_modules_dir_path.join(".bin");
+ fs::create_dir_all(&bin_node_modules_dir_path).with_context(|| {
+ format!("Creating '{}'", bin_node_modules_dir_path.display())
+ })?;
let single_process_lock = LaxSingleProcessFsFlag::lock(
deno_local_registry_dir.join(".deno.lock"),
@@ -286,6 +293,7 @@ async fn sync_resolution_with_fs(
Vec::with_capacity(package_partitions.packages.len());
let mut newest_packages_by_name: HashMap<&String, &NpmResolutionPackage> =
HashMap::with_capacity(package_partitions.packages.len());
+ let bin_entries_to_setup = Arc::new(Mutex::new(Vec::with_capacity(16)));
for package in &package_partitions.packages {
if let Some(current_pkg) =
newest_packages_by_name.get_mut(&package.id.nv.name)
@@ -313,6 +321,7 @@ async fn sync_resolution_with_fs(
let pb = progress_bar.clone();
let cache = cache.clone();
let package = package.clone();
+ let bin_entries_to_setup = bin_entries_to_setup.clone();
let handle = spawn(async move {
cache.ensure_package(&package.id.nv, &package.dist).await?;
let pb_guard = pb.update_with_prompt(
@@ -334,6 +343,13 @@ async fn sync_resolution_with_fs(
}
// write out a file that indicates this folder has been initialized
fs::write(initialized_file, "")?;
+
+ if package.bin.is_some() {
+ bin_entries_to_setup
+ .lock()
+ .push((package.clone(), package_path));
+ }
+
// finally stop showing the progress bar
drop(pb_guard); // explicit for clarity
Ok(())
@@ -464,6 +480,50 @@ async fn sync_resolution_with_fs(
}
}
+ // 6. Set up `node_modules/.bin` entries for packages that need it.
+ {
+ let bin_entries = bin_entries_to_setup.lock();
+ if !bin_entries.is_empty() && !bin_node_modules_dir_path.exists() {
+ fs::create_dir_all(&bin_node_modules_dir_path).with_context(|| {
+ format!("Creating '{}'", bin_node_modules_dir_path.display())
+ })?;
+ }
+ for (package, package_path) in &*bin_entries {
+ let package = snapshot.package_from_id(&package.id).unwrap();
+ if let Some(bin_entries) = &package.bin {
+ match bin_entries {
+ deno_npm::registry::NpmPackageVersionBinEntry::String(script) => {
+ // the default bin name doesn't include the organization
+ let name = package
+ .id
+ .nv
+ .name
+ .rsplit_once('/')
+ .map_or(package.id.nv.name.as_str(), |(_, name)| name);
+ bin_entries::set_up_bin_entry(
+ package,
+ name,
+ script,
+ package_path,
+ &bin_node_modules_dir_path,
+ )?;
+ }
+ deno_npm::registry::NpmPackageVersionBinEntry::Map(entries) => {
+ for (name, script) in entries {
+ bin_entries::set_up_bin_entry(
+ package,
+ name,
+ script,
+ package_path,
+ &bin_node_modules_dir_path,
+ )?;
+ }
+ }
+ }
+ }
+ }
+ }
+
setup_cache.save();
drop(single_process_lock);
drop(pb_clear_guard);