diff options
Diffstat (limited to 'cli/args/package_json.rs')
-rw-r--r-- | cli/args/package_json.rs | 128 |
1 files changed, 69 insertions, 59 deletions
diff --git a/cli/args/package_json.rs b/cli/args/package_json.rs index b6ccb33a4..eb1c41c5d 100644 --- a/cli/args/package_json.rs +++ b/cli/args/package_json.rs @@ -1,77 +1,87 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use std::path::Path; use std::path::PathBuf; use std::sync::Arc; -use deno_config::package_json::PackageJsonDeps; -use deno_core::anyhow::bail; -use deno_core::error::AnyError; -use deno_runtime::deno_fs::RealFs; -use deno_runtime::deno_node::load_pkg_json; -use deno_runtime::deno_node::PackageJson; +use deno_config::package_json::PackageJsonDepValue; +use deno_config::workspace::Workspace; use deno_semver::package::PackageReq; -#[derive(Debug, Default)] -pub struct PackageJsonDepsProvider(Option<PackageJsonDeps>); - -impl PackageJsonDepsProvider { - pub fn new(deps: Option<PackageJsonDeps>) -> Self { - Self(deps) - } - - pub fn deps(&self) -> Option<&PackageJsonDeps> { - self.0.as_ref() - } - - pub fn reqs(&self) -> Option<Vec<&PackageReq>> { - match &self.0 { - Some(deps) => { - let mut package_reqs = deps - .values() - .filter_map(|r| r.as_ref().ok()) - .collect::<Vec<_>>(); - package_reqs.sort(); // deterministic resolution - Some(package_reqs) - } - None => None, - } - } +#[derive(Debug)] +pub struct InstallNpmWorkspacePkg { + pub alias: String, + pub pkg_dir: PathBuf, } -/// Attempts to discover the package.json file, maybe stopping when it -/// reaches the specified `maybe_stop_at` directory. -pub fn discover_from( - start: &Path, - maybe_stop_at: Option<PathBuf>, -) -> Result<Option<Arc<PackageJson>>, AnyError> { - const PACKAGE_JSON_NAME: &str = "package.json"; +// todo(#24419): this is not correct, but it's good enough for now. +// We need deno_npm to be able to understand workspace packages and +// then have a way to properly lay them out on the file system +#[derive(Debug, Default)] +pub struct PackageJsonInstallDepsProvider { + remote_pkg_reqs: Vec<PackageReq>, + workspace_pkgs: Vec<InstallNpmWorkspacePkg>, +} - // note: ancestors() includes the `start` path - for ancestor in start.ancestors() { - let path = ancestor.join(PACKAGE_JSON_NAME); +impl PackageJsonInstallDepsProvider { + pub fn empty() -> Self { + Self::default() + } - let package_json = match load_pkg_json(&RealFs, &path) { - Ok(Some(package_json)) => package_json, - Ok(None) => { - if let Some(stop_at) = maybe_stop_at.as_ref() { - if ancestor == stop_at { - break; + pub fn from_workspace(workspace: &Arc<Workspace>) -> Self { + let mut workspace_pkgs = Vec::new(); + let mut remote_pkg_reqs = Vec::new(); + let workspace_npm_pkgs = workspace.npm_packages(); + for pkg_json in workspace.package_jsons() { + let deps = pkg_json.resolve_local_package_json_deps(); + let mut pkg_reqs = Vec::with_capacity(deps.len()); + for (alias, dep) in deps { + let Ok(dep) = dep else { + continue; + }; + match dep { + PackageJsonDepValue::Req(pkg_req) => { + if let Some(pkg) = workspace_npm_pkgs + .iter() + .find(|pkg| pkg.matches_req(&pkg_req)) + { + workspace_pkgs.push(InstallNpmWorkspacePkg { + alias, + pkg_dir: pkg.pkg_json.dir_path().to_path_buf(), + }); + } else { + pkg_reqs.push(pkg_req) + } + } + PackageJsonDepValue::Workspace(version_req) => { + if let Some(pkg) = workspace_npm_pkgs.iter().find(|pkg| { + pkg.matches_name_and_version_req(&alias, &version_req) + }) { + workspace_pkgs.push(InstallNpmWorkspacePkg { + alias, + pkg_dir: pkg.pkg_json.dir_path().to_path_buf(), + }); + } } } - continue; } - Err(err) => bail!( - "Error loading package.json at {}. {:#}", - path.display(), - err - ), - }; + // sort within each package + pkg_reqs.sort(); - log::debug!("package.json file found at '{}'", path.display()); - return Ok(Some(package_json)); + remote_pkg_reqs.extend(pkg_reqs); + } + remote_pkg_reqs.shrink_to_fit(); + workspace_pkgs.shrink_to_fit(); + Self { + remote_pkg_reqs, + workspace_pkgs, + } + } + + pub fn remote_pkg_reqs(&self) -> &Vec<PackageReq> { + &self.remote_pkg_reqs } - log::debug!("No package.json file found"); - Ok(None) + pub fn workspace_pkgs(&self) -> &Vec<InstallNpmWorkspacePkg> { + &self.workspace_pkgs + } } |