diff options
Diffstat (limited to 'cli/npm/installer.rs')
-rw-r--r-- | cli/npm/installer.rs | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/cli/npm/installer.rs b/cli/npm/installer.rs index 41d85a9b9..5a15494ab 100644 --- a/cli/npm/installer.rs +++ b/cli/npm/installer.rs @@ -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 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)) - } - })); + let mut reqs_with_info_futures = inner.reqs_with_info_futures(); - 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(()) |