summaryrefslogtreecommitdiff
path: root/cli/npm
diff options
context:
space:
mode:
Diffstat (limited to 'cli/npm')
-rw-r--r--cli/npm/byonm.rs60
-rw-r--r--cli/npm/managed/mod.rs11
-rw-r--r--cli/npm/managed/resolvers/common.rs14
-rw-r--r--cli/npm/managed/resolvers/global.rs65
-rw-r--r--cli/npm/managed/resolvers/local.rs90
5 files changed, 162 insertions, 78 deletions
diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs
index bbd5da8ec..4abb6b3b2 100644
--- a/cli/npm/byonm.rs
+++ b/cli/npm/byonm.rs
@@ -11,6 +11,8 @@ use deno_core::anyhow::bail;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_runtime::deno_fs::FileSystem;
+use deno_runtime::deno_node::errors::PackageFolderResolveError;
+use deno_runtime::deno_node::errors::PackageFolderResolveErrorKind;
use deno_runtime::deno_node::load_pkg_json;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NpmResolver;
@@ -168,42 +170,50 @@ impl NpmResolver for ByonmCliNpmResolver {
&self,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PackageFolderResolveError> {
fn inner(
fs: &dyn FileSystem,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError> {
- let referrer_file = specifier_to_file_path(referrer)?;
- let mut current_folder = referrer_file.parent().unwrap();
- loop {
- let node_modules_folder = if current_folder.ends_with("node_modules") {
- Cow::Borrowed(current_folder)
- } else {
- Cow::Owned(current_folder.join("node_modules"))
- };
-
- let sub_dir = join_package_name(&node_modules_folder, name);
- if fs.is_dir_sync(&sub_dir) {
- return Ok(sub_dir);
- }
+ ) -> Result<PathBuf, PackageFolderResolveError> {
+ let maybe_referrer_file = specifier_to_file_path(referrer).ok();
+ let maybe_start_folder =
+ maybe_referrer_file.as_ref().and_then(|f| f.parent());
+ if let Some(start_folder) = maybe_start_folder {
+ for current_folder in start_folder.ancestors() {
+ let node_modules_folder = if current_folder.ends_with("node_modules")
+ {
+ Cow::Borrowed(current_folder)
+ } else {
+ Cow::Owned(current_folder.join("node_modules"))
+ };
- if let Some(parent) = current_folder.parent() {
- current_folder = parent;
- } else {
- break;
+ let sub_dir = join_package_name(&node_modules_folder, name);
+ if fs.is_dir_sync(&sub_dir) {
+ return Ok(sub_dir);
+ }
}
}
- bail!(
- "could not find package '{}' from referrer '{}'.",
- name,
- referrer
- );
+ Err(
+ PackageFolderResolveErrorKind::NotFoundPackage {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ referrer_extra: None,
+ }
+ .into(),
+ )
}
let path = inner(&*self.fs, name, referrer)?;
- Ok(self.fs.realpath_sync(&path)?)
+ self.fs.realpath_sync(&path).map_err(|err| {
+ PackageFolderResolveErrorKind::Io {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ source: err.into_io_error(),
+ }
+ .into()
+ })
}
fn in_npm_package(&self, specifier: &ModuleSpecifier) -> bool {
diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs
index 467703b05..6022396d6 100644
--- a/cli/npm/managed/mod.rs
+++ b/cli/npm/managed/mod.rs
@@ -20,6 +20,8 @@ use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FileSystem;
+use deno_runtime::deno_node::errors::PackageFolderResolveError;
+use deno_runtime::deno_node::errors::PackageFolderResolveErrorKind;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NpmResolver;
use deno_semver::package::PackageNv;
@@ -522,12 +524,17 @@ impl NpmResolver for ManagedCliNpmResolver {
&self,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PackageFolderResolveError> {
let path = self
.fs_resolver
.resolve_package_folder_from_package(name, referrer)?;
let path =
- canonicalize_path_maybe_not_exists_with_fs(&path, self.fs.as_ref())?;
+ canonicalize_path_maybe_not_exists_with_fs(&path, self.fs.as_ref())
+ .map_err(|err| PackageFolderResolveErrorKind::Io {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ source: err,
+ })?;
log::debug!("Resolved {} from {} to {}", name, referrer, path.display());
Ok(path)
}
diff --git a/cli/npm/managed/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs
index 35f368cb5..dffa1b75c 100644
--- a/cli/npm/managed/resolvers/common.rs
+++ b/cli/npm/managed/resolvers/common.rs
@@ -18,6 +18,7 @@ use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
use deno_runtime::deno_fs::FileSystem;
+use deno_runtime::deno_node::errors::PackageFolderResolveError;
use deno_runtime::deno_node::NodePermissions;
use crate::npm::managed::cache::TarballCache;
@@ -31,16 +32,25 @@ pub trait NpmPackageFsResolver: Send + Sync {
/// The local node_modules folder if it is applicable to the implementation.
fn node_modules_path(&self) -> Option<&PathBuf>;
+ fn maybe_package_folder(&self, package_id: &NpmPackageId) -> Option<PathBuf>;
+
fn package_folder(
&self,
package_id: &NpmPackageId,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, AnyError> {
+ self.maybe_package_folder(package_id).ok_or_else(|| {
+ deno_core::anyhow::anyhow!(
+ "Package folder not found for '{}'",
+ package_id.as_serialized()
+ )
+ })
+ }
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PackageFolderResolveError>;
fn resolve_package_cache_folder_id_from_specifier(
&self,
diff --git a/cli/npm/managed/resolvers/global.rs b/cli/npm/managed/resolvers/global.rs
index d10b33e7d..d16fe7cd0 100644
--- a/cli/npm/managed/resolvers/global.rs
+++ b/cli/npm/managed/resolvers/global.rs
@@ -8,13 +8,14 @@ use std::sync::Arc;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
-use deno_core::anyhow::bail;
use deno_core::error::AnyError;
use deno_core::url::Url;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FileSystem;
+use deno_runtime::deno_node::errors::PackageFolderResolveError;
+use deno_runtime::deno_node::errors::PackageFolderResolveErrorKind;
use deno_runtime::deno_node::NodePermissions;
use super::super::cache::NpmCache;
@@ -65,29 +66,71 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
None
}
- fn package_folder(&self, id: &NpmPackageId) -> Result<PathBuf, AnyError> {
+ fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let folder_id = self
.resolution
- .resolve_pkg_cache_folder_id_from_pkg_id(id)
- .unwrap();
- Ok(self.cache.package_folder_for_id(&folder_id))
+ .resolve_pkg_cache_folder_id_from_pkg_id(id)?;
+ Some(self.cache.package_folder_for_id(&folder_id))
}
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError> {
- let Some(referrer_pkg_id) = self
+ ) -> Result<PathBuf, PackageFolderResolveError> {
+ use deno_npm::resolution::PackageNotFoundFromReferrerError;
+ let Some(referrer_cache_folder_id) = self
.cache
.resolve_package_folder_id_from_specifier(referrer)
else {
- bail!("could not find npm package for '{}'", referrer);
+ return Err(
+ PackageFolderResolveErrorKind::NotFoundReferrer {
+ referrer: referrer.clone(),
+ referrer_extra: None,
+ }
+ .into(),
+ );
};
- let pkg = self
+ let resolve_result = self
.resolution
- .resolve_package_from_package(name, &referrer_pkg_id)?;
- self.package_folder(&pkg.id)
+ .resolve_package_from_package(name, &referrer_cache_folder_id);
+ match resolve_result {
+ Ok(pkg) => match self.maybe_package_folder(&pkg.id) {
+ Some(folder) => Ok(folder),
+ None => Err(
+ PackageFolderResolveErrorKind::NotFoundPackage {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ referrer_extra: Some(format!(
+ "{} -> {}",
+ referrer_cache_folder_id,
+ pkg.id.as_serialized()
+ )),
+ }
+ .into(),
+ ),
+ },
+ Err(err) => match *err {
+ PackageNotFoundFromReferrerError::Referrer(cache_folder_id) => Err(
+ PackageFolderResolveErrorKind::NotFoundReferrer {
+ referrer: referrer.clone(),
+ referrer_extra: Some(cache_folder_id.to_string()),
+ }
+ .into(),
+ ),
+ PackageNotFoundFromReferrerError::Package {
+ name,
+ referrer: cache_folder_id_referrer,
+ } => Err(
+ PackageFolderResolveErrorKind::NotFoundPackage {
+ package_name: name,
+ referrer: referrer.clone(),
+ referrer_extra: Some(cache_folder_id_referrer.to_string()),
+ }
+ .into(),
+ ),
+ },
+ }
}
fn resolve_package_cache_folder_id_from_specifier(
diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs
index e8fffa0cd..ed36162c0 100644
--- a/cli/npm/managed/resolvers/local.rs
+++ b/cli/npm/managed/resolvers/local.rs
@@ -15,19 +15,8 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
-use crate::args::PackageJsonInstallDepsProvider;
-use crate::cache::CACHE_PERM;
-use crate::npm::cache_dir::mixed_case_package_name_decode;
-use crate::util::fs::atomic_write_file_with_retries;
-use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
-use crate::util::fs::clone_dir_recursive;
-use crate::util::fs::symlink_dir;
-use crate::util::fs::LaxSingleProcessFsFlag;
-use crate::util::progress_bar::ProgressBar;
-use crate::util::progress_bar::ProgressMessagePrompt;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
-use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::futures::stream::FuturesUnordered;
@@ -39,12 +28,24 @@ use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs;
+use deno_runtime::deno_node::errors::PackageFolderResolveError;
+use deno_runtime::deno_node::errors::PackageFolderResolveErrorKind;
use deno_runtime::deno_node::NodePermissions;
use deno_semver::package::PackageNv;
use serde::Deserialize;
use serde::Serialize;
+use crate::args::PackageJsonInstallDepsProvider;
+use crate::cache::CACHE_PERM;
+use crate::npm::cache_dir::mixed_case_package_name_decode;
use crate::npm::cache_dir::mixed_case_package_name_encode;
+use crate::util::fs::atomic_write_file_with_retries;
+use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
+use crate::util::fs::clone_dir_recursive;
+use crate::util::fs::symlink_dir;
+use crate::util::fs::LaxSingleProcessFsFlag;
+use crate::util::progress_bar::ProgressBar;
+use crate::util::progress_bar::ProgressMessagePrompt;
use super::super::cache::NpmCache;
use super::super::cache::TarballCache;
@@ -113,7 +114,7 @@ impl LocalNpmPackageResolver {
fn resolve_folder_for_specifier(
&self,
specifier: &ModuleSpecifier,
- ) -> Result<Option<PathBuf>, AnyError> {
+ ) -> Result<Option<PathBuf>, std::io::Error> {
let Some(relative_url) =
self.root_node_modules_url.make_relative(specifier)
else {
@@ -130,7 +131,6 @@ impl LocalNpmPackageResolver {
// in `node_modules` directory of the referrer.
canonicalize_path_maybe_not_exists_with_fs(&path, self.fs.as_ref())
.map(Some)
- .map_err(|err| err.into())
}
fn resolve_package_folder_from_specifier(
@@ -155,32 +155,42 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
Some(&self.root_node_modules_path)
}
- fn package_folder(&self, id: &NpmPackageId) -> Result<PathBuf, AnyError> {
- match self.resolution.resolve_pkg_cache_folder_id_from_pkg_id(id) {
- // package is stored at:
- // node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name>
- Some(cache_folder_id) => Ok(
- self
- .root_node_modules_path
- .join(".deno")
- .join(get_package_folder_id_folder_name(&cache_folder_id))
- .join("node_modules")
- .join(&cache_folder_id.nv.name),
- ),
- None => bail!(
- "Could not find package information for '{}'",
- id.as_serialized()
- ),
- }
+ fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
+ let cache_folder_id = self
+ .resolution
+ .resolve_pkg_cache_folder_id_from_pkg_id(id)?;
+ // package is stored at:
+ // node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name>
+ Some(
+ self
+ .root_node_modules_path
+ .join(".deno")
+ .join(get_package_folder_id_folder_name(&cache_folder_id))
+ .join("node_modules")
+ .join(&cache_folder_id.nv.name),
+ )
}
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
- ) -> Result<PathBuf, AnyError> {
- let Some(local_path) = self.resolve_folder_for_specifier(referrer)? else {
- bail!("could not find npm package for '{}'", referrer);
+ ) -> Result<PathBuf, PackageFolderResolveError> {
+ let maybe_local_path = self
+ .resolve_folder_for_specifier(referrer)
+ .map_err(|err| PackageFolderResolveErrorKind::Io {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ source: err,
+ })?;
+ let Some(local_path) = maybe_local_path else {
+ return Err(
+ PackageFolderResolveErrorKind::NotFoundReferrer {
+ referrer: referrer.clone(),
+ referrer_extra: None,
+ }
+ .into(),
+ );
};
let package_root_path = self.resolve_package_root(&local_path);
let mut current_folder = package_root_path.as_path();
@@ -202,11 +212,14 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
}
}
- bail!(
- "could not find package '{}' from referrer '{}'.",
- name,
- referrer
- );
+ Err(
+ PackageFolderResolveErrorKind::NotFoundPackage {
+ package_name: name.to_string(),
+ referrer: referrer.clone(),
+ referrer_extra: None,
+ }
+ .into(),
+ )
}
fn resolve_package_cache_folder_id_from_specifier(
@@ -696,6 +709,7 @@ fn junction_or_symlink_dir(
old_path: &Path,
new_path: &Path,
) -> Result<(), AnyError> {
+ use deno_core::anyhow::bail;
// Use junctions because they're supported on ntfs file systems without
// needing to elevate privileges on Windows