1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-19 12:16:17 -05:00

refactor(npm): move InNpmPackageChecker code to deno_resolver (#27609)

As title. Will allow consumers to create this struct and use our
behaviour.

Closes #27409
This commit is contained in:
David Sherret 2025-01-09 14:04:52 -05:00 committed by GitHub
parent 318f524c5c
commit 966370c908
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 81 additions and 69 deletions

View file

@ -12,6 +12,8 @@ use deno_core::futures::FutureExt;
use deno_core::FeatureChecker;
use deno_error::JsErrorBox;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver;
@ -64,14 +66,11 @@ use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::NpmRegistryReadPermissionChecker;
use crate::npm::NpmRegistryReadPermissionCheckerMode;
use crate::resolver::CjsTracker;
@ -387,7 +386,7 @@ impl CliFactory {
CreateInNpmPkgCheckerOptions::Byonm
} else {
CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: self.npm_cache_dir()?.root_dir_url(),
maybe_node_modules_path: cli_options
.node_modules_dir_path()
@ -395,7 +394,7 @@ impl CliFactory {
},
)
};
Ok(create_in_npm_pkg_checker(options))
Ok(deno_resolver::npm::create_in_npm_pkg_checker(options))
})
}

View file

@ -23,6 +23,8 @@ use deno_graph::Range;
use deno_npm::NpmSystemInfo;
use deno_path_util::url_to_file_path;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver;
@ -53,12 +55,10 @@ use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver_for_lsp;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::ManagedCliNpmResolver;
use crate::resolver::CliDenoResolver;
use crate::resolver::CliNpmReqResolver;
@ -736,14 +736,14 @@ impl<'a> ResolverFactory<'a> {
pub fn in_npm_pkg_checker(&self) -> &Arc<dyn InNpmPackageChecker> {
self.services.in_npm_pkg_checker.get_or_init(|| {
crate::npm::create_in_npm_pkg_checker(
deno_resolver::npm::create_in_npm_pkg_checker(
match self.services.npm_resolver.as_ref().map(|r| r.as_inner()) {
Some(crate::npm::InnerCliNpmResolverRef::Byonm(_)) | None => {
CreateInNpmPkgCheckerOptions::Byonm
}
Some(crate::npm::InnerCliNpmResolverRef::Managed(m)) => {
CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: m.global_cache_root_url(),
maybe_node_modules_path: m.maybe_node_modules_path(),
},

View file

@ -38,7 +38,6 @@ use installers::create_npm_fs_installer;
use installers::NpmPackageFsInstaller;
use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageFolderResolveIoError;
use node_resolver::InNpmPackageChecker;
use node_resolver::NpmPackageFolderResolver;
use super::CliNpmCache;
@ -276,35 +275,6 @@ async fn snapshot_from_lockfile(
Ok(snapshot)
}
#[derive(Debug)]
struct ManagedInNpmPackageChecker {
root_dir: Url,
}
impl InNpmPackageChecker for ManagedInNpmPackageChecker {
fn in_npm_package(&self, specifier: &Url) -> bool {
specifier.as_ref().starts_with(self.root_dir.as_str())
}
}
pub struct CliManagedInNpmPkgCheckerCreateOptions<'a> {
pub root_cache_dir_url: &'a Url,
pub maybe_node_modules_path: Option<&'a Path>,
}
pub fn create_managed_in_npm_pkg_checker(
options: CliManagedInNpmPkgCheckerCreateOptions,
) -> Arc<dyn InNpmPackageChecker> {
let root_dir = match options.maybe_node_modules_path {
Some(node_modules_folder) => {
deno_path_util::url_from_directory_path(node_modules_folder).unwrap()
}
None => options.root_cache_dir_url.clone(),
};
debug_assert!(root_dir.as_str().ends_with('/'));
Arc::new(ManagedInNpmPackageChecker { root_dir })
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PackageCaching<'a> {
Only(Cow<'a, [PackageReq]>),

View file

@ -14,7 +14,6 @@ use deno_core::url::Url;
use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo;
use deno_resolver::npm::ByonmInNpmPackageChecker;
use deno_resolver::npm::ByonmNpmResolver;
use deno_resolver::npm::CliNpmReqResolver;
use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
@ -23,13 +22,10 @@ use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use http::HeaderName;
use http::HeaderValue;
use managed::create_managed_in_npm_pkg_checker;
use node_resolver::InNpmPackageChecker;
use node_resolver::NpmPackageFolderResolver;
pub use self::byonm::CliByonmNpmResolver;
pub use self::byonm::CliByonmNpmResolverCreateOptions;
pub use self::managed::CliManagedInNpmPkgCheckerCreateOptions;
pub use self::managed::CliManagedNpmResolverCreateOptions;
pub use self::managed::CliNpmResolverManagedSnapshotOption;
pub use self::managed::ManagedCliNpmResolver;
@ -134,22 +130,6 @@ pub async fn create_cli_npm_resolver(
}
}
pub enum CreateInNpmPkgCheckerOptions<'a> {
Managed(CliManagedInNpmPkgCheckerCreateOptions<'a>),
Byonm,
}
pub fn create_in_npm_pkg_checker(
options: CreateInNpmPkgCheckerOptions,
) -> Arc<dyn InNpmPackageChecker> {
match options {
CreateInNpmPkgCheckerOptions::Managed(options) => {
create_managed_in_npm_pkg_checker(options)
}
CreateInNpmPkgCheckerOptions::Byonm => Arc::new(ByonmInNpmPackageChecker),
}
}
pub enum InnerCliNpmResolverRef<'a> {
Managed(&'a ManagedCliNpmResolver),
#[allow(dead_code)]

View file

@ -39,6 +39,9 @@ use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonDepValue;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::create_in_npm_pkg_checker;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FileSystem;
@ -81,14 +84,11 @@ use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::NpmRegistryReadPermissionChecker;
use crate::npm::NpmRegistryReadPermissionCheckerMode;
use crate::resolver::CjsTracker;
@ -738,7 +738,7 @@ pub async fn run(
.map(|node_modules_dir| root_path.join(node_modules_dir));
let in_npm_pkg_checker =
create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: npm_cache_dir.root_dir_url(),
maybe_node_modules_path: maybe_node_modules_path.as_deref(),
},
@ -796,7 +796,7 @@ pub async fn run(
));
let in_npm_pkg_checker =
create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: npm_cache_dir.root_dir_url(),
maybe_node_modules_path: None,
},

View file

@ -14,7 +14,7 @@ description = "Deno resolution algorithm"
path = "lib.rs"
[features]
sync = ["dashmap"]
sync = ["dashmap", "deno_package_json/sync", "node_resolver/sync"]
[dependencies]
anyhow.workspace = true
@ -27,10 +27,10 @@ deno_config.workspace = true
deno_error.workspace = true
deno_media_type.workspace = true
deno_npm.workspace = true
deno_package_json = { workspace = true, features = ["sync"] }
deno_package_json.workspace = true
deno_path_util.workspace = true
deno_semver.workspace = true
node_resolver = { workspace = true, features = ["sync"] }
node_resolver.workspace = true
parking_lot.workspace = true
sys_traits.workspace = true
thiserror.workspace = true

View file

@ -9,6 +9,9 @@ use deno_npm::NpmPackageId;
use node_resolver::errors::PackageFolderResolveError;
use url::Url;
use crate::sync::MaybeSend;
use crate::sync::MaybeSync;
#[allow(clippy::disallowed_types)]
pub(super) type NpmPackageFsResolverRc =
crate::sync::MaybeArc<dyn NpmPackageFsResolver>;
@ -20,7 +23,7 @@ pub struct NpmPackageFsResolverPackageFolderError(deno_semver::StackString);
/// Part of the resolution that interacts with the file system.
#[async_trait(?Send)]
pub trait NpmPackageFsResolver: Send + Sync {
pub trait NpmPackageFsResolver: MaybeSend + MaybeSync {
/// The local node_modules folder if it is applicable to the implementation.
fn node_modules_path(&self) -> Option<&Path>;

View file

@ -5,10 +5,13 @@ mod global;
mod local;
mod resolution;
use std::path::Path;
use std::path::PathBuf;
use node_resolver::InNpmPackageChecker;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata;
use url::Url;
pub use self::common::NpmPackageFsResolver;
pub use self::common::NpmPackageFsResolverPackageFolderError;
@ -43,3 +46,32 @@ pub fn create_npm_fs_resolver<
)),
}
}
#[derive(Debug)]
pub struct ManagedInNpmPackageChecker {
root_dir: Url,
}
impl InNpmPackageChecker for ManagedInNpmPackageChecker {
fn in_npm_package(&self, specifier: &Url) -> bool {
specifier.as_ref().starts_with(self.root_dir.as_str())
}
}
pub struct ManagedInNpmPkgCheckerCreateOptions<'a> {
pub root_cache_dir_url: &'a Url,
pub maybe_node_modules_path: Option<&'a Path>,
}
pub fn create_managed_in_npm_pkg_checker(
options: ManagedInNpmPkgCheckerCreateOptions,
) -> ManagedInNpmPackageChecker {
let root_dir = match options.maybe_node_modules_path {
Some(node_modules_folder) => {
deno_path_util::url_from_directory_path(node_modules_folder).unwrap()
}
None => options.root_cache_dir_url.clone(),
};
debug_assert!(root_dir.as_str().ends_with('/'));
ManagedInNpmPackageChecker { root_dir }
}

View file

@ -34,11 +34,32 @@ pub use self::byonm::ByonmNpmResolverRc;
pub use self::byonm::ByonmResolvePkgFolderFromDenoReqError;
pub use self::local::get_package_folder_id_folder_name;
pub use self::local::normalize_pkg_name_for_node_modules_deno_folder;
use self::managed::create_managed_in_npm_pkg_checker;
use self::managed::ManagedInNpmPkgCheckerCreateOptions;
use crate::sync::new_rc;
use crate::sync::MaybeSend;
use crate::sync::MaybeSync;
mod byonm;
mod local;
pub mod managed;
pub enum CreateInNpmPkgCheckerOptions<'a> {
Managed(ManagedInNpmPkgCheckerCreateOptions<'a>),
Byonm,
}
pub fn create_in_npm_pkg_checker(
options: CreateInNpmPkgCheckerOptions,
) -> InNpmPackageCheckerRc {
match options {
CreateInNpmPkgCheckerOptions::Managed(options) => {
new_rc(create_managed_in_npm_pkg_checker(options))
}
CreateInNpmPkgCheckerOptions::Byonm => new_rc(ByonmInNpmPackageChecker),
}
}
#[derive(Debug, Error, JsError)]
#[class(generic)]
#[error("Could not resolve \"{}\", but found it in a package.json. Deno expects the node_modules/ directory to be up to date. Did you forget to run `deno install`?", specifier)]
@ -99,7 +120,7 @@ pub type CliNpmReqResolverRc = crate::sync::MaybeArc<dyn CliNpmReqResolver>;
// todo(dsherret): a temporary trait until we extract
// out the CLI npm resolver into here
pub trait CliNpmReqResolver: Debug + Send + Sync {
pub trait CliNpmReqResolver: Debug + MaybeSend + MaybeSync {
fn resolve_pkg_folder_from_deno_module_req(
&self,
req: &PackageReq,

View file

@ -6,6 +6,8 @@ pub use inner::*;
mod inner {
#![allow(clippy::disallowed_types)]
pub use core::marker::Send as MaybeSend;
pub use core::marker::Sync as MaybeSync;
pub use std::sync::Arc as MaybeArc;
pub use dashmap::DashMap as MaybeDashMap;
@ -21,6 +23,11 @@ mod inner {
use std::hash::RandomState;
pub use std::rc::Rc as MaybeArc;
pub trait MaybeSync {}
impl<T> MaybeSync for T where T: ?Sized {}
pub trait MaybeSend {}
impl<T> MaybeSend for T where T: ?Sized {}
// Wrapper struct that exposes a subset of `DashMap` API.
#[derive(Debug)]
pub struct MaybeDashMap<K, V, S = RandomState>(RefCell<HashMap<K, V, S>>);