summaryrefslogtreecommitdiff
path: root/cli/args/package_json.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/args/package_json.rs')
-rw-r--r--cli/args/package_json.rs128
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
+ }
}