fix(npm): add support for npm packages in lock files (#15938)

This commit adds support for npm packages in the lock file.
This commit is contained in:
Bartek Iwańczuk 2022-10-25 18:20:07 +02:00 committed by GitHub
parent 10c3c0ee57
commit 9835b095e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 513 additions and 16 deletions

View file

@ -11,6 +11,7 @@ use deno_core::futures;
use deno_core::futures::future::BoxFuture;
use deno_core::url::Url;
use crate::lockfile::Lockfile;
use crate::npm::cache::should_sync_download;
use crate::npm::resolution::NpmResolutionSnapshot;
use crate::npm::NpmCache;
@ -50,6 +51,8 @@ pub trait InnerNpmPackageResolver: Send + Sync {
fn ensure_read_permission(&self, path: &Path) -> Result<(), AnyError>;
fn snapshot(&self) -> NpmResolutionSnapshot;
fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError>;
}
/// Caches all the packages in parallel.

View file

@ -15,6 +15,7 @@ use deno_core::url::Url;
use deno_runtime::deno_node::PackageJson;
use deno_runtime::deno_node::TYPES_CONDITIONS;
use crate::lockfile::Lockfile;
use crate::npm::resolution::NpmResolution;
use crate::npm::resolution::NpmResolutionSnapshot;
use crate::npm::resolvers::common::cache_packages;
@ -145,6 +146,11 @@ impl InnerNpmPackageResolver for GlobalNpmPackageResolver {
fn snapshot(&self) -> NpmResolutionSnapshot {
self.resolution.snapshot()
}
fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> {
let snapshot = self.resolution.snapshot();
self.resolution.lock(lockfile, &snapshot)
}
}
async fn cache_packages_in_resolver(

View file

@ -22,6 +22,7 @@ use deno_runtime::deno_node::TYPES_CONDITIONS;
use tokio::task::JoinHandle;
use crate::fs_util;
use crate::lockfile::Lockfile;
use crate::npm::cache::should_sync_download;
use crate::npm::resolution::NpmResolution;
use crate::npm::resolution::NpmResolutionSnapshot;
@ -213,6 +214,10 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver {
fn snapshot(&self) -> NpmResolutionSnapshot {
self.resolution.snapshot()
}
fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> {
self.resolution.lock(lockfile, &self.snapshot())
}
}
async fn sync_resolver_with_fs(

View file

@ -8,6 +8,7 @@ use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_runtime::deno_node::PathClean;
use deno_runtime::deno_node::RequireNpmResolver;
@ -21,6 +22,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use crate::fs_util;
use crate::lockfile::Lockfile;
use self::common::InnerNpmPackageResolver;
use self::local::LocalNpmPackageResolver;
@ -70,6 +72,7 @@ pub struct NpmPackageResolver {
local_node_modules_path: Option<PathBuf>,
api: NpmRegistryApi,
cache: NpmCache,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
}
impl std::fmt::Debug for NpmPackageResolver {
@ -101,6 +104,32 @@ impl NpmPackageResolver {
)
}
/// This function will replace current resolver with a new one built from a
/// snapshot created out of the lockfile.
pub async fn add_lockfile(
&mut self,
lockfile: Arc<Mutex<Lockfile>>,
) -> Result<(), AnyError> {
let snapshot =
NpmResolutionSnapshot::from_lockfile(lockfile.clone(), &self.api).await?;
self.maybe_lockfile = Some(lockfile);
if let Some(node_modules_folder) = &self.local_node_modules_path {
self.inner = Arc::new(LocalNpmPackageResolver::new(
self.cache.clone(),
self.api.clone(),
node_modules_folder.clone(),
Some(snapshot),
));
} else {
self.inner = Arc::new(GlobalNpmPackageResolver::new(
self.cache.clone(),
self.api.clone(),
Some(snapshot),
));
}
Ok(())
}
fn new_with_maybe_snapshot(
cache: NpmCache,
api: NpmRegistryApi,
@ -138,6 +167,7 @@ impl NpmPackageResolver {
local_node_modules_path,
api,
cache,
maybe_lockfile: None,
}
}
@ -224,7 +254,15 @@ impl NpmPackageResolver {
));
}
self.inner.add_package_reqs(packages).await
self.inner.add_package_reqs(packages).await?;
// If there's a lock file, update it with all discovered npm packages
if let Some(lockfile_mutex) = &self.maybe_lockfile {
let mut lockfile = lockfile_mutex.lock();
self.lock(&mut lockfile)?;
}
Ok(())
}
/// Sets package requirements to the resolver, removing old requirements and adding new ones.
@ -266,6 +304,10 @@ impl NpmPackageResolver {
Some(self.inner.snapshot()),
)
}
pub fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> {
self.inner.lock(lockfile)
}
}
impl RequireNpmResolver for NpmPackageResolver {