summaryrefslogtreecommitdiff
path: root/cli/npm/installer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/npm/installer.rs')
-rw-r--r--cli/npm/installer.rs74
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(())