From 286ee1d8b68b54d39e698f3b78e3ce9e257fa674 Mon Sep 17 00:00:00 2001 From: "Kevin (Kun) \"Kassimo\" Qian" Date: Fri, 9 Aug 2019 16:33:59 -0700 Subject: [PATCH] Fix dynamic import base path problem for REPL and eval (#2757) --- cli/worker.rs | 8 ++++++-- core/module_specifier.rs | 17 ++++++++++++++++- tests/041_dyn_import_eval.out | 1 + tests/041_dyn_import_eval.test | 2 ++ tests/042_dyn_import_evalcontext.test | 2 ++ tests/042_dyn_import_evalcontext.ts | 4 ++++ tests/042_dyn_import_evalcontext.ts.out | 1 + tools/integration_tests.py | 1 + 8 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tests/041_dyn_import_eval.out create mode 100644 tests/041_dyn_import_eval.test create mode 100644 tests/042_dyn_import_evalcontext.test create mode 100644 tests/042_dyn_import_evalcontext.ts create mode 100644 tests/042_dyn_import_evalcontext.ts.out diff --git a/cli/worker.rs b/cli/worker.rs index db948cc3..f639c3d6 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -9,8 +9,10 @@ use deno::RecursiveLoad; use deno::StartupData; use futures::Async; use futures::Future; +use std::env; use std::sync::Arc; use std::sync::Mutex; +use url::Url; /// Wraps deno::Isolate to provide source maps, ops for the CLI, and /// high-level module loading @@ -55,9 +57,11 @@ impl Worker { Self { isolate, state } } - /// Same as execute2() but the filename defaults to "". + /// Same as execute2() but the filename defaults to "$CWD/__anonymous__". pub fn execute(&mut self, js_source: &str) -> Result<(), ErrBox> { - self.execute2("", js_source) + let path = env::current_dir().unwrap().join("__anonymous__"); + let url = Url::from_file_path(path).unwrap(); + self.execute2(url.as_str(), js_source) } /// Executes the provided JavaScript source code. The js_filename argument is diff --git a/core/module_specifier.rs b/core/module_specifier.rs index 3cfabd03..9194b908 100644 --- a/core/module_specifier.rs +++ b/core/module_specifier.rs @@ -46,6 +46,10 @@ impl fmt::Display for ModuleResolutionError { pub struct ModuleSpecifier(Url); impl ModuleSpecifier { + fn is_dummy_specifier(specifier: &str) -> bool { + specifier == "" + } + pub fn as_url(&self) -> &Url { &self.0 } @@ -80,7 +84,18 @@ impl ModuleSpecifier { // 3. Return the result of applying the URL parser to specifier with base // URL as the base URL. Err(ParseError::RelativeUrlWithoutBase) => { - let base = Url::parse(base).map_err(InvalidBaseUrl)?; + let base = if ModuleSpecifier::is_dummy_specifier(base) { + // Handle case, happening under e.g. repl. + // Use CWD for such case. + + // Forcefully join base to current dir. + // Otherwise, later joining in Url would be interpreted in + // the parent directory (appending trailing slash does not work) + let path = current_dir().unwrap().join(base); + Url::from_file_path(path).unwrap() + } else { + Url::parse(base).map_err(InvalidBaseUrl)? + }; base.join(&specifier).map_err(InvalidUrl)? } diff --git a/tests/041_dyn_import_eval.out b/tests/041_dyn_import_eval.out new file mode 100644 index 00000000..1dfef2e9 --- /dev/null +++ b/tests/041_dyn_import_eval.out @@ -0,0 +1 @@ +{ isMod4: true } diff --git a/tests/041_dyn_import_eval.test b/tests/041_dyn_import_eval.test new file mode 100644 index 00000000..b9baf522 --- /dev/null +++ b/tests/041_dyn_import_eval.test @@ -0,0 +1,2 @@ +args: eval import('./tests/subdir/mod4.js').then(console.log) +output: tests/041_dyn_import_eval.out diff --git a/tests/042_dyn_import_evalcontext.test b/tests/042_dyn_import_evalcontext.test new file mode 100644 index 00000000..cfe0df3f --- /dev/null +++ b/tests/042_dyn_import_evalcontext.test @@ -0,0 +1,2 @@ +args: run --reload tests/042_dyn_import_evalcontext.ts +output: tests/042_dyn_import_evalcontext.ts.out diff --git a/tests/042_dyn_import_evalcontext.ts b/tests/042_dyn_import_evalcontext.ts new file mode 100644 index 00000000..ef643ae4 --- /dev/null +++ b/tests/042_dyn_import_evalcontext.ts @@ -0,0 +1,4 @@ +// @ts-ignore +Deno.core.evalContext( + "(async () => console.log(await import('./tests/subdir/mod4.js')))()" +); diff --git a/tests/042_dyn_import_evalcontext.ts.out b/tests/042_dyn_import_evalcontext.ts.out new file mode 100644 index 00000000..1dfef2e9 --- /dev/null +++ b/tests/042_dyn_import_evalcontext.ts.out @@ -0,0 +1 @@ +{ isMod4: true } diff --git a/tools/integration_tests.py b/tools/integration_tests.py index 56f430d7..dd65feaf 100755 --- a/tools/integration_tests.py +++ b/tools/integration_tests.py @@ -60,6 +60,7 @@ class TestIntegrations(DenoTestCase): if not args: return + # TODO(kevinkassimo): better args parsing with quotation marks. args = args.split(" ") check_stderr = str2bool(test.get("check_stderr", "false")) stderr = subprocess.STDOUT if check_stderr else open(os.devnull, 'w') -- GitLab