diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/lsp/resolver.rs | 4 | ||||
-rw-r--r-- | cli/module_loader.rs | 2 | ||||
-rw-r--r-- | cli/npm/byonm.rs | 60 | ||||
-rw-r--r-- | cli/npm/managed/mod.rs | 11 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/common.rs | 14 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/global.rs | 65 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/local.rs | 90 | ||||
-rw-r--r-- | cli/resolver.rs | 38 | ||||
-rw-r--r-- | cli/standalone/mod.rs | 2 | ||||
-rw-r--r-- | cli/tsc/mod.rs | 4 | ||||
-rw-r--r-- | cli/worker.rs | 7 |
11 files changed, 193 insertions, 104 deletions
diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 18d22afad..29f986ce3 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -28,13 +28,13 @@ use deno_ast::MediaType; use deno_cache_dir::HttpCache; use deno_config::workspace::PackageJsonDepResolution; use deno_config::workspace::WorkspaceResolver; -use deno_core::error::AnyError; use deno_core::url::Url; use deno_graph::source::Resolver; use deno_graph::GraphImport; use deno_graph::ModuleSpecifier; use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs; +use deno_runtime::deno_node::errors::ClosestPkgJsonError; use deno_runtime::deno_node::NodeResolution; use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::NodeResolver; @@ -365,7 +365,7 @@ impl LspResolver { pub fn get_closest_package_json( &self, referrer: &ModuleSpecifier, - ) -> Result<Option<Arc<PackageJson>>, AnyError> { + ) -> Result<Option<Arc<PackageJson>>, ClosestPkgJsonError> { let resolver = self.get_scope_resolver(Some(referrer)); let Some(node_resolver) = resolver.node_resolver.as_ref() else { return Ok(None); diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 4786b742f..5156e98e3 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -517,7 +517,7 @@ impl<TGraphContainer: ModuleGraphContainer> .resolve_package_sub_path_from_deno_module( &package_folder, module.nv_reference.sub_path(), - referrer, + Some(referrer), NodeResolutionMode::Execution, ) .with_context(|| { 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 diff --git a/cli/resolver.rs b/cli/resolver.rs index d1e5d91e7..e035a313c 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -23,6 +23,8 @@ use deno_graph::NpmResolvePkgReqsResult; use deno_npm::resolution::NpmResolutionError; use deno_runtime::deno_fs; use deno_runtime::deno_fs::FileSystem; +use deno_runtime::deno_node::errors::ClosestPkgJsonError; +use deno_runtime::deno_node::errors::UrlToNodeResolutionError; use deno_runtime::deno_node::is_builtin_node_module; use deno_runtime::deno_node::parse_npm_pkg_name; use deno_runtime::deno_node::NodeResolution; @@ -94,7 +96,7 @@ impl CliNodeResolver { pub fn get_closest_package_json( &self, referrer: &ModuleSpecifier, - ) -> Result<Option<Arc<PackageJson>>, AnyError> { + ) -> Result<Option<Arc<PackageJson>>, ClosestPkgJsonError> { self.node_resolver.get_closest_package_json(referrer) } @@ -119,7 +121,10 @@ impl CliNodeResolver { mode: NodeResolutionMode, ) -> Result<Option<NodeResolution>, AnyError> { self.handle_node_resolve_result( - self.node_resolver.resolve(specifier, referrer, mode), + self + .node_resolver + .resolve(specifier, referrer, mode) + .map_err(AnyError::from), ) } @@ -151,7 +156,7 @@ impl CliNodeResolver { .maybe_resolve_package_sub_path_from_deno_module( &package_folder, sub_path, - referrer, + Some(referrer), mode, )?; match maybe_resolution { @@ -180,14 +185,14 @@ impl CliNodeResolver { &self, package_folder: &Path, sub_path: Option<&str>, - referrer: &ModuleSpecifier, + maybe_referrer: Option<&ModuleSpecifier>, mode: NodeResolutionMode, ) -> Result<NodeResolution, AnyError> { self .maybe_resolve_package_sub_path_from_deno_module( package_folder, sub_path, - referrer, + maybe_referrer, mode, )? .ok_or_else(|| { @@ -205,16 +210,19 @@ impl CliNodeResolver { &self, package_folder: &Path, sub_path: Option<&str>, - referrer: &ModuleSpecifier, + maybe_referrer: Option<&ModuleSpecifier>, mode: NodeResolutionMode, ) -> Result<Option<NodeResolution>, AnyError> { self.handle_node_resolve_result( - self.node_resolver.resolve_package_subpath_from_deno_module( - package_folder, - sub_path, - referrer, - mode, - ), + self + .node_resolver + .resolve_package_subpath_from_deno_module( + package_folder, + sub_path, + maybe_referrer, + mode, + ) + .map_err(AnyError::from), ) } @@ -252,7 +260,7 @@ impl CliNodeResolver { pub fn url_to_node_resolution( &self, specifier: ModuleSpecifier, - ) -> Result<NodeResolution, AnyError> { + ) -> Result<NodeResolution, UrlToNodeResolutionError> { self.node_resolver.url_to_node_resolution(specifier) } @@ -574,7 +582,7 @@ impl Resolver for CliGraphResolver { .resolve_package_sub_path_from_deno_module( pkg_folder, sub_path.as_deref(), - referrer, + Some(referrer), to_node_mode(mode), )? .into_url(), @@ -599,7 +607,7 @@ impl Resolver for CliGraphResolver { .resolve_package_sub_path_from_deno_module( pkg_folder, req_ref.sub_path(), - referrer, + Some(referrer), to_node_mode(mode), )? .into_url(), diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index cbd14db4f..106b7b7e7 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -197,7 +197,7 @@ impl ModuleLoader for EmbeddedModuleLoader { .resolve_package_sub_path_from_deno_module( pkg_folder, sub_path.as_deref(), - &referrer, + Some(&referrer), NodeResolutionMode::Execution, )? .into_url(), diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index de4c05e27..6306c9975 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -739,7 +739,7 @@ fn resolve_graph_specifier_types( npm.node_resolver.resolve_package_subpath_from_deno_module( &package_folder, module.nv_reference.sub_path(), - referrer, + Some(referrer), NodeResolutionMode::Types, )?; Ok(Some(NodeResolution::into_specifier_and_media_type( @@ -793,7 +793,7 @@ fn resolve_non_graph_specifier_types( .resolve_package_subpath_from_deno_module( &package_folder, npm_req_ref.sub_path(), - referrer, + Some(referrer), NodeResolutionMode::Types, )?; Ok(Some(NodeResolution::into_specifier_and_media_type( diff --git a/cli/worker.rs b/cli/worker.rs index 987d65192..9125f28be 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -669,7 +669,7 @@ impl CliMainWorkerFactory { self.resolve_binary_entrypoint_fallback(package_folder, sub_path); match result { Ok(Some(resolution)) => Ok(resolution), - Ok(None) => Err(original_err), + Ok(None) => Err(original_err.into()), Err(fallback_err) => { bail!("{:#}\n\nFallback failed: {:#}", original_err, fallback_err) } @@ -692,16 +692,13 @@ impl CliMainWorkerFactory { return Ok(None); } - // use a fake referrer since a real one doesn't exist - let referrer = - ModuleSpecifier::from_directory_path(package_folder).unwrap(); let Some(resolution) = self .shared .node_resolver .resolve_package_subpath_from_deno_module( package_folder, sub_path, - &referrer, + /* referrer */ None, NodeResolutionMode::Execution, )? else { |