diff options
Diffstat (limited to 'cli/args/package_json.rs')
-rw-r--r-- | cli/args/package_json.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/cli/args/package_json.rs b/cli/args/package_json.rs index 76d353c5e..73bcfb582 100644 --- a/cli/args/package_json.rs +++ b/cli/args/package_json.rs @@ -1,6 +1,8 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use std::collections::HashMap; +use std::path::Path; +use std::path::PathBuf; use deno_core::anyhow::anyhow; use deno_core::anyhow::bail; @@ -83,6 +85,44 @@ pub fn get_local_package_json_version_reqs( Ok(result) } +/// 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<PackageJson>, AnyError> { + const PACKAGE_JSON_NAME: &str = "package.json"; + + // note: ancestors() includes the `start` path + for ancestor in start.ancestors() { + let path = ancestor.join(PACKAGE_JSON_NAME); + + let source = match std::fs::read_to_string(&path) { + Ok(source) => source, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + if let Some(stop_at) = maybe_stop_at.as_ref() { + if ancestor == stop_at { + break; + } + } + continue; + } + Err(err) => bail!( + "Error loading package.json at {}. {:#}", + path.display(), + err + ), + }; + + let package_json = PackageJson::load_from_string(path.clone(), source)?; + log::debug!("package.json file found at '{}'", path.display()); + return Ok(Some(package_json)); + } + + log::debug!("No package.json file found"); + Ok(None) +} + #[cfg(test)] mod test { use pretty_assertions::assert_eq; |