summaryrefslogtreecommitdiff
path: root/cli/args/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/args/mod.rs')
-rw-r--r--cli/args/mod.rs164
1 files changed, 84 insertions, 80 deletions
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index 7cb2213e9..3d8a29fe7 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -51,7 +51,6 @@ use deno_runtime::permissions::PermissionsOptions;
use once_cell::sync::Lazy;
use std::collections::BTreeMap;
use std::collections::HashMap;
-use std::collections::HashSet;
use std::env;
use std::io::BufReader;
use std::io::Cursor;
@@ -393,38 +392,35 @@ fn discover_package_json(
flags: &Flags,
maybe_stop_at: Option<PathBuf>,
) -> Result<Option<PackageJson>, AnyError> {
- pub fn discover_from(
+ fn discover_from(
start: &Path,
- checked: &mut HashSet<PathBuf>,
maybe_stop_at: Option<PathBuf>,
) -> Result<Option<PackageJson>, AnyError> {
const PACKAGE_JSON_NAME: &str = "package.json";
for ancestor in start.ancestors() {
- if checked.insert(ancestor.to_path_buf()) {
- 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;
- }
+ 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
- ),
- };
+ 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));
- }
+ let package_json = PackageJson::load_from_string(path.clone(), source)?;
+ log::debug!("package.json file found at '{}'", path.display());
+ return Ok(Some(package_json));
}
// No config file found.
log::debug!("No package.json file found");
@@ -434,21 +430,17 @@ fn discover_package_json(
// TODO(bartlomieju): discover for all subcommands, but print warnings that
// `package.json` is ignored in bundle/compile/etc.
- if let Some(package_json_arg) = flags.package_json_arg() {
- return discover_from(
- &package_json_arg,
- &mut HashSet::new(),
- maybe_stop_at,
- );
- } else if let crate::args::DenoSubcommand::Task(TaskFlags {
- cwd: Some(path),
- ..
+ if let crate::args::DenoSubcommand::Task(TaskFlags {
+ cwd: Some(path), ..
}) = &flags.subcommand
{
// attempt to resolve the config file from the task subcommand's
// `--cwd` when specified
let task_cwd = canonicalize_path(&PathBuf::from(path))?;
- return discover_from(&task_cwd, &mut HashSet::new(), None);
+ return discover_from(&task_cwd, None);
+ } else if let Some(package_json_arg) = flags.package_json_arg() {
+ let package_json_arg = canonicalize_path(&package_json_arg)?;
+ return discover_from(&package_json_arg, maybe_stop_at);
}
log::debug!("No package.json file found");
@@ -542,9 +534,6 @@ pub fn get_root_cert_store(
const RESOLUTION_STATE_ENV_VAR_NAME: &str =
"DENO_DONT_USE_INTERNAL_NODE_COMPAT_STATE";
-static IS_NPM_MAIN: Lazy<bool> =
- Lazy::new(|| std::env::var(RESOLUTION_STATE_ENV_VAR_NAME).is_ok());
-
static NPM_PROCESS_STATE: Lazy<Option<NpmProcessState>> = Lazy::new(|| {
let state = std::env::var(RESOLUTION_STATE_ENV_VAR_NAME).ok()?;
let state: NpmProcessState = serde_json::from_str(&state).ok()?;
@@ -568,6 +557,7 @@ pub struct CliOptions {
// the source of the options is a detail the rest of the
// application need not concern itself with, so keep these private
flags: Flags,
+ maybe_node_modules_folder: Option<PathBuf>,
maybe_config_file: Option<ConfigFile>,
maybe_package_json: Option<PackageJson>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
@@ -577,10 +567,11 @@ pub struct CliOptions {
impl CliOptions {
pub fn new(
flags: Flags,
+ initial_cwd: PathBuf,
maybe_config_file: Option<ConfigFile>,
maybe_lockfile: Option<Lockfile>,
maybe_package_json: Option<PackageJson>,
- ) -> Self {
+ ) -> Result<Self, AnyError> {
if let Some(insecure_allowlist) =
flags.unsafely_ignore_certificate_errors.as_ref()
{
@@ -596,18 +587,28 @@ impl CliOptions {
}
let maybe_lockfile = maybe_lockfile.map(|l| Arc::new(Mutex::new(l)));
+ let maybe_node_modules_folder = resolve_local_node_modules_folder(
+ &initial_cwd,
+ &flags,
+ maybe_config_file.as_ref(),
+ maybe_package_json.as_ref(),
+ )
+ .with_context(|| "Resolving node_modules folder.")?;
- Self {
+ Ok(Self {
+ flags,
maybe_config_file,
maybe_lockfile,
maybe_package_json,
- flags,
+ maybe_node_modules_folder,
overrides: Default::default(),
- }
+ })
}
pub fn from_flags(flags: Flags) -> Result<Self, AnyError> {
- let maybe_config_file = ConfigFile::discover(&flags)?;
+ let initial_cwd =
+ std::env::current_dir().with_context(|| "Failed getting cwd.")?;
+ let maybe_config_file = ConfigFile::discover(&flags, &initial_cwd)?;
let mut maybe_package_json = None;
if let Some(config_file) = &maybe_config_file {
@@ -626,12 +627,13 @@ impl CliOptions {
}
let maybe_lock_file =
lockfile::discover(&flags, maybe_config_file.as_ref())?;
- Ok(Self::new(
+ Self::new(
flags,
+ initial_cwd,
maybe_config_file,
maybe_lock_file,
maybe_package_json,
- ))
+ )
}
pub fn maybe_config_file_specifier(&self) -> Option<ModuleSpecifier> {
@@ -705,16 +707,8 @@ impl CliOptions {
.map(Some)
}
- fn get_npm_process_state(&self) -> Option<&NpmProcessState> {
- if !self.is_npm_main() {
- return None;
- }
-
- (*NPM_PROCESS_STATE).as_ref()
- }
-
pub fn get_npm_resolution_snapshot(&self) -> Option<NpmResolutionSnapshot> {
- if let Some(state) = self.get_npm_process_state() {
+ if let Some(state) = &*NPM_PROCESS_STATE {
// TODO(bartlomieju): remove this clone
return Some(state.snapshot.clone());
}
@@ -727,7 +721,7 @@ impl CliOptions {
// for functionality like child_process.fork. Users should NOT depend
// on this functionality.
pub fn is_npm_main(&self) -> bool {
- *IS_NPM_MAIN
+ NPM_PROCESS_STATE.is_some()
}
/// Overrides the import map specifier to use.
@@ -735,36 +729,19 @@ impl CliOptions {
self.overrides.import_map_specifier = Some(path);
}
- pub fn node_modules_dir(&self) -> bool {
- if let Some(node_modules_dir) = self.flags.node_modules_dir {
- return node_modules_dir;
- }
-
- if let Some(npm_process_state) = self.get_npm_process_state() {
- return npm_process_state.local_node_modules_path.is_some();
- }
+ pub fn has_node_modules_dir(&self) -> bool {
+ self.maybe_node_modules_folder.is_some()
+ }
- self.maybe_package_json.is_some()
+ pub fn node_modules_dir_path(&self) -> Option<PathBuf> {
+ self.maybe_node_modules_folder.clone()
}
- /// Resolves the path to use for a local node_modules folder.
- pub fn resolve_local_node_modules_folder(
- &self,
- ) -> Result<Option<PathBuf>, AnyError> {
- let path = if !self.node_modules_dir() {
- return Ok(None);
- } else if let Some(state) = self.get_npm_process_state() {
- return Ok(state.local_node_modules_path.as_ref().map(PathBuf::from));
- } else if let Some(config_path) = self
- .maybe_config_file
+ pub fn node_modules_dir_specifier(&self) -> Option<ModuleSpecifier> {
+ self
+ .maybe_node_modules_folder
.as_ref()
- .and_then(|c| c.specifier.to_file_path().ok())
- {
- config_path.parent().unwrap().join("node_modules")
- } else {
- std::env::current_dir()?.join("node_modules")
- };
- Ok(Some(canonicalize_path_maybe_not_exists(&path)?))
+ .map(|path| ModuleSpecifier::from_directory_path(path).unwrap())
}
pub fn resolve_root_cert_store(&self) -> Result<RootCertStore, AnyError> {
@@ -1081,6 +1058,33 @@ impl CliOptions {
}
}
+/// Resolves the path to use for a local node_modules folder.
+fn resolve_local_node_modules_folder(
+ cwd: &Path,
+ flags: &Flags,
+ maybe_config_file: Option<&ConfigFile>,
+ maybe_package_json: Option<&PackageJson>,
+) -> Result<Option<PathBuf>, AnyError> {
+ let path = if flags.node_modules_dir == Some(false) {
+ return Ok(None);
+ } else if let Some(state) = &*NPM_PROCESS_STATE {
+ return Ok(state.local_node_modules_path.as_ref().map(PathBuf::from));
+ } else if let Some(package_json_path) = maybe_package_json.map(|c| &c.path) {
+ // always auto-discover the local_node_modules_folder when a package.json exists
+ package_json_path.parent().unwrap().join("node_modules")
+ } else if flags.node_modules_dir.is_none() {
+ return Ok(None);
+ } else if let Some(config_path) = maybe_config_file
+ .as_ref()
+ .and_then(|c| c.specifier.to_file_path().ok())
+ {
+ config_path.parent().unwrap().join("node_modules")
+ } else {
+ cwd.join("node_modules")
+ };
+ Ok(Some(canonicalize_path_maybe_not_exists(&path)?))
+}
+
fn resolve_import_map_specifier(
maybe_import_map_path: Option<&str>,
maybe_config_file: Option<&ConfigFile>,