diff options
Diffstat (limited to 'cli/npm')
-rw-r--r-- | cli/npm/managed/installer.rs (renamed from cli/npm/installer.rs) | 2 | ||||
-rw-r--r-- | cli/npm/managed/mod.rs (renamed from cli/npm/resolvers/mod.rs) | 174 | ||||
-rw-r--r-- | cli/npm/managed/resolution.rs (renamed from cli/npm/resolution.rs) | 10 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/common.rs (renamed from cli/npm/resolvers/common.rs) | 0 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/global.rs (renamed from cli/npm/resolvers/global.rs) | 4 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/local.rs (renamed from cli/npm/resolvers/local.rs) | 2 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/mod.rs | 50 | ||||
-rw-r--r-- | cli/npm/mod.rs | 102 | ||||
-rw-r--r-- | cli/npm/registry.rs | 6 |
9 files changed, 230 insertions, 120 deletions
diff --git a/cli/npm/installer.rs b/cli/npm/managed/installer.rs index 8f3db0531..21285c3d7 100644 --- a/cli/npm/installer.rs +++ b/cli/npm/managed/installer.rs @@ -13,7 +13,7 @@ use deno_semver::package::PackageReq; use crate::args::PackageJsonDepsProvider; use crate::util::sync::AtomicFlag; -use super::CliNpmRegistryApi; +use super::super::CliNpmRegistryApi; use super::NpmResolution; #[derive(Debug)] diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/managed/mod.rs index 07a122a3e..c5ba3d3af 100644 --- a/cli/npm/resolvers/mod.rs +++ b/cli/npm/managed/mod.rs @@ -1,9 +1,5 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -mod common; -mod global; -mod local; - use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; @@ -14,10 +10,13 @@ use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; use deno_core::serde_json; use deno_core::url::Url; +use deno_graph::NpmPackageReqResolution; +use deno_npm::registry::NpmRegistryApi; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::resolution::PackageReqNotFoundError; use deno_npm::resolution::SerializedNpmResolutionSnapshot; use deno_npm::NpmPackageId; +use deno_npm::NpmResolutionPackage; use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; @@ -28,19 +27,24 @@ use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageNv; use deno_semver::package::PackageNvReference; use deno_semver::package::PackageReq; -use global::GlobalNpmPackageResolver; use serde::Deserialize; use serde::Serialize; use crate::args::Lockfile; use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs; -use crate::util::progress_bar::ProgressBar; -use self::local::LocalNpmPackageResolver; -use super::resolution::NpmResolution; -use super::NpmCache; +use super::CliNpmRegistryApi; +use super::CliNpmResolver; +use super::InnerCliNpmResolverRef; + +pub use self::installer::PackageJsonDepsInstaller; +pub use self::resolution::NpmResolution; +pub use self::resolvers::create_npm_fs_resolver; +pub use self::resolvers::NpmPackageFsResolver; -pub use self::common::NpmPackageFsResolver; +mod installer; +mod resolution; +mod resolvers; /// State provided to the process via an environment variable. #[derive(Clone, Debug, Serialize, Deserialize)] @@ -49,97 +53,46 @@ pub struct NpmProcessState { pub local_node_modules_path: Option<String>, } -pub enum InnerCliNpmResolverRef<'a> { - Managed(&'a ManagedCliNpmResolver), - #[allow(dead_code)] - Byonm(&'a ByonmCliNpmResolver), -} - -pub trait CliNpmResolver: NpmResolver { - fn into_npm_resolver(self: Arc<Self>) -> Arc<dyn NpmResolver>; - - fn root_dir_url(&self) -> &Url; - - fn as_inner(&self) -> InnerCliNpmResolverRef; - - fn as_managed(&self) -> Option<&ManagedCliNpmResolver> { - match self.as_inner() { - InnerCliNpmResolverRef::Managed(inner) => Some(inner), - InnerCliNpmResolverRef::Byonm(_) => None, - } - } - - fn node_modules_path(&self) -> Option<PathBuf>; - - /// Checks if the provided package req's folder is cached. - fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool; - - fn resolve_pkg_nv_ref_from_pkg_req_ref( - &self, - req_ref: &NpmPackageReqReference, - ) -> Result<NpmPackageNvReference, PackageReqNotFoundError>; - - /// Resolve the root folder of the package the provided specifier is in. - /// - /// This will error when the provided specifier is not in an npm package. - fn resolve_pkg_folder_from_specifier( - &self, - specifier: &ModuleSpecifier, - ) -> Result<Option<PathBuf>, AnyError>; - - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - ) -> Result<PathBuf, AnyError>; - - fn resolve_pkg_folder_from_deno_module( - &self, - nv: &PackageNv, - ) -> Result<PathBuf, AnyError>; - - /// Gets the state of npm for the process. - fn get_npm_process_state(&self) -> String; - - // todo(#18967): should instead return a hash state of the resolver - // or perhaps this could be non-BYONM only and byonm always runs deno check - fn package_reqs(&self) -> HashMap<PackageReq, PackageNv>; -} - -// todo(dsherret): implement this -pub struct ByonmCliNpmResolver; - /// An npm resolver where the resolution is managed by Deno rather than /// the user bringing their own node_modules (BYONM) on the file system. pub struct ManagedCliNpmResolver { + api: Arc<CliNpmRegistryApi>, fs: Arc<dyn FileSystem>, fs_resolver: Arc<dyn NpmPackageFsResolver>, resolution: Arc<NpmResolution>, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, + package_json_deps_installer: Arc<PackageJsonDepsInstaller>, } impl std::fmt::Debug for ManagedCliNpmResolver { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ManagedNpmResolver") + .field("api", &"<omitted>") .field("fs", &"<omitted>") .field("fs_resolver", &"<omitted>") .field("resolution", &"<omitted>") .field("maybe_lockfile", &"<omitted>") + .field("package_json_deps_installer", &"<omitted>") .finish() } } impl ManagedCliNpmResolver { pub fn new( + api: Arc<CliNpmRegistryApi>, fs: Arc<dyn FileSystem>, resolution: Arc<NpmResolution>, fs_resolver: Arc<dyn NpmPackageFsResolver>, maybe_lockfile: Option<Arc<Mutex<Lockfile>>>, + package_json_deps_installer: Arc<PackageJsonDepsInstaller>, ) -> Self { Self { + api, fs, fs_resolver, resolution, maybe_lockfile, + package_json_deps_installer, } } @@ -180,6 +133,13 @@ impl ManagedCliNpmResolver { )) } + pub fn resolve_pkg_reqs_from_pkg_id( + &self, + id: &NpmPackageId, + ) -> Vec<PackageReq> { + self.resolution.resolve_pkg_reqs_from_pkg_id(id) + } + /// Attempts to get the package size in bytes. pub fn package_size( &self, @@ -189,6 +149,13 @@ impl ManagedCliNpmResolver { Ok(crate::util::fs::dir_size(&package_folder)?) } + pub fn all_system_packages( + &self, + system_info: &NpmSystemInfo, + ) -> Vec<NpmResolutionPackage> { + self.resolution.all_system_packages(system_info) + } + /// Adds package requirements to the resolver and ensures everything is setup. pub async fn add_package_reqs( &self, @@ -251,6 +218,28 @@ impl ManagedCliNpmResolver { ) -> Result<NpmPackageId, PackageReqNotFoundError> { self.resolution.resolve_pkg_id_from_pkg_req(req) } + + pub async fn ensure_top_level_package_json_install( + &self, + ) -> Result<(), AnyError> { + self + .package_json_deps_installer + .ensure_top_level_install() + .await + } + + pub async fn cache_package_info( + &self, + package_name: &str, + ) -> Result<(), AnyError> { + // this will internally cache the package information + self + .api + .package_info(package_name) + .await + .map(|_| ()) + .map_err(|err| err.into()) + } } impl NpmResolver for ManagedCliNpmResolver { @@ -316,6 +305,24 @@ impl CliNpmResolver for ManagedCliNpmResolver { .unwrap_or(false) } + fn resolve_npm_for_deno_graph( + &self, + pkg_req: &PackageReq, + ) -> NpmPackageReqResolution { + let result = self.resolution.resolve_pkg_req_as_pending(pkg_req); + match result { + Ok(nv) => NpmPackageReqResolution::Ok(nv), + Err(err) => { + if self.api.mark_force_reload() { + log::debug!("Restarting npm specifier resolution to check for new registry information. Error: {:#}", err); + NpmPackageReqResolution::ReloadRegistryInfo(err.into()) + } else { + NpmPackageReqResolution::Err(err.into()) + } + } + } + } + fn resolve_pkg_nv_ref_from_pkg_req_ref( &self, req_ref: &NpmPackageReqReference, @@ -385,32 +392,3 @@ impl CliNpmResolver for ManagedCliNpmResolver { self.resolution.package_reqs() } } - -pub fn create_npm_fs_resolver( - fs: Arc<dyn FileSystem>, - cache: Arc<NpmCache>, - progress_bar: &ProgressBar, - registry_url: Url, - resolution: Arc<NpmResolution>, - maybe_node_modules_path: Option<PathBuf>, - system_info: NpmSystemInfo, -) -> Arc<dyn NpmPackageFsResolver> { - match maybe_node_modules_path { - Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new( - fs, - cache, - progress_bar.clone(), - registry_url, - node_modules_folder, - resolution, - system_info, - )), - None => Arc::new(GlobalNpmPackageResolver::new( - fs, - cache, - registry_url, - resolution, - system_info, - )), - } -} diff --git a/cli/npm/resolution.rs b/cli/npm/managed/resolution.rs index 3e76d5e85..05c1227a7 100644 --- a/cli/npm/resolution.rs +++ b/cli/npm/managed/resolution.rs @@ -34,7 +34,7 @@ use deno_semver::VersionReq; use crate::args::Lockfile; use crate::util::sync::TaskQueue; -use super::registry::CliNpmRegistryApi; +use super::super::registry::CliNpmRegistryApi; /// Handles updating and storing npm resolution in memory where the underlying /// snapshot can be updated concurrently. Additionally handles updating the lockfile @@ -221,6 +221,8 @@ impl NpmResolution { .map(|pkg| pkg.id.clone()) } + // todo: NEXT + /// Resolves a package requirement for deno graph. This should only be /// called by deno_graph's NpmResolver or for resolving packages in /// a package.json @@ -273,10 +275,14 @@ impl NpmResolution { .all_system_packages_partitioned(system_info) } + // todo: NEXT + pub fn has_packages(&self) -> bool { !self.snapshot.read().is_empty() } + // todo: NEXT + pub fn snapshot(&self) -> NpmResolutionSnapshot { self.snapshot.read().clone() } @@ -287,6 +293,8 @@ impl NpmResolution { self.snapshot.read().as_valid_serialized() } + // todo: NEXT + pub fn serialized_valid_snapshot_for_system( &self, system_info: &NpmSystemInfo, diff --git a/cli/npm/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs index 4076579bf..4076579bf 100644 --- a/cli/npm/resolvers/common.rs +++ b/cli/npm/managed/resolvers/common.rs diff --git a/cli/npm/resolvers/global.rs b/cli/npm/managed/resolvers/global.rs index e1144f610..25db62f73 100644 --- a/cli/npm/resolvers/global.rs +++ b/cli/npm/managed/resolvers/global.rs @@ -20,10 +20,10 @@ use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; -use crate::npm::resolution::NpmResolution; -use crate::npm::resolvers::common::cache_packages; use crate::npm::NpmCache; +use super::super::resolution::NpmResolution; +use super::common::cache_packages; use super::common::types_package_name; use super::common::NpmPackageFsResolver; use super::common::RegistryReadPermissionChecker; diff --git a/cli/npm/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index afa95e756..57170eccd 100644 --- a/cli/npm/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -42,11 +42,11 @@ use serde::Deserialize; use serde::Serialize; use crate::npm::cache::mixed_case_package_name_encode; -use crate::npm::resolution::NpmResolution; use crate::npm::NpmCache; use crate::util::fs::copy_dir_recursive; use crate::util::fs::hard_link_dir_recursive; +use super::super::resolution::NpmResolution; use super::common::types_package_name; use super::common::NpmPackageFsResolver; use super::common::RegistryReadPermissionChecker; diff --git a/cli/npm/managed/resolvers/mod.rs b/cli/npm/managed/resolvers/mod.rs new file mode 100644 index 000000000..b6d96c4af --- /dev/null +++ b/cli/npm/managed/resolvers/mod.rs @@ -0,0 +1,50 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +mod common; +mod global; +mod local; + +use std::path::PathBuf; +use std::sync::Arc; + +use deno_core::url::Url; +use deno_npm::NpmSystemInfo; +use deno_runtime::deno_fs::FileSystem; + +use crate::npm::NpmCache; +use crate::util::progress_bar::ProgressBar; + +pub use self::common::NpmPackageFsResolver; +use self::global::GlobalNpmPackageResolver; +use self::local::LocalNpmPackageResolver; + +use super::NpmResolution; + +pub fn create_npm_fs_resolver( + fs: Arc<dyn FileSystem>, + cache: Arc<NpmCache>, + progress_bar: &ProgressBar, + registry_url: Url, + resolution: Arc<NpmResolution>, + maybe_node_modules_path: Option<PathBuf>, + system_info: NpmSystemInfo, +) -> Arc<dyn NpmPackageFsResolver> { + match maybe_node_modules_path { + Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new( + fs, + cache, + progress_bar.clone(), + registry_url, + node_modules_folder, + resolution, + system_info, + )), + None => Arc::new(GlobalNpmPackageResolver::new( + fs, + cache, + registry_url, + resolution, + system_info, + )), + } +} diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 1b6ec243c..114bf15f2 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -1,20 +1,100 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +mod managed; + +// todo(#18967): move the cache, registry, and tarball into the managed folder mod cache; -mod installer; mod registry; -mod resolution; -mod resolvers; mod tarball; +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::Arc; + +use deno_ast::ModuleSpecifier; +use deno_core::error::AnyError; +use deno_core::url::Url; +use deno_graph::NpmPackageReqResolution; +use deno_npm::resolution::PackageReqNotFoundError; +use deno_runtime::deno_node::NpmResolver; + pub use cache::NpmCache; pub use cache::NpmCacheDir; -pub use installer::PackageJsonDepsInstaller; +use deno_semver::npm::NpmPackageNvReference; +use deno_semver::npm::NpmPackageReqReference; +use deno_semver::package::PackageNv; +use deno_semver::package::PackageReq; +pub use managed::create_npm_fs_resolver; +pub use managed::ManagedCliNpmResolver; +pub use managed::NpmPackageFsResolver; +pub use managed::NpmProcessState; +pub use managed::NpmResolution; +pub use managed::PackageJsonDepsInstaller; pub use registry::CliNpmRegistryApi; -pub use resolution::NpmResolution; -pub use resolvers::create_npm_fs_resolver; -pub use resolvers::CliNpmResolver; -pub use resolvers::InnerCliNpmResolverRef; -pub use resolvers::ManagedCliNpmResolver; -pub use resolvers::NpmPackageFsResolver; -pub use resolvers::NpmProcessState; + +pub enum InnerCliNpmResolverRef<'a> { + Managed(&'a ManagedCliNpmResolver), + #[allow(dead_code)] + Byonm(&'a ByonmCliNpmResolver), +} + +pub trait CliNpmResolver: NpmResolver { + fn into_npm_resolver(self: Arc<Self>) -> Arc<dyn NpmResolver>; + + fn root_dir_url(&self) -> &Url; + + fn as_inner(&self) -> InnerCliNpmResolverRef; + + fn as_managed(&self) -> Option<&ManagedCliNpmResolver> { + match self.as_inner() { + InnerCliNpmResolverRef::Managed(inner) => Some(inner), + InnerCliNpmResolverRef::Byonm(_) => None, + } + } + + fn node_modules_path(&self) -> Option<PathBuf>; + + /// Checks if the provided package req's folder is cached. + fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool; + + /// Resolves a package requirement for deno graph. This should only be + /// called by deno_graph's NpmResolver or for resolving packages in + /// a package.json + fn resolve_npm_for_deno_graph( + &self, + pkg_req: &PackageReq, + ) -> NpmPackageReqResolution; + + fn resolve_pkg_nv_ref_from_pkg_req_ref( + &self, + req_ref: &NpmPackageReqReference, + ) -> Result<NpmPackageNvReference, PackageReqNotFoundError>; + + /// Resolve the root folder of the package the provided specifier is in. + /// + /// This will error when the provided specifier is not in an npm package. + fn resolve_pkg_folder_from_specifier( + &self, + specifier: &ModuleSpecifier, + ) -> Result<Option<PathBuf>, AnyError>; + + fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + ) -> Result<PathBuf, AnyError>; + + fn resolve_pkg_folder_from_deno_module( + &self, + nv: &PackageNv, + ) -> Result<PathBuf, AnyError>; + + /// Gets the state of npm for the process. + fn get_npm_process_state(&self) -> String; + + // todo(#18967): should instead return a hash state of the resolver + // or perhaps this could be non-BYONM only and byonm always runs deno check + fn package_reqs(&self) -> HashMap<PackageReq, PackageNv>; +} + +// todo(#18967): implement this +pub struct ByonmCliNpmResolver; diff --git a/cli/npm/registry.rs b/cli/npm/registry.rs index e960d926f..61eb4123d 100644 --- a/cli/npm/registry.rs +++ b/cli/npm/registry.rs @@ -75,12 +75,6 @@ impl CliNpmRegistryApi { }))) } - /// Creates an npm registry API that will be uninitialized. This is - /// useful for tests or for initializing the LSP. - pub fn new_uninitialized() -> Self { - Self(None) - } - /// Clears the internal memory cache. pub fn clear_memory_cache(&self) { self.inner().clear_memory_cache(); |