fix(npm): show a progress bar when initializing the node_modules folder (#18136)

Creating the node_modules folder when the packages are already
downloaded can take a bit of time and not knowing what is going on can
be confusing. It's better to show a progress bar.
This commit is contained in:
David Sherret 2023-03-13 14:18:29 -04:00 committed by GitHub
parent e8f22c0765
commit 44b0d4cb11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 256 additions and 165 deletions

View file

@ -11,6 +11,8 @@ use std::path::PathBuf;
use crate::util::fs::symlink_dir;
use crate::util::fs::LaxSingleProcessFsFlag;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressMessagePrompt;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
@ -42,6 +44,7 @@ use super::common::NpmPackageFsResolver;
#[derive(Debug, Clone)]
pub struct LocalNpmPackageResolver {
cache: NpmCache,
progress_bar: ProgressBar,
resolution: NpmResolution,
registry_url: Url,
root_node_modules_path: PathBuf,
@ -51,12 +54,14 @@ pub struct LocalNpmPackageResolver {
impl LocalNpmPackageResolver {
pub fn new(
cache: NpmCache,
progress_bar: ProgressBar,
registry_url: Url,
node_modules_folder: PathBuf,
resolution: NpmResolution,
) -> Self {
Self {
cache,
progress_bar,
resolution,
registry_url,
root_node_modules_url: Url::from_directory_path(&node_modules_folder)
@ -200,8 +205,14 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
}
async fn cache_packages(&self) -> Result<(), AnyError> {
sync_resolver_with_fs(self).await?;
Ok(())
sync_resolution_with_fs(
&self.resolution.snapshot(),
&self.cache,
&self.progress_bar,
&self.registry_url,
&self.root_node_modules_path,
)
.await
}
fn ensure_read_permission(
@ -217,22 +228,11 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
}
}
async fn sync_resolver_with_fs(
resolver: &LocalNpmPackageResolver,
) -> Result<(), AnyError> {
sync_resolution_with_fs(
&resolver.resolution.snapshot(),
&resolver.cache,
&resolver.registry_url,
&resolver.root_node_modules_path,
)
.await
}
/// Creates a pnpm style folder structure.
async fn sync_resolution_with_fs(
snapshot: &NpmResolutionSnapshot,
cache: &NpmCache,
progress_bar: &ProgressBar,
registry_url: &Url,
root_node_modules_dir_path: &Path,
) -> Result<(), AnyError> {
@ -252,6 +252,8 @@ async fn sync_resolution_with_fs(
)
.await;
let pb_clear_guard = progress_bar.clear_guard(); // prevent flickering
// 1. Write all the packages out the .deno directory.
//
// Copy (hardlink in future) <global_registry_cache>/<package_id>/ to
@ -277,6 +279,7 @@ async fn sync_resolution_with_fs(
.should_use_for_npm_package(&package.pkg_id.nv.name)
|| !initialized_file.exists()
{
let pb = progress_bar.clone();
let cache = cache.clone();
let registry_url = registry_url.clone();
let package = package.clone();
@ -284,6 +287,10 @@ async fn sync_resolution_with_fs(
cache
.ensure_package(&package.pkg_id.nv, &package.dist, &registry_url)
.await?;
let pb_guard = pb.update_with_prompt(
ProgressMessagePrompt::Initialize,
&package.pkg_id.nv.to_string(),
);
let sub_node_modules = folder_path.join("node_modules");
let package_path =
join_package_name(&sub_node_modules, &package.pkg_id.nv.name);
@ -297,6 +304,8 @@ async fn sync_resolution_with_fs(
copy_dir_recursive(&cache_folder, &package_path)?;
// write out a file that indicates this folder has been initialized
fs::write(initialized_file, "")?;
// finally stop showing the progress bar
drop(pb_guard); // explicit for clarity
Ok(())
});
if sync_download {
@ -411,6 +420,7 @@ async fn sync_resolution_with_fs(
}
drop(single_process_lock);
drop(pb_clear_guard);
Ok(())
}

View file

@ -27,6 +27,7 @@ use std::sync::Arc;
use crate::args::Lockfile;
use crate::util::fs::canonicalize_path_maybe_not_exists;
use crate::util::progress_bar::ProgressBar;
use self::common::NpmPackageFsResolver;
use self::local::LocalNpmPackageResolver;
@ -276,6 +277,7 @@ impl RequireNpmResolver for NpmPackageResolver {
pub fn create_npm_fs_resolver(
cache: NpmCache,
progress_bar: &ProgressBar,
registry_url: Url,
resolution: NpmResolution,
maybe_node_modules_path: Option<PathBuf>,
@ -283,6 +285,7 @@ pub fn create_npm_fs_resolver(
match maybe_node_modules_path {
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
cache,
progress_bar.clone(),
registry_url,
node_modules_folder,
resolution,