diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/args/flags.rs | 2 | ||||
-rw-r--r-- | cli/args/package_json.rs | 20 | ||||
-rw-r--r-- | cli/npm/managed/mod.rs | 21 | ||||
-rw-r--r-- | cli/tools/installer.rs | 4 | ||||
-rw-r--r-- | cli/tools/registry/pm.rs | 33 | ||||
-rw-r--r-- | cli/tools/registry/pm/cache_deps.rs | 1 |
6 files changed, 67 insertions, 14 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 06ce50783..258712ca9 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -2910,6 +2910,7 @@ List all available tasks: .help("Specify the directory to run the task in") .value_hint(ValueHint::DirPath), ) + .arg(node_modules_dir_arg()) }) } @@ -4974,6 +4975,7 @@ fn task_parse(flags: &mut Flags, matches: &mut ArgMatches) { .unwrap_or(ConfigFlag::Discover); unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionAndRuntime); + node_modules_arg_parse(flags, matches); let mut task_flags = TaskFlags { cwd: matches.remove_one::<String>("cwd"), diff --git a/cli/args/package_json.rs b/cli/args/package_json.rs index 2529e54fd..2ef39a30d 100644 --- a/cli/args/package_json.rs +++ b/cli/args/package_json.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use deno_config::workspace::Workspace; use deno_core::serde_json; use deno_package_json::PackageJsonDepValue; +use deno_package_json::PackageJsonDepValueParseError; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageReq; @@ -26,6 +27,7 @@ pub struct InstallNpmWorkspacePkg { pub struct NpmInstallDepsProvider { remote_pkgs: Vec<InstallNpmRemotePkg>, workspace_pkgs: Vec<InstallNpmWorkspacePkg>, + pkg_json_dep_errors: Vec<PackageJsonDepValueParseError>, } impl NpmInstallDepsProvider { @@ -37,6 +39,7 @@ impl NpmInstallDepsProvider { // todo(dsherret): estimate capacity? let mut workspace_pkgs = Vec::new(); let mut remote_pkgs = Vec::new(); + let mut pkg_json_dep_errors = Vec::new(); let workspace_npm_pkgs = workspace.npm_packages(); for (_, folder) in workspace.config_folders() { @@ -83,8 +86,12 @@ impl NpmInstallDepsProvider { let deps = pkg_json.resolve_local_package_json_deps(); let mut pkg_pkgs = Vec::with_capacity(deps.len()); for (alias, dep) in deps { - let Ok(dep) = dep else { - continue; + let dep = match dep { + Ok(dep) => dep, + Err(err) => { + pkg_json_dep_errors.push(err); + continue; + } }; match dep { PackageJsonDepValue::Req(pkg_req) => { @@ -131,14 +138,19 @@ impl NpmInstallDepsProvider { Self { remote_pkgs, workspace_pkgs, + pkg_json_dep_errors, } } - pub fn remote_pkgs(&self) -> &Vec<InstallNpmRemotePkg> { + pub fn remote_pkgs(&self) -> &[InstallNpmRemotePkg] { &self.remote_pkgs } - pub fn workspace_pkgs(&self) -> &Vec<InstallNpmWorkspacePkg> { + pub fn workspace_pkgs(&self) -> &[InstallNpmWorkspacePkg] { &self.workspace_pkgs } + + pub fn pkg_json_dep_errors(&self) -> &[PackageJsonDepValueParseError] { + &self.pkg_json_dep_errors + } } diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index 7bb254cb5..225cd6c29 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -20,6 +20,7 @@ use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::NpmPackageId; use deno_npm::NpmResolutionPackage; use deno_npm::NpmSystemInfo; +use deno_runtime::colors; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeRequireResolver; @@ -478,6 +479,25 @@ impl ManagedCliNpmResolver { self.resolution.resolve_pkg_id_from_pkg_req(req) } + pub fn ensure_no_pkg_json_dep_errors(&self) -> Result<(), AnyError> { + for err in self.npm_install_deps_provider.pkg_json_dep_errors() { + match err { + deno_package_json::PackageJsonDepValueParseError::VersionReq(_) => { + return Err( + AnyError::from(err.clone()) + .context("Failed to install from package.json"), + ); + } + deno_package_json::PackageJsonDepValueParseError::Unsupported { + .. + } => { + log::warn!("{} {} in package.json", colors::yellow("Warning"), err) + } + } + } + Ok(()) + } + /// Ensures that the top level `package.json` dependencies are installed. /// This may set up the `node_modules` directory. /// @@ -489,6 +509,7 @@ impl ManagedCliNpmResolver { if !self.top_level_install_flag.raise() { return Ok(false); // already did this } + let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs(); if pkg_json_remote_pkgs.is_empty() { return Ok(false); diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index bc8769de1..ed86e86c7 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -298,6 +298,10 @@ async fn install_local( } InstallFlagsLocal::TopLevel => { let factory = CliFactory::from_flags(flags); + // surface any errors in the package.json + if let Some(npm_resolver) = factory.npm_resolver().await?.as_managed() { + npm_resolver.ensure_no_pkg_json_dep_errors()?; + } crate::tools::registry::cache_top_level_deps(&factory, None).await?; if let Some(lockfile) = factory.cli_options()?.maybe_lockfile() { diff --git a/cli/tools/registry/pm.rs b/cli/tools/registry/pm.rs index c92710f46..f56774e8e 100644 --- a/cli/tools/registry/pm.rs +++ b/cli/tools/registry/pm.rs @@ -558,12 +558,7 @@ pub async fn add( result.context("Failed to update configuration file")?; } - // clear the previously cached package.json from memory before reloading it - node_resolver::PackageJsonThreadLocalCache::clear(); - // make a new CliFactory to pick up the updated config file - let cli_factory = CliFactory::from_flags(flags); - // cache deps - cache_deps::cache_top_level_deps(&cli_factory, Some(jsr_resolver)).await?; + npm_install_after_modification(flags, Some(jsr_resolver)).await?; Ok(()) } @@ -786,11 +781,29 @@ pub async fn remove( config.commit().await?; } - // Update deno.lock - node_resolver::PackageJsonThreadLocalCache::clear(); - let cli_factory = CliFactory::from_flags(flags); - cache_deps::cache_top_level_deps(&cli_factory, None).await?; + npm_install_after_modification(flags, None).await?; + } + + Ok(()) +} + +async fn npm_install_after_modification( + flags: Arc<Flags>, + // explicitly provided to prevent redownloading + jsr_resolver: Option<Arc<crate::jsr::JsrFetchResolver>>, +) -> Result<(), AnyError> { + // clear the previously cached package.json from memory before reloading it + node_resolver::PackageJsonThreadLocalCache::clear(); + + // make a new CliFactory to pick up the updated config file + let cli_factory = CliFactory::from_flags(flags); + // surface any errors in the package.json + let npm_resolver = cli_factory.npm_resolver().await?; + if let Some(npm_resolver) = npm_resolver.as_managed() { + npm_resolver.ensure_no_pkg_json_dep_errors()?; } + // npm install + cache_deps::cache_top_level_deps(&cli_factory, jsr_resolver).await?; Ok(()) } diff --git a/cli/tools/registry/pm/cache_deps.rs b/cli/tools/registry/pm/cache_deps.rs index 7d1773b34..c8258e600 100644 --- a/cli/tools/registry/pm/cache_deps.rs +++ b/cli/tools/registry/pm/cache_deps.rs @@ -11,6 +11,7 @@ use deno_core::futures::StreamExt; use deno_semver::package::PackageReq; pub async fn cache_top_level_deps( + // todo(dsherret): don't pass the factory into this function. Instead use ctor deps factory: &CliFactory, jsr_resolver: Option<Arc<crate::jsr::JsrFetchResolver>>, ) -> Result<(), AnyError> { |