summaryrefslogtreecommitdiff
path: root/cli/npm/cache.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2022-11-27 13:25:08 -0500
committerGitHub <noreply@github.com>2022-11-27 13:25:08 -0500
commitfb04e87387e04053bf41a1512b4850adf62202c6 (patch)
treea4c57282a33b510d8638681ace10356a4c60a6e4 /cli/npm/cache.rs
parenta4dfc6f95553b8e2c6da78cb87a8c74a2f7c7682 (diff)
fix(npm): ensure npm package downloaded once per run when using `--reload` (#16842)
Diffstat (limited to 'cli/npm/cache.rs')
-rw-r--r--cli/npm/cache.rs34
1 files changed, 28 insertions, 6 deletions
diff --git a/cli/npm/cache.rs b/cli/npm/cache.rs
index b2c842309..5e2f06ef7 100644
--- a/cli/npm/cache.rs
+++ b/cli/npm/cache.rs
@@ -1,14 +1,17 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+use std::collections::HashSet;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
+use std::sync::Arc;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
+use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use crate::cache::DenoDir;
@@ -317,6 +320,8 @@ pub struct NpmCache {
cache_setting: CacheSetting,
http_client: HttpClient,
progress_bar: ProgressBar,
+ /// ensures a package is only downloaded once per run
+ previously_reloaded_packages: Arc<Mutex<HashSet<String>>>,
}
impl NpmCache {
@@ -331,6 +336,7 @@ impl NpmCache {
cache_setting,
http_client,
progress_bar,
+ previously_reloaded_packages: Default::default(),
}
}
@@ -338,6 +344,26 @@ impl NpmCache {
self.readonly.clone()
}
+ pub fn cache_setting(&self) -> &CacheSetting {
+ &self.cache_setting
+ }
+
+ /// Checks if the cache should be used for the provided name and version.
+ /// NOTE: Subsequent calls for the same package will always return `true`
+ /// to ensure a package is only downloaded once per run of the CLI. This
+ /// prevents downloads from re-occurring when someone has `--reload` and
+ /// and imports a dynamic import that imports the same package again for example.
+ fn should_use_global_cache_for_package(
+ &self,
+ package: (&str, &NpmVersion),
+ ) -> bool {
+ self.cache_setting.should_use_for_npm_package(package.0)
+ || !self
+ .previously_reloaded_packages
+ .lock()
+ .insert(format!("{}@{}", package.0, package.1))
+ }
+
pub async fn ensure_package(
&self,
package: (&str, &NpmVersion),
@@ -352,10 +378,6 @@ impl NpmCache {
})
}
- pub fn should_use_cache_for_npm_package(&self, package_name: &str) -> bool {
- self.cache_setting.should_use_for_npm_package(package_name)
- }
-
async fn ensure_package_inner(
&self,
package: (&str, &NpmVersion),
@@ -367,11 +389,11 @@ impl NpmCache {
package.1,
registry_url,
);
- if package_folder.exists()
+ if self.should_use_global_cache_for_package(package)
+ && package_folder.exists()
// if this file exists, then the package didn't successfully extract
// the first time, or another process is currently extracting the zip file
&& !package_folder.join(NPM_PACKAGE_SYNC_LOCK_FILENAME).exists()
- && self.should_use_cache_for_npm_package(package.0)
{
return Ok(());
} else if self.cache_setting == CacheSetting::Only {