diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2022-11-27 13:25:08 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-27 13:25:08 -0500 |
commit | fb04e87387e04053bf41a1512b4850adf62202c6 (patch) | |
tree | a4c57282a33b510d8638681ace10356a4c60a6e4 /cli/npm/cache.rs | |
parent | a4dfc6f95553b8e2c6da78cb87a8c74a2f7c7682 (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.rs | 34 |
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 { |