diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2024-05-24 00:43:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 23:43:38 +0000 |
commit | 92a8d09e498712aec2ba0e54a1ad85194ebd83af (patch) | |
tree | d26e89bb46850665b2ed357a11718d8148850880 /cli/npm/managed/resolvers/local.rs | |
parent | 959739f609dddacde3bbe9ecede2f409214fb34c (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.rs | 60 |
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); |