diff options
Diffstat (limited to 'cli/npm')
-rw-r--r-- | cli/npm/cache.rs | 5 | ||||
-rw-r--r-- | cli/npm/installer.rs | 24 | ||||
-rw-r--r-- | cli/npm/registry.rs | 6 | ||||
-rw-r--r-- | cli/npm/resolution.rs | 73 | ||||
-rw-r--r-- | cli/npm/resolvers/common.rs | 10 | ||||
-rw-r--r-- | cli/npm/resolvers/global.rs | 43 | ||||
-rw-r--r-- | cli/npm/resolvers/local.rs | 53 | ||||
-rw-r--r-- | cli/npm/resolvers/mod.rs | 35 |
8 files changed, 108 insertions, 141 deletions
diff --git a/cli/npm/cache.rs b/cli/npm/cache.rs index 1ad6bf72a..eb674d3cb 100644 --- a/cli/npm/cache.rs +++ b/cli/npm/cache.rs @@ -4,7 +4,6 @@ use std::collections::HashSet; use std::fs; use std::path::Path; use std::path::PathBuf; -use std::sync::Arc; use deno_ast::ModuleSpecifier; use deno_core::anyhow::bail; @@ -296,14 +295,14 @@ impl ReadonlyNpmCache { } /// Stores a single copy of npm packages in a cache. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct NpmCache { readonly: ReadonlyNpmCache, cache_setting: CacheSetting, http_client: HttpClient, progress_bar: ProgressBar, /// ensures a package is only downloaded once per run - previously_reloaded_packages: Arc<Mutex<HashSet<NpmPackageNv>>>, + previously_reloaded_packages: Mutex<HashSet<NpmPackageNv>>, } impl NpmCache { diff --git a/cli/npm/installer.rs b/cli/npm/installer.rs index 9e5fcc4c3..bdcafb542 100644 --- a/cli/npm/installer.rs +++ b/cli/npm/installer.rs @@ -19,8 +19,8 @@ use super::NpmResolution; #[derive(Debug)] struct PackageJsonDepsInstallerInner { has_installed_flag: AtomicFlag, - npm_registry_api: CliNpmRegistryApi, - npm_resolution: NpmResolution, + npm_registry_api: Arc<CliNpmRegistryApi>, + npm_resolution: Arc<NpmResolution>, package_deps: PackageJsonDeps, } @@ -58,22 +58,20 @@ impl PackageJsonDepsInstallerInner { } /// Holds and controls installing dependencies from package.json. -#[derive(Debug, Clone, Default)] -pub struct PackageJsonDepsInstaller(Option<Arc<PackageJsonDepsInstallerInner>>); +#[derive(Debug, Default)] +pub struct PackageJsonDepsInstaller(Option<PackageJsonDepsInstallerInner>); impl PackageJsonDepsInstaller { pub fn new( - npm_registry_api: CliNpmRegistryApi, - npm_resolution: NpmResolution, + npm_registry_api: Arc<CliNpmRegistryApi>, + npm_resolution: Arc<NpmResolution>, deps: Option<PackageJsonDeps>, ) -> Self { - Self(deps.map(|package_deps| { - Arc::new(PackageJsonDepsInstallerInner { - has_installed_flag: Default::default(), - npm_registry_api, - npm_resolution, - package_deps, - }) + Self(deps.map(|package_deps| PackageJsonDepsInstallerInner { + has_installed_flag: Default::default(), + npm_registry_api, + npm_resolution, + package_deps, })) } diff --git a/cli/npm/registry.rs b/cli/npm/registry.rs index 798cb17dd..ef050a734 100644 --- a/cli/npm/registry.rs +++ b/cli/npm/registry.rs @@ -52,7 +52,7 @@ static NPM_REGISTRY_DEFAULT_URL: Lazy<Url> = Lazy::new(|| { Url::parse("https://registry.npmjs.org").unwrap() }); -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct CliNpmRegistryApi(Option<Arc<CliNpmRegistryApiInner>>); impl CliNpmRegistryApi { @@ -62,7 +62,7 @@ impl CliNpmRegistryApi { pub fn new( base_url: Url, - cache: NpmCache, + cache: Arc<NpmCache>, http_client: HttpClient, progress_bar: ProgressBar, ) -> Self { @@ -168,7 +168,7 @@ enum CacheItem { #[derive(Debug)] struct CliNpmRegistryApiInner { base_url: Url, - cache: NpmCache, + cache: Arc<NpmCache>, force_reload_flag: AtomicFlag, mem_cache: Mutex<HashMap<String, CacheItem>>, previously_reloaded_packages: Mutex<HashSet<String>>, diff --git a/cli/npm/resolution.rs b/cli/npm/resolution.rs index dbfbb9665..375191b2d 100644 --- a/cli/npm/resolution.rs +++ b/cli/npm/resolution.rs @@ -38,11 +38,8 @@ use super::registry::CliNpmRegistryApi; /// based on changes to the resolution. /// /// This does not interact with the file system. -#[derive(Clone)] -pub struct NpmResolution(Arc<NpmResolutionInner>); - -struct NpmResolutionInner { - api: CliNpmRegistryApi, +pub struct NpmResolution { + api: Arc<CliNpmRegistryApi>, snapshot: RwLock<NpmResolutionSnapshot>, update_queue: TaskQueue, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, @@ -50,7 +47,7 @@ struct NpmResolutionInner { impl std::fmt::Debug for NpmResolution { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let snapshot = self.0.snapshot.read(); + let snapshot = self.snapshot.read(); f.debug_struct("NpmResolution") .field("snapshot", &snapshot.as_serialized()) .finish() @@ -59,13 +56,13 @@ impl std::fmt::Debug for NpmResolution { impl NpmResolution { pub fn from_serialized( - api: CliNpmRegistryApi, + api: Arc<CliNpmRegistryApi>, initial_snapshot: Option<ValidSerializedNpmResolutionSnapshot>, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, ) -> Self { let snapshot = NpmResolutionSnapshot::new(NpmResolutionSnapshotCreateOptions { - api: Arc::new(api.clone()), + api: api.clone(), snapshot: initial_snapshot.unwrap_or_default(), // WARNING: When bumping this version, check if anything needs to be // updated in the `setNodeOnlyGlobalNames` call in 99_main_compiler.js @@ -77,35 +74,33 @@ impl NpmResolution { } pub fn new( - api: CliNpmRegistryApi, + api: Arc<CliNpmRegistryApi>, initial_snapshot: NpmResolutionSnapshot, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, ) -> Self { - Self(Arc::new(NpmResolutionInner { + Self { api, snapshot: RwLock::new(initial_snapshot), update_queue: Default::default(), maybe_lockfile, - })) + } } pub async fn add_package_reqs( &self, package_reqs: Vec<NpmPackageReq>, ) -> Result<(), AnyError> { - let inner = &self.0; - // only allow one thread in here at a time - let _permit = inner.update_queue.acquire().await; + let _permit = self.update_queue.acquire().await; let snapshot = add_package_reqs_to_snapshot( - &inner.api, + &self.api, package_reqs, - self.0.maybe_lockfile.clone(), - || inner.snapshot.read().clone(), + self.maybe_lockfile.clone(), + || self.snapshot.read().clone(), ) .await?; - *inner.snapshot.write() = snapshot; + *self.snapshot.write() = snapshot; Ok(()) } @@ -113,17 +108,16 @@ impl NpmResolution { &self, package_reqs: Vec<NpmPackageReq>, ) -> Result<(), AnyError> { - let inner = &self.0; // only allow one thread in here at a time - let _permit = inner.update_queue.acquire().await; + let _permit = self.update_queue.acquire().await; let reqs_set = package_reqs.iter().cloned().collect::<HashSet<_>>(); let snapshot = add_package_reqs_to_snapshot( - &inner.api, + &self.api, package_reqs, - self.0.maybe_lockfile.clone(), + self.maybe_lockfile.clone(), || { - let snapshot = inner.snapshot.read().clone(); + let snapshot = self.snapshot.read().clone(); let has_removed_package = !snapshot .package_reqs() .keys() @@ -138,25 +132,24 @@ impl NpmResolution { ) .await?; - *inner.snapshot.write() = snapshot; + *self.snapshot.write() = snapshot; Ok(()) } pub async fn resolve_pending(&self) -> Result<(), AnyError> { - let inner = &self.0; // only allow one thread in here at a time - let _permit = inner.update_queue.acquire().await; + let _permit = self.update_queue.acquire().await; let snapshot = add_package_reqs_to_snapshot( - &inner.api, + &self.api, Vec::new(), - self.0.maybe_lockfile.clone(), - || inner.snapshot.read().clone(), + self.maybe_lockfile.clone(), + || self.snapshot.read().clone(), ) .await?; - *inner.snapshot.write() = snapshot; + *self.snapshot.write() = snapshot; Ok(()) } @@ -177,7 +170,6 @@ impl NpmResolution { id: &NpmPackageId, ) -> Option<NpmPackageCacheFolderId> { self - .0 .snapshot .read() .package_from_id(id) @@ -190,7 +182,6 @@ impl NpmResolution { referrer: &NpmPackageCacheFolderId, ) -> Result<NpmResolutionPackage, Box<PackageNotFoundFromReferrerError>> { self - .0 .snapshot .read() .resolve_package_from_package(name, referrer) @@ -203,7 +194,6 @@ impl NpmResolution { req: &NpmPackageReq, ) -> Result<NpmPackageId, PackageReqNotFoundError> { self - .0 .snapshot .read() .resolve_pkg_from_pkg_req(req) @@ -215,7 +205,6 @@ impl NpmResolution { id: &NpmPackageNv, ) -> Result<NpmPackageId, PackageNvNotFoundError> { self - .0 .snapshot .read() .resolve_package_from_deno_module(id) @@ -230,8 +219,7 @@ impl NpmResolution { pkg_req: &NpmPackageReq, ) -> Result<NpmPackageNv, NpmPackageVersionResolutionError> { // we should always have this because it should have been cached before here - let package_info = - self.0.api.get_cached_package_info(&pkg_req.name).unwrap(); + let package_info = self.api.get_cached_package_info(&pkg_req.name).unwrap(); self.resolve_package_req_as_pending_with_info(pkg_req, &package_info) } @@ -244,30 +232,29 @@ impl NpmResolution { package_info: &NpmPackageInfo, ) -> Result<NpmPackageNv, NpmPackageVersionResolutionError> { debug_assert_eq!(pkg_req.name, package_info.name); - let inner = &self.0; - let mut snapshot = inner.snapshot.write(); + let mut snapshot = self.snapshot.write(); let nv = snapshot.resolve_package_req_as_pending(pkg_req, package_info)?; Ok(nv) } pub fn all_packages_partitioned(&self) -> NpmPackagesPartitioned { - self.0.snapshot.read().all_packages_partitioned() + self.snapshot.read().all_packages_partitioned() } pub fn has_packages(&self) -> bool { - !self.0.snapshot.read().is_empty() + !self.snapshot.read().is_empty() } pub fn snapshot(&self) -> NpmResolutionSnapshot { - self.0.snapshot.read().clone() + self.snapshot.read().clone() } pub fn serialized_snapshot(&self) -> SerializedNpmResolutionSnapshot { - self.0.snapshot.read().as_serialized() + self.snapshot.read().as_serialized() } pub fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> { - let snapshot = self.0.snapshot.read(); + let snapshot = self.snapshot.read(); populate_lockfile_from_snapshot(lockfile, &snapshot) } } diff --git a/cli/npm/resolvers/common.rs b/cli/npm/resolvers/common.rs index 8b8be5ce2..a31459a70 100644 --- a/cli/npm/resolvers/common.rs +++ b/cli/npm/resolvers/common.rs @@ -3,6 +3,7 @@ use std::io::ErrorKind; use std::path::Path; use std::path::PathBuf; +use std::sync::Arc; use async_trait::async_trait; use deno_ast::ModuleSpecifier; @@ -26,11 +27,10 @@ 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 resolve_package_folder_from_deno_module( + fn package_folder( &self, - id: &NpmPackageId, + package_id: &NpmPackageId, ) -> Result<PathBuf, AnyError>; - fn resolve_package_folder_from_package( &self, name: &str, @@ -43,8 +43,6 @@ pub trait NpmPackageFsResolver: Send + Sync { specifier: &ModuleSpecifier, ) -> Result<PathBuf, AnyError>; - fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError>; - async fn cache_packages(&self) -> Result<(), AnyError>; fn ensure_read_permission( @@ -57,7 +55,7 @@ pub trait NpmPackageFsResolver: Send + Sync { /// Caches all the packages in parallel. pub async fn cache_packages( mut packages: Vec<NpmResolutionPackage>, - cache: &NpmCache, + cache: &Arc<NpmCache>, registry_url: &Url, ) -> Result<(), AnyError> { let sync_download = should_sync_download(); diff --git a/cli/npm/resolvers/global.rs b/cli/npm/resolvers/global.rs index 810548e98..66935380f 100644 --- a/cli/npm/resolvers/global.rs +++ b/cli/npm/resolvers/global.rs @@ -4,6 +4,7 @@ use std::path::Path; use std::path::PathBuf; +use std::sync::Arc; use async_trait::async_trait; use deno_ast::ModuleSpecifier; @@ -25,18 +26,18 @@ use super::common::types_package_name; use super::common::NpmPackageFsResolver; /// Resolves packages from the global npm cache. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct GlobalNpmPackageResolver { - cache: NpmCache, - resolution: NpmResolution, + cache: Arc<NpmCache>, + resolution: Arc<NpmResolution>, registry_url: Url, } impl GlobalNpmPackageResolver { pub fn new( - cache: NpmCache, + cache: Arc<NpmCache>, registry_url: Url, - resolution: NpmResolution, + resolution: Arc<NpmResolution>, ) -> Self { Self { cache, @@ -45,16 +46,6 @@ impl GlobalNpmPackageResolver { } } - fn package_folder(&self, id: &NpmPackageId) -> PathBuf { - let folder_id = self - .resolution - .resolve_package_cache_folder_id_from_id(id) - .unwrap(); - self - .cache - .package_folder_for_id(&folder_id, &self.registry_url) - } - fn resolve_types_package( &self, package_name: &str, @@ -77,11 +68,16 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver { None } - fn resolve_package_folder_from_deno_module( - &self, - id: &NpmPackageId, - ) -> Result<PathBuf, AnyError> { - Ok(self.package_folder(id)) + fn package_folder(&self, id: &NpmPackageId) -> Result<PathBuf, AnyError> { + let folder_id = self + .resolution + .resolve_package_cache_folder_id_from_id(id) + .unwrap(); + Ok( + self + .cache + .package_folder_for_id(&folder_id, &self.registry_url), + ) } fn resolve_package_folder_from_package( @@ -106,7 +102,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver { .resolution .resolve_package_from_package(name, &referrer_pkg_id)? }; - Ok(self.package_folder(&pkg.pkg_id)) + self.package_folder(&pkg.pkg_id) } fn resolve_package_folder_from_specifier( @@ -124,11 +120,6 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver { ) } - fn package_size(&self, id: &NpmPackageId) -> Result<u64, AnyError> { - let package_folder = self.package_folder(id); - Ok(crate::util::fs::dir_size(&package_folder)?) - } - async fn cache_packages(&self) -> Result<(), AnyError> { cache_packages_in_resolver(self).await } diff --git a/cli/npm/resolvers/local.rs b/cli/npm/resolvers/local.rs index 59d8b0829..d4085f345 100644 --- a/cli/npm/resolvers/local.rs +++ b/cli/npm/resolvers/local.rs @@ -8,6 +8,7 @@ use std::collections::VecDeque; use std::fs; use std::path::Path; use std::path::PathBuf; +use std::sync::Arc; use crate::util::fs::symlink_dir; use crate::util::fs::LaxSingleProcessFsFlag; @@ -41,11 +42,11 @@ use super::common::NpmPackageFsResolver; /// Resolver that creates a local node_modules directory /// and resolves packages from it. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct LocalNpmPackageResolver { - cache: NpmCache, + cache: Arc<NpmCache>, progress_bar: ProgressBar, - resolution: NpmResolution, + resolution: Arc<NpmResolution>, registry_url: Url, root_node_modules_path: PathBuf, root_node_modules_url: Url, @@ -53,11 +54,11 @@ pub struct LocalNpmPackageResolver { impl LocalNpmPackageResolver { pub fn new( - cache: NpmCache, + cache: Arc<NpmCache>, progress_bar: ProgressBar, registry_url: Url, node_modules_folder: PathBuf, - resolution: NpmResolution, + resolution: Arc<NpmResolution>, ) -> Self { Self { cache, @@ -103,11 +104,19 @@ impl LocalNpmPackageResolver { // it's within the directory, so use it specifier.to_file_path().ok() } +} - fn get_package_id_folder( - &self, - id: &NpmPackageId, - ) -> Result<PathBuf, AnyError> { +#[async_trait] +impl NpmPackageFsResolver for LocalNpmPackageResolver { + fn root_dir_url(&self) -> &Url { + &self.root_node_modules_url + } + + fn node_modules_path(&self) -> Option<PathBuf> { + Some(self.root_node_modules_path.clone()) + } + + fn package_folder(&self, id: &NpmPackageId) -> Result<PathBuf, AnyError> { match self.resolution.resolve_package_cache_folder_id_from_id(id) { // package is stored at: // node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name> @@ -125,24 +134,6 @@ impl LocalNpmPackageResolver { ), } } -} - -#[async_trait] -impl NpmPackageFsResolver for LocalNpmPackageResolver { - fn root_dir_url(&self) -> &Url { - &self.root_node_modules_url - } - - fn node_modules_path(&self) -> Option<PathBuf> { - Some(self.root_node_modules_path.clone()) - } - - fn resolve_package_folder_from_deno_module( - &self, - node_id: &NpmPackageId, - ) -> Result<PathBuf, AnyError> { - self.get_package_id_folder(node_id) - } fn resolve_package_folder_from_package( &self, @@ -198,12 +189,6 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { Ok(package_root_path) } - fn package_size(&self, id: &NpmPackageId) -> Result<u64, AnyError> { - let package_folder_path = self.get_package_id_folder(id)?; - - Ok(crate::util::fs::dir_size(&package_folder_path)?) - } - async fn cache_packages(&self) -> Result<(), AnyError> { sync_resolution_with_fs( &self.resolution.snapshot(), @@ -231,7 +216,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { /// Creates a pnpm style folder structure. async fn sync_resolution_with_fs( snapshot: &NpmResolutionSnapshot, - cache: &NpmCache, + cache: &Arc<NpmCache>, progress_bar: &ProgressBar, registry_url: &Url, root_node_modules_dir_path: &Path, diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/resolvers/mod.rs index 31218f356..c8b841b54 100644 --- a/cli/npm/resolvers/mod.rs +++ b/cli/npm/resolvers/mod.rs @@ -47,10 +47,9 @@ pub struct NpmProcessState { } /// Brings together the npm resolution with the file system. -#[derive(Clone)] pub struct NpmPackageResolver { fs_resolver: Arc<dyn NpmPackageFsResolver>, - resolution: NpmResolution, + resolution: Arc<NpmResolution>, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, } @@ -66,7 +65,7 @@ impl std::fmt::Debug for NpmPackageResolver { impl NpmPackageResolver { pub fn new( - resolution: NpmResolution, + resolution: Arc<NpmResolution>, fs_resolver: Arc<dyn NpmPackageFsResolver>, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, ) -> Self { @@ -108,9 +107,7 @@ impl NpmPackageResolver { &self, pkg_id: &NpmPackageId, ) -> Result<PathBuf, AnyError> { - let path = self - .fs_resolver - .resolve_package_folder_from_deno_module(pkg_id)?; + let path = self.fs_resolver.package_folder(pkg_id)?; let path = canonicalize_path_maybe_not_exists(&path)?; log::debug!( "Resolved package folder of {} to {}", @@ -157,7 +154,8 @@ impl NpmPackageResolver { &self, package_id: &NpmPackageId, ) -> Result<u64, AnyError> { - self.fs_resolver.package_size(package_id) + let package_folder = self.fs_resolver.package_folder(package_id)?; + Ok(crate::util::fs::dir_size(&package_folder)?) } /// Gets if the provided specifier is in an npm package. @@ -239,9 +237,17 @@ impl NpmPackageResolver { self.fs_resolver.cache_packages().await?; Ok(()) } + + pub fn as_require_npm_resolver( + self: &Arc<Self>, + ) -> RequireNpmPackageResolver { + RequireNpmPackageResolver(self.clone()) + } } -impl RequireNpmResolver for NpmPackageResolver { +pub struct RequireNpmPackageResolver(Arc<NpmPackageResolver>); + +impl RequireNpmResolver for RequireNpmPackageResolver { fn resolve_package_folder_from_package( &self, specifier: &str, @@ -249,7 +255,9 @@ impl RequireNpmResolver for NpmPackageResolver { mode: NodeResolutionMode, ) -> Result<PathBuf, AnyError> { let referrer = path_to_specifier(referrer)?; - self.resolve_package_folder_from_package(specifier, &referrer, mode) + self + .0 + .resolve_package_folder_from_package(specifier, &referrer, mode) } fn resolve_package_folder_from_path( @@ -257,7 +265,7 @@ impl RequireNpmResolver for NpmPackageResolver { path: &Path, ) -> Result<PathBuf, AnyError> { let specifier = path_to_specifier(path)?; - self.resolve_package_folder_from_specifier(&specifier) + self.0.resolve_package_folder_from_specifier(&specifier) } fn in_npm_package(&self, path: &Path) -> bool { @@ -267,6 +275,7 @@ impl RequireNpmResolver for NpmPackageResolver { Err(_) => return false, }; self + .0 .resolve_package_folder_from_specifier(&specifier) .is_ok() } @@ -276,15 +285,15 @@ impl RequireNpmResolver for NpmPackageResolver { permissions: &mut dyn NodePermissions, path: &Path, ) -> Result<(), AnyError> { - self.fs_resolver.ensure_read_permission(permissions, path) + self.0.fs_resolver.ensure_read_permission(permissions, path) } } pub fn create_npm_fs_resolver( - cache: NpmCache, + cache: Arc<NpmCache>, progress_bar: &ProgressBar, registry_url: Url, - resolution: NpmResolution, + resolution: Arc<NpmResolution>, maybe_node_modules_path: Option<PathBuf>, ) -> Arc<dyn NpmPackageFsResolver> { match maybe_node_modules_path { |