diff --git a/cli/args/config_file.rs b/cli/args/config_file.rs index b5ee8c50ae..6df06da5e2 100644 --- a/cli/args/config_file.rs +++ b/cli/args/config_file.rs @@ -506,7 +506,7 @@ impl ConfigFile { Ok(Some(ConfigFile::read(&config_path)?)) } ConfigFlag::Discover => { - if let Some(config_path_args) = flags.config_path_args() { + if let Some(config_path_args) = flags.config_path_args(cwd) { let mut checked = HashSet::new(); for f in config_path_args { if let Some(cf) = Self::discover_from(&f, &mut checked)? { diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 26cf497f6a..883a4d0342 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -6,6 +6,7 @@ use clap::ColorChoice; use clap::Command; use clap::ValueHint; use deno_core::error::AnyError; +use deno_core::resolve_url_or_path; use deno_core::url::Url; use deno_runtime::permissions::parse_sys_kind; use log::debug; @@ -16,6 +17,7 @@ use std::net::SocketAddr; use std::num::NonZeroU32; use std::num::NonZeroU8; use std::num::NonZeroUsize; +use std::path::Path; use std::path::PathBuf; use std::str::FromStr; @@ -474,16 +476,17 @@ impl Flags { /// Extract path arguments for config search paths. /// If it returns Some(vec), the config should be discovered - /// from the current dir after trying to discover from each entry in vec. + /// from the passed `current_dir` after trying to discover from each entry in + /// the returned vector. /// If it returns None, the config file shouldn't be discovered at all. - pub fn config_path_args(&self) -> Option> { + pub fn config_path_args(&self, current_dir: &Path) -> Option> { use DenoSubcommand::*; match &self.subcommand { Fmt(FmtFlags { files, .. }) => Some(files.include.clone()), Lint(LintFlags { files, .. }) => Some(files.include.clone()), Run(RunFlags { script }) => { - if let Ok(module_specifier) = deno_core::resolve_url_or_path(script) { + if let Ok(module_specifier) = resolve_url_or_path(script, current_dir) { if module_specifier.scheme() == "file" || module_specifier.scheme() == "npm" { @@ -520,12 +523,12 @@ impl Flags { /// from the `path` dir. /// If it returns None, the `package.json` file shouldn't be discovered at /// all. - pub fn package_json_search_dir(&self) -> Option { + pub fn package_json_search_dir(&self, current_dir: &Path) -> Option { use DenoSubcommand::*; match &self.subcommand { Run(RunFlags { script }) => { - let module_specifier = deno_core::resolve_url_or_path(script).ok()?; + let module_specifier = resolve_url_or_path(script, current_dir).ok()?; if module_specifier.scheme() == "file" { let p = module_specifier .to_file_path() @@ -540,7 +543,7 @@ impl Flags { } } Task(TaskFlags { cwd: Some(cwd), .. }) => { - deno_core::resolve_url_or_path(cwd) + resolve_url_or_path(cwd, current_dir) .ok()? .to_file_path() .ok() @@ -6338,30 +6341,28 @@ mod tests { #[test] fn test_config_path_args() { let flags = flags_from_vec(svec!["deno", "run", "foo.js"]).unwrap(); - assert_eq!( - flags.config_path_args(), - Some(vec![std::env::current_dir().unwrap().join("foo.js")]) - ); + let cwd = std::env::current_dir().unwrap(); + assert_eq!(flags.config_path_args(&cwd), Some(vec![cwd.join("foo.js")])); let flags = flags_from_vec(svec!["deno", "run", "https://example.com/foo.js"]) .unwrap(); - assert_eq!(flags.config_path_args(), None); + assert_eq!(flags.config_path_args(&cwd), None); let flags = flags_from_vec(svec!["deno", "lint", "dir/a.js", "dir/b.js"]).unwrap(); assert_eq!( - flags.config_path_args(), + flags.config_path_args(&cwd), Some(vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]) ); let flags = flags_from_vec(svec!["deno", "lint"]).unwrap(); - assert!(flags.config_path_args().unwrap().is_empty()); + assert!(flags.config_path_args(&cwd).unwrap().is_empty()); let flags = flags_from_vec(svec!["deno", "fmt", "dir/a.js", "dir/b.js"]).unwrap(); assert_eq!( - flags.config_path_args(), + flags.config_path_args(&cwd), Some(vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]) ); } diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 5be5fc7ab3..25a1514f39 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -385,11 +385,12 @@ fn resolve_lint_rules_options( fn discover_package_json( flags: &Flags, maybe_stop_at: Option, + current_dir: &Path, ) -> Result, AnyError> { // TODO(bartlomieju): discover for all subcommands, but print warnings that // `package.json` is ignored in bundle/compile/etc. - if let Some(package_json_dir) = flags.package_json_search_dir() { + if let Some(package_json_dir) = flags.package_json_search_dir(current_dir) { let package_json_dir = canonicalize_path_maybe_not_exists(&package_json_dir)?; return package_json::discover_from(&package_json_dir, maybe_stop_at); @@ -509,6 +510,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, + initial_cwd: PathBuf, maybe_node_modules_folder: Option, maybe_config_file: Option, maybe_package_json: Option, @@ -549,6 +551,7 @@ impl CliOptions { Ok(Self { flags, + initial_cwd, maybe_config_file, maybe_lockfile, maybe_package_json, @@ -577,10 +580,11 @@ impl CliOptions { .parent() .map(|p| p.to_path_buf()); - maybe_package_json = discover_package_json(&flags, maybe_stop_at)?; + maybe_package_json = + discover_package_json(&flags, maybe_stop_at, &initial_cwd)?; } } else { - maybe_package_json = discover_package_json(&flags, None)?; + maybe_package_json = discover_package_json(&flags, None, &initial_cwd)?; } let maybe_lock_file = @@ -594,6 +598,11 @@ impl CliOptions { ) } + #[inline(always)] + pub fn initial_cwd(&self) -> &Path { + &self.initial_cwd + } + pub fn maybe_config_file_specifier(&self) -> Option { self.maybe_config_file.as_ref().map(|f| f.specifier.clone()) } @@ -641,6 +650,7 @@ impl CliOptions { None => resolve_import_map_specifier( self.flags.import_map_path.as_deref(), self.maybe_config_file.as_ref(), + &self.initial_cwd, ), } } @@ -1071,6 +1081,7 @@ fn resolve_local_node_modules_folder( fn resolve_import_map_specifier( maybe_import_map_path: Option<&str>, maybe_config_file: Option<&ConfigFile>, + current_dir: &Path, ) -> Result, AnyError> { if let Some(import_map_path) = maybe_import_map_path { if let Some(config_file) = &maybe_config_file { @@ -1078,8 +1089,9 @@ fn resolve_import_map_specifier( log::warn!("{} the configuration file \"{}\" contains an entry for \"importMap\" that is being ignored.", colors::yellow("Warning"), config_file.specifier); } } - let specifier = deno_core::resolve_url_or_path(import_map_path) - .context(format!("Bad URL (\"{import_map_path}\") for import map."))?; + let specifier = + deno_core::resolve_url_or_path(import_map_path, current_dir) + .context(format!("Bad URL (\"{import_map_path}\") for import map."))?; return Ok(Some(specifier)); } else if let Some(config_file) = &maybe_config_file { // if the config file is an import map we prefer to use it, over `importMap` @@ -1171,7 +1183,11 @@ mod test { let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = resolve_import_map_specifier(None, Some(&config_file)); + let actual = resolve_import_map_specifier( + None, + Some(&config_file), + &PathBuf::from("/"), + ); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!( @@ -1188,7 +1204,11 @@ mod test { let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = resolve_import_map_specifier(None, Some(&config_file)); + let actual = resolve_import_map_specifier( + None, + Some(&config_file), + &PathBuf::from("/"), + ); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!( @@ -1207,7 +1227,11 @@ mod test { let config_specifier = ModuleSpecifier::parse("https://example.com/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = resolve_import_map_specifier(None, Some(&config_file)); + let actual = resolve_import_map_specifier( + None, + Some(&config_file), + &PathBuf::from("/"), + ); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!( @@ -1223,13 +1247,16 @@ mod test { let config_text = r#"{ "importMap": "import_map.json" }"#; + let cwd = &PathBuf::from("/"); let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = - resolve_import_map_specifier(Some("import-map.json"), Some(&config_file)); - let import_map_path = - std::env::current_dir().unwrap().join("import-map.json"); + let actual = resolve_import_map_specifier( + Some("import-map.json"), + Some(&config_file), + cwd, + ); + let import_map_path = cwd.join("import-map.json"); let expected_specifier = ModuleSpecifier::from_file_path(import_map_path).unwrap(); assert!(actual.is_ok()); @@ -1246,7 +1273,11 @@ mod test { let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = resolve_import_map_specifier(None, Some(&config_file)); + let actual = resolve_import_map_specifier( + None, + Some(&config_file), + &PathBuf::from("/"), + ); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!(actual, Some(config_specifier)); @@ -1258,7 +1289,11 @@ mod test { let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); let config_file = ConfigFile::new(config_text, &config_specifier).unwrap(); - let actual = resolve_import_map_specifier(None, Some(&config_file)); + let actual = resolve_import_map_specifier( + None, + Some(&config_file), + &PathBuf::from("/"), + ); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!(actual, None); @@ -1266,7 +1301,7 @@ mod test { #[test] fn resolve_import_map_no_config() { - let actual = resolve_import_map_specifier(None, None); + let actual = resolve_import_map_specifier(None, None, &PathBuf::from("/")); assert!(actual.is_ok()); let actual = actual.unwrap(); assert_eq!(actual, None); diff --git a/cli/proc_state.rs b/cli/proc_state.rs index eb43e75d73..4d8acf5249 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -459,7 +459,7 @@ impl ProcState { let specifiers = files .iter() - .map(|file| resolve_url_or_path(file)) + .map(|file| resolve_url_or_path(file, self.options.initial_cwd())) .collect::, _>>()?; self .prepare_module_load( @@ -495,7 +495,7 @@ impl ProcState { referrer: &str, permissions: &mut PermissionsContainer, ) -> Result { - if let Ok(referrer) = deno_core::resolve_url_or_path(referrer) { + if let Ok(referrer) = deno_core::resolve_url_or_path_deprecated(referrer) { if self.npm_resolver.in_npm_package(&referrer) { // we're in an npm package, so use node resolution return self @@ -565,10 +565,9 @@ impl ProcState { // but sadly that's not the case due to missing APIs in V8. let is_repl = matches!(self.options.sub_command(), DenoSubcommand::Repl(_)); let referrer = if referrer.is_empty() && is_repl { - let cwd = std::env::current_dir().context("Unable to get CWD")?; - deno_core::resolve_path("./$deno$repl.ts", &cwd)? + deno_core::resolve_path("./$deno$repl.ts", self.options.initial_cwd())? } else { - deno_core::resolve_url_or_path(referrer)? + deno_core::resolve_url_or_path_deprecated(referrer)? }; // FIXME(bartlomieju): this is another hack way to provide NPM specifier diff --git a/cli/standalone.rs b/cli/standalone.rs index ecf2959247..7e0658165a 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -140,9 +140,9 @@ impl ModuleLoader for EmbeddedModuleLoader { // Try to follow redirects when resolving. let referrer = match self.eszip.get_module(referrer) { Some(eszip::Module { ref specifier, .. }) => { - deno_core::resolve_url_or_path(specifier)? + deno_core::resolve_url_or_path_deprecated(specifier)? } - None => deno_core::resolve_url_or_path(referrer)?, + None => deno_core::resolve_url_or_path_deprecated(referrer)?, }; self.maybe_import_map_resolver.as_ref().map_or_else( diff --git a/cli/tests/unit/process_test.ts b/cli/tests/unit/process_test.ts index e79365a6df..1799a01905 100644 --- a/cli/tests/unit/process_test.ts +++ b/cli/tests/unit/process_test.ts @@ -658,6 +658,6 @@ Deno.test( p.close(); p.stdout.close(); assertStrictEquals(code, 1); - assertStringIncludes(stderr, "Unable to get CWD"); + assertStringIncludes(stderr, "No such file or directory"); }, ); diff --git a/cli/tools/bench.rs b/cli/tools/bench.rs index 578b72adfb..70fc34ca1f 100644 --- a/cli/tools/bench.rs +++ b/cli/tools/bench.rs @@ -692,7 +692,8 @@ pub async fn run_benchmarks_with_watch( if let Some(changed) = &changed { for path in changed.iter().filter_map(|path| { - deno_core::resolve_url_or_path(&path.to_string_lossy()).ok() + deno_core::resolve_url_or_path_deprecated(&path.to_string_lossy()) + .ok() }) { if modules.contains(&path) { modules_to_reload.push(specifier); diff --git a/cli/tools/bundle.rs b/cli/tools/bundle.rs index d75da5ec76..c1d4befb12 100644 --- a/cli/tools/bundle.rs +++ b/cli/tools/bundle.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use deno_core::error::AnyError; use deno_core::futures::FutureExt; -use deno_core::resolve_url_or_path; +use deno_core::resolve_url_or_path_deprecated; use deno_graph::Module; use deno_runtime::colors; @@ -40,7 +40,7 @@ pub async fn bundle( let source_file1 = &bundle_flags.source_file; let source_file2 = &bundle_flags.source_file; async move { - let module_specifier = resolve_url_or_path(source_file1)?; + let module_specifier = resolve_url_or_path_deprecated(source_file1)?; log::debug!(">>>>> bundle START"); let ps = ProcState::from_options(cli_options).await?; diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs index c7a4d58da7..05ad853f86 100644 --- a/cli/tools/coverage/mod.rs +++ b/cli/tools/coverage/mod.rs @@ -655,8 +655,10 @@ pub async fn cover_files( }; for script_coverage in script_coverages { - let module_specifier = - deno_core::resolve_url_or_path(&script_coverage.url)?; + let module_specifier = deno_core::resolve_url_or_path( + &script_coverage.url, + ps.options.initial_cwd(), + )?; let maybe_file = if module_specifier.scheme() == "file" { ps.file_fetcher.get_source(&module_specifier) diff --git a/cli/tools/doc.rs b/cli/tools/doc.rs index 2ee80f6b7f..38553e9ffa 100644 --- a/cli/tools/doc.rs +++ b/cli/tools/doc.rs @@ -12,7 +12,6 @@ use crate::proc_state::ProcState; use crate::tsc::get_types_declaration_file_text; use deno_ast::MediaType; use deno_core::anyhow::bail; -use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::resolve_path; use deno_core::resolve_url_or_path; @@ -62,12 +61,13 @@ pub async fn print_docs( doc_parser.parse_module(&source_file_specifier)?.definitions } DocSourceFileFlag::Path(source_file) => { - let cwd = std::env::current_dir().context("Unable to get CWD")?; - let module_specifier = resolve_url_or_path(&source_file)?; + let module_specifier = + resolve_url_or_path(&source_file, ps.options.initial_cwd())?; // If the root module has external types, the module graph won't redirect it, // so instead create a dummy file which exports everything from the actual file being documented. - let root_specifier = resolve_path("./$deno$doc.ts", &cwd).unwrap(); + let root_specifier = + resolve_path("./$deno$doc.ts", ps.options.initial_cwd()).unwrap(); let root = File { local: PathBuf::from("./$deno$doc.ts"), maybe_types: None, diff --git a/cli/tools/info.rs b/cli/tools/info.rs index f7284154a8..1cc60286d3 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -34,7 +34,7 @@ use crate::util::checksum; pub async fn info(flags: Flags, info_flags: InfoFlags) -> Result<(), AnyError> { let ps = ProcState::build(flags).await?; if let Some(specifier) = info_flags.file { - let specifier = resolve_url_or_path(&specifier)?; + let specifier = resolve_url_or_path(&specifier, ps.options.initial_cwd())?; let mut loader = ps.create_graph_loader(); loader.enable_loading_cache_info(); // for displaying the cache information let graph = ps diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index a43ec84d54..86291b2c9a 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -308,7 +308,8 @@ async fn resolve_shim_data( let installation_dir = root.join("bin"); // Check if module_url is remote - let module_url = resolve_url_or_path(&install_flags.module_url)?; + let cwd = std::env::current_dir().context("Unable to get CWD")?; + let module_url = resolve_url_or_path(&install_flags.module_url, &cwd)?; let name = if install_flags.name.is_some() { install_flags.name.clone() @@ -408,7 +409,7 @@ async fn resolve_shim_data( } if let Some(import_map_path) = &flags.import_map_path { - let import_map_url = resolve_url_or_path(import_map_path)?; + let import_map_url = resolve_url_or_path(import_map_path, &cwd)?; executable_args.push("--import-map".to_string()); executable_args.push(import_map_url.to_string()); } diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index 99dab62614..7224eb45f7 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -5,7 +5,6 @@ use crate::args::ReplFlags; use crate::colors; use crate::proc_state::ProcState; use crate::worker::create_main_worker; -use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::resolve_path; use deno_runtime::permissions::Permissions; @@ -70,7 +69,8 @@ async fn read_eval_file( ps: &ProcState, eval_file: &str, ) -> Result { - let specifier = deno_core::resolve_url_or_path(eval_file)?; + let specifier = + deno_core::resolve_url_or_path(eval_file, ps.options.initial_cwd())?; let file = ps .file_fetcher @@ -81,9 +81,9 @@ async fn read_eval_file( } pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result { - let cwd = std::env::current_dir().context("Unable to get CWD")?; - let main_module = resolve_path("./$deno$repl.ts", &cwd).unwrap(); let ps = ProcState::build(flags).await?; + let main_module = + resolve_path("./$deno$repl.ts", ps.options.initial_cwd()).unwrap(); let mut worker = create_main_worker( &ps, main_module, diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index 1cd67fc97d..3cd9730a7f 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -11,7 +11,6 @@ use deno_ast::swc::visit::VisitWith; use deno_ast::DiagnosticsError; use deno_ast::ImportsNotUsedAsValues; use deno_ast::ModuleSpecifier; -use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::futures::channel::mpsc::UnboundedReceiver; use deno_core::futures::FutureExt; @@ -144,8 +143,11 @@ impl ReplSession { } assert_ne!(context_id, 0); - let cwd = std::env::current_dir().context("Unable to get CWD")?; - let referrer = deno_core::resolve_path("./$deno$repl.ts", &cwd).unwrap(); + let referrer = deno_core::resolve_path( + "./$deno$repl.ts", + proc_state.options.initial_cwd(), + ) + .unwrap(); let mut repl_session = ReplSession { proc_state, diff --git a/cli/tools/run.rs b/cli/tools/run.rs index d949a1cdb2..04ddcb4d99 100644 --- a/cli/tools/run.rs +++ b/cli/tools/run.rs @@ -9,6 +9,7 @@ use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::resolve_path; use deno_core::resolve_url_or_path; +use deno_core::resolve_url_or_path_deprecated; use deno_graph::npm::NpmPackageReqReference; use deno_runtime::permissions::Permissions; use deno_runtime::permissions::PermissionsContainer; @@ -56,7 +57,7 @@ To grant permissions, set them before the script argument. For example: if NpmPackageReqReference::from_str(&run_flags.script).is_ok() { ModuleSpecifier::parse(&run_flags.script)? } else { - resolve_url_or_path(&run_flags.script)? + resolve_url_or_path(&run_flags.script, ps.options.initial_cwd())? }; let permissions = PermissionsContainer::new(Permissions::from_options( &ps.options.permissions_options(), @@ -103,7 +104,7 @@ pub async fn run_from_stdin(flags: Flags) -> Result { // code properly. async fn run_with_watch(flags: Flags, script: String) -> Result { let flags = Arc::new(flags); - let main_module = resolve_url_or_path(&script)?; + let main_module = resolve_url_or_path_deprecated(&script)?; let (sender, receiver) = tokio::sync::mpsc::unbounded_channel(); let mut ps = ProcState::build_for_file_watcher((*flags).clone(), sender.clone()).await?; @@ -142,10 +143,11 @@ pub async fn eval_command( ) -> Result { // deno_graph works off of extensions for local files to determine the media // type, and so our "fake" specifier needs to have the proper extension. - let cwd = std::env::current_dir().context("Unable to get CWD")?; - let main_module = - resolve_path(&format!("./$deno$eval.{}", eval_flags.ext), &cwd)?; let ps = ProcState::build(flags).await?; + let main_module = resolve_path( + &format!("./$deno$eval.{}", eval_flags.ext), + ps.options.initial_cwd(), + )?; let permissions = PermissionsContainer::new(Permissions::from_options( &ps.options.permissions_options(), )?); diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs index 4573717a37..f0f53d417e 100644 --- a/cli/tools/standalone.rs +++ b/cli/tools/standalone.rs @@ -39,11 +39,15 @@ pub async fn compile( compile_flags: CompileFlags, ) -> Result<(), AnyError> { let ps = ProcState::build(flags).await?; - let module_specifier = resolve_url_or_path(&compile_flags.source_file)?; + let module_specifier = + resolve_url_or_path(&compile_flags.source_file, ps.options.initial_cwd())?; let deno_dir = &ps.dir; - let output_path = - resolve_compile_executable_output_path(&compile_flags).await?; + let output_path = resolve_compile_executable_output_path( + &compile_flags, + ps.options.initial_cwd(), + ) + .await?; let graph = Arc::try_unwrap( create_graph_and_maybe_check(module_specifier.clone(), &ps).await?, @@ -282,8 +286,10 @@ async fn write_standalone_binary( async fn resolve_compile_executable_output_path( compile_flags: &CompileFlags, + current_dir: &Path, ) -> Result { - let module_specifier = resolve_url_or_path(&compile_flags.source_file)?; + let module_specifier = + resolve_url_or_path(&compile_flags.source_file, current_dir)?; let mut output = compile_flags.output.clone(); @@ -339,12 +345,15 @@ mod test { #[tokio::test] async fn resolve_compile_executable_output_path_target_linux() { - let path = resolve_compile_executable_output_path(&CompileFlags { - source_file: "mod.ts".to_string(), - output: Some(PathBuf::from("./file")), - args: Vec::new(), - target: Some("x86_64-unknown-linux-gnu".to_string()), - }) + let path = resolve_compile_executable_output_path( + &CompileFlags { + source_file: "mod.ts".to_string(), + output: Some(PathBuf::from("./file")), + args: Vec::new(), + target: Some("x86_64-unknown-linux-gnu".to_string()), + }, + &std::env::current_dir().unwrap(), + ) .await .unwrap(); @@ -356,12 +365,15 @@ mod test { #[tokio::test] async fn resolve_compile_executable_output_path_target_windows() { - let path = resolve_compile_executable_output_path(&CompileFlags { - source_file: "mod.ts".to_string(), - output: Some(PathBuf::from("./file")), - args: Vec::new(), - target: Some("x86_64-pc-windows-msvc".to_string()), - }) + let path = resolve_compile_executable_output_path( + &CompileFlags { + source_file: "mod.ts".to_string(), + output: Some(PathBuf::from("./file")), + args: Vec::new(), + target: Some("x86_64-pc-windows-msvc".to_string()), + }, + &std::env::current_dir().unwrap(), + ) .await .unwrap(); assert_eq!(path.file_name().unwrap(), "file.exe"); diff --git a/cli/tools/test.rs b/cli/tools/test.rs index 1feb83ca31..12f5d7c1f9 100644 --- a/cli/tools/test.rs +++ b/cli/tools/test.rs @@ -799,7 +799,7 @@ fn extract_files_from_regex_blocks( writeln!(file_source, "{}", text.as_str()).unwrap(); } - let file_specifier = deno_core::resolve_url_or_path(&format!( + let file_specifier = deno_core::resolve_url_or_path_deprecated(&format!( "{}${}-{}{}", specifier, file_line_index + line_offset + 1, @@ -1428,7 +1428,8 @@ pub async fn run_tests_with_watch( if let Some(changed) = &changed { for path in changed.iter().filter_map(|path| { - deno_core::resolve_url_or_path(&path.to_string_lossy()).ok() + deno_core::resolve_url_or_path_deprecated(&path.to_string_lossy()) + .ok() }) { if modules.contains(&path) { modules_to_reload.push(specifier); diff --git a/cli/tools/vendor/mod.rs b/cli/tools/vendor/mod.rs index e3536a00d7..3198348e37 100644 --- a/cli/tools/vendor/mod.rs +++ b/cli/tools/vendor/mod.rs @@ -268,7 +268,7 @@ async fn create_graph( let entry_points = flags .specifiers .iter() - .map(|p| resolve_url_or_path(p)) + .map(|p| resolve_url_or_path(p, ps.options.initial_cwd())) .collect::, _>>()?; ps.create_graph(entry_points).await diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 6add7d1fda..010d65a416 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -13,7 +13,7 @@ use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::located_script_name; use deno_core::op; -use deno_core::resolve_url_or_path; +use deno_core::resolve_url_or_path_deprecated; use deno_core::serde::Deserialize; use deno_core::serde::Deserializer; use deno_core::serde::Serialize; @@ -402,7 +402,7 @@ impl State { } fn normalize_specifier(specifier: &str) -> Result { - resolve_url_or_path(specifier).map_err(|err| err.into()) + resolve_url_or_path_deprecated(specifier).map_err(|err| err.into()) } #[derive(Debug, Deserialize)] diff --git a/cli/worker.rs b/cli/worker.rs index 151f70f053..3643a43162 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -729,7 +729,6 @@ fn create_web_worker_callback( mod tests { use super::*; use deno_core::resolve_path; - use deno_core::resolve_url_or_path; use deno_core::FsModuleLoader; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; use deno_runtime::deno_web::BlobStore; @@ -787,7 +786,7 @@ mod tests { #[tokio::test] async fn execute_mod_esm_imports_a() { let p = test_util::testdata_path().join("runtime/esm_imports_a.js"); - let module_specifier = resolve_url_or_path(&p.to_string_lossy()).unwrap(); + let module_specifier = ModuleSpecifier::from_file_path(&p).unwrap(); let mut worker = create_test_worker(); let result = worker.execute_main_module(&module_specifier).await; if let Err(err) = result { diff --git a/core/lib.rs b/core/lib.rs index 08df6e44dc..b48a77f693 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -72,6 +72,7 @@ pub use crate::module_specifier::resolve_import; pub use crate::module_specifier::resolve_path; pub use crate::module_specifier::resolve_url; pub use crate::module_specifier::resolve_url_or_path; +pub use crate::module_specifier::resolve_url_or_path_deprecated; pub use crate::module_specifier::ModuleResolutionError; pub use crate::module_specifier::ModuleSpecifier; pub use crate::module_specifier::DUMMY_SPECIFIER; diff --git a/core/module_specifier.rs b/core/module_specifier.rs index 72d6937230..6c6dbad952 100644 --- a/core/module_specifier.rs +++ b/core/module_specifier.rs @@ -123,7 +123,7 @@ pub fn resolve_url( /// e.g. 'http:' or 'file:' or 'git+ssh:'. If not, it's interpreted as a /// file path; if it is a relative path it's resolved relative to the current /// working directory. -pub fn resolve_url_or_path( +pub fn resolve_url_or_path_deprecated( specifier: &str, ) -> Result { if specifier_has_uri_scheme(specifier) { @@ -135,9 +135,26 @@ pub fn resolve_url_or_path( } } +/// Takes a string representing either an absolute URL or a file path, +/// as it may be passed to deno as a command line argument. +/// The string is interpreted as a URL if it starts with a valid URI scheme, +/// e.g. 'http:' or 'file:' or 'git+ssh:'. If not, it's interpreted as a +/// file path; if it is a relative path it's resolved relative to passed +/// `current_dir`. +pub fn resolve_url_or_path( + specifier: &str, + current_dir: &Path, +) -> Result { + if specifier_has_uri_scheme(specifier) { + resolve_url(specifier) + } else { + resolve_path(specifier, current_dir) + } +} + /// Converts a string representing a relative or absolute path into a -/// ModuleSpecifier. A relative path is considered relative to the current -/// working directory. +/// ModuleSpecifier. A relative path is considered relative to the passed +/// `current_dir`. pub fn resolve_path( path_str: &str, current_dir: &Path, @@ -344,7 +361,7 @@ mod tests { } #[test] - fn test_resolve_url_or_path() { + fn test_resolve_url_or_path_deprecated() { // Absolute URL. let mut tests: Vec<(&str, String)> = vec![ ( @@ -440,13 +457,15 @@ mod tests { } for (specifier, expected_url) in tests { - let url = resolve_url_or_path(specifier).unwrap().to_string(); + let url = resolve_url_or_path_deprecated(specifier) + .unwrap() + .to_string(); assert_eq!(url, expected_url); } } #[test] - fn test_resolve_url_or_path_error() { + fn test_resolve_url_or_path_deprecated_error() { use url::ParseError::*; use ModuleResolutionError::*; @@ -460,7 +479,7 @@ mod tests { } for (specifier, expected_err) in tests { - let err = resolve_url_or_path(specifier).unwrap_err(); + let err = resolve_url_or_path_deprecated(specifier).unwrap_err(); assert_eq!(err, expected_err); } } diff --git a/core/ops_builtin_v8.rs b/core/ops_builtin_v8.rs index c3c4ec092f..e00ed5a297 100644 --- a/core/ops_builtin_v8.rs +++ b/core/ops_builtin_v8.rs @@ -6,7 +6,7 @@ use crate::error::range_error; use crate::error::type_error; use crate::error::JsError; use crate::ops_builtin::WasmStreamingResource; -use crate::resolve_url_or_path; +use crate::resolve_url_or_path_deprecated; use crate::serde_v8::from_v8; use crate::source_map::apply_source_map as apply_source_map_; use crate::JsRealm; @@ -165,7 +165,7 @@ fn op_eval_context<'a>( let source = v8::Local::::try_from(source.v8_value) .map_err(|_| type_error("Invalid source"))?; let specifier = match specifier { - Some(s) => resolve_url_or_path(&s)?.to_string(), + Some(s) => resolve_url_or_path_deprecated(&s)?.to_string(), None => crate::DUMMY_SPECIFIER.to_string(), }; let specifier = v8::String::new(tc_scope, &specifier).unwrap();