mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 10:59:13 +00:00
fix(npm): cache bust npm specifiers more aggressively (#18636)
Part 1: #18622 Part 2: This PR Closes #16901 --------- Co-authored-by: Luca Casonato <hello@lcas.dev>
This commit is contained in:
parent
806671af33
commit
0e3f62d444
14 changed files with 289 additions and 143 deletions
|
@ -1,33 +1,69 @@
|
|||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::stream::FuturesOrdered;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
|
||||
use deno_semver::npm::NpmPackageReq;
|
||||
|
||||
use crate::args::package_json::PackageJsonDeps;
|
||||
use crate::util::sync::AtomicFlag;
|
||||
|
||||
use super::NpmRegistry;
|
||||
use super::CliNpmRegistryApi;
|
||||
use super::NpmResolution;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PackageJsonDepsInstallerInner {
|
||||
has_installed_flag: AtomicFlag,
|
||||
npm_registry_api: NpmRegistry,
|
||||
npm_registry_api: CliNpmRegistryApi,
|
||||
npm_resolution: NpmResolution,
|
||||
package_deps: PackageJsonDeps,
|
||||
}
|
||||
|
||||
impl PackageJsonDepsInstallerInner {
|
||||
pub fn reqs(&self) -> Vec<&NpmPackageReq> {
|
||||
let mut package_reqs = self
|
||||
.package_deps
|
||||
.values()
|
||||
.filter_map(|r| r.as_ref().ok())
|
||||
.collect::<Vec<_>>();
|
||||
package_reqs.sort(); // deterministic resolution
|
||||
package_reqs
|
||||
}
|
||||
|
||||
pub fn reqs_with_info_futures(
|
||||
&self,
|
||||
) -> FuturesOrdered<
|
||||
impl Future<
|
||||
Output = Result<
|
||||
(&NpmPackageReq, Arc<deno_npm::registry::NpmPackageInfo>),
|
||||
NpmRegistryPackageInfoLoadError,
|
||||
>,
|
||||
>,
|
||||
> {
|
||||
let package_reqs = self.reqs();
|
||||
|
||||
FuturesOrdered::from_iter(package_reqs.into_iter().map(|req| {
|
||||
let api = self.npm_registry_api.clone();
|
||||
async move {
|
||||
let info = api.package_info(&req.name).await?;
|
||||
Ok::<_, NpmRegistryPackageInfoLoadError>((req, info))
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds and controls installing dependencies from package.json.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PackageJsonDepsInstaller(Option<Arc<PackageJsonDepsInstallerInner>>);
|
||||
|
||||
impl PackageJsonDepsInstaller {
|
||||
pub fn new(
|
||||
npm_registry_api: NpmRegistry,
|
||||
npm_registry_api: CliNpmRegistryApi,
|
||||
npm_resolution: NpmResolution,
|
||||
deps: Option<PackageJsonDeps>,
|
||||
) -> Self {
|
||||
|
@ -57,27 +93,23 @@ impl PackageJsonDepsInstaller {
|
|||
return Ok(()); // already installed by something else
|
||||
}
|
||||
|
||||
let mut package_reqs = inner
|
||||
.package_deps
|
||||
.values()
|
||||
.filter_map(|r| r.as_ref().ok())
|
||||
.collect::<Vec<_>>();
|
||||
package_reqs.sort(); // deterministic resolution
|
||||
let mut reqs_with_info_futures = inner.reqs_with_info_futures();
|
||||
|
||||
let mut req_with_infos =
|
||||
FuturesOrdered::from_iter(package_reqs.into_iter().map(|req| {
|
||||
let api = inner.npm_registry_api.clone();
|
||||
async move {
|
||||
let info = api.package_info(&req.name).await?;
|
||||
Ok::<_, AnyError>((req, info))
|
||||
}
|
||||
}));
|
||||
|
||||
while let Some(result) = req_with_infos.next().await {
|
||||
while let Some(result) = reqs_with_info_futures.next().await {
|
||||
let (req, info) = result?;
|
||||
inner
|
||||
let result = inner
|
||||
.npm_resolution
|
||||
.resolve_package_req_as_pending_with_info(req, &info)?;
|
||||
.resolve_package_req_as_pending_with_info(req, &info);
|
||||
if let Err(err) = result {
|
||||
if inner.npm_registry_api.mark_force_reload() {
|
||||
log::debug!("Failed to resolve package. Retrying. Error: {err:#}");
|
||||
// re-initialize
|
||||
inner.npm_registry_api.clear_memory_cache();
|
||||
reqs_with_info_futures = inner.reqs_with_info_futures();
|
||||
} else {
|
||||
return Err(err.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue