From 83fe39701651058ae8c824621b7ef3849704fe07 Mon Sep 17 00:00:00 2001 From: andy finch Date: Fri, 28 Jun 2019 16:26:54 -0400 Subject: [PATCH 1/8] update rust version for ci (#2599) --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 3a5e9855a5e461..fbc0efe95c3988 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,7 +12,7 @@ environment: DENO_BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\target\release DENO_THIRD_PARTY_PATH: $(APPVEYOR_BUILD_FOLDER)\third_party RELEASE_ARTIFACT: deno_win_x64.zip - RUST_VERSION: 1.34.1 + RUST_VERSION: 1.35.0 RUST_DIR: $(USERPROFILE)\rust-$(RUST_VERSION) CARGO_HOME: $(RUST_DIR)\cargo RUSTUP_HOME: $(RUST_DIR)\rustup diff --git a/.travis.yml b/.travis.yml index 0109041d90aae4..b2fbc673761211 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ git: depth: 1 env: global: - - RUST_VERSION=1.34.1 + - RUST_VERSION=1.35.0 - CARGO_HOME=$TRAVIS_BUILD_DIR/third_party/rust_crates/ - RUSTUP_HOME=$HOME/.rustup/ - RUST_BACKTRACE=full From 1b48d67fbba55d64372052879d26bf8e2143d9c7 Mon Sep 17 00:00:00 2001 From: matzkoh <34151961+matzkoh@users.noreply.github.com> Date: Sat, 29 Jun 2019 07:49:03 +0900 Subject: [PATCH 2/8] docs(style_guide): fix typoFixes a small syntax error (#2567) --- website/style_guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/style_guide.md b/website/style_guide.md index 94a3cb4cc865eb..7655289224d6b2 100644 --- a/website/style_guide.md +++ b/website/style_guide.md @@ -174,9 +174,9 @@ limited to closures. Bad ```ts -export const foo(): string => { +export const foo = (): string => { return "bar"; -} +}; ``` Good From cde81c6a53bcb7e5e12a1f8d6003826544eff38e Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Sat, 29 Jun 2019 14:30:21 -0400 Subject: [PATCH 3/8] manual: adjust windows build instructions (#2601) --- website/manual.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/website/manual.md b/website/manual.md index 1ae44c763acf97..4e8f9fe16f9b25 100644 --- a/website/manual.md +++ b/website/manual.md @@ -129,19 +129,25 @@ deno run https://deno.land/welcome.ts ### Build from source -Clone on Unix/MacOs +Clone on Linux or Mac: ```bash -# Fetch deps. git clone --recurse-submodules https://github.com/denoland/deno.git ``` -Clone on Windows (with Admin privileges) +On Windows, a couple extra steps are required to clone because we use symlinks +in the repository. First +[enable "Developer Mode"](https://www.google.com/search?q=windows+enable+developer+mode) +(otherwise symlinks would require administrator privileges). Then you must set +`core.symlinks=true` before the checkout is started. ```bash -git clone -c core.symlinks=true --recurse-submodules https://github.com/denoland/deno.git +git config --global core.symlinks=true +git clone --recurse-submodules https://github.com/denoland/deno.git ``` +Now we can start the build: + ```bash cd deno ./tools/setup.py From 38cf346d5c0f69dfb0919781fb61db7a6597ded1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 30 Jun 2019 00:32:54 +0200 Subject: [PATCH 4/8] feat: parse flags after script name (#2596) --- cli/flags.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/cli/flags.rs b/cli/flags.rs index f7444f8d1f831d..5e15a1e75ba6e6 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -434,8 +434,11 @@ fn resolve_paths(paths: Vec) -> Vec { /// Parse ArgMatches into internal DenoFlags structure. /// This method should not make any side effects. -pub fn parse_flags(matches: &ArgMatches) -> DenoFlags { - let mut flags = DenoFlags::default(); +pub fn parse_flags( + matches: &ArgMatches, + maybe_flags: Option, +) -> DenoFlags { + let mut flags = maybe_flags.unwrap_or_default(); if matches.is_present("log-level") { flags.log_level = match matches.value_of("log-level").unwrap() { @@ -552,6 +555,56 @@ fn parse_run_args(mut flags: DenoFlags, matches: &ArgMatches) -> DenoFlags { flags } +/// Parse vector or arguments as DenoFlags. +/// +/// This is very specialized utility that parses arguments passed after script URL. +/// +/// Only dash (eg. `-r`) and double dash (eg. `--reload`) arguments are supported. +/// Arguments recognized as DenoFlags will be eaten. +/// Parsing stops after double dash `--` argument. +/// +/// NOTE: this method ignores `-h/--help` and `-v/--version` flags. +fn parse_script_args( + args: Vec, + mut flags: DenoFlags, +) -> (Vec, DenoFlags) { + let mut argv = vec![]; + let mut seen_double_dash = false; + + // we have to iterate and parse argument one by one because clap returns error on any + // unrecognized argument + for arg in args.iter() { + if seen_double_dash { + argv.push(arg.to_string()); + continue; + } + + if arg == "--" { + seen_double_dash = true; + argv.push(arg.to_string()); + continue; + } + + if !arg.starts_with('-') { + argv.push(arg.to_string()); + continue; + } + + let cli_app = create_cli_app(); + // `get_matches_from_safe` returns error for `-h/-v` flags + let matches = + cli_app.get_matches_from_safe(vec!["deno".to_string(), arg.to_string()]); + + if matches.is_ok() { + flags = parse_flags(&matches.unwrap(), Some(flags)); + } else { + argv.push(arg.to_string()); + } + } + + (argv, flags) +} + /// Used for `deno fmt ...` subcommand const PRETTIER_URL: &str = "https://deno.land/std@v0.7.0/prettier/main.ts"; /// Used for `deno install...` subcommand @@ -603,7 +656,7 @@ pub fn flags_from_vec( let cli_app = create_cli_app(); let matches = cli_app.get_matches_from(args); let mut argv: Vec = vec!["deno".to_string()]; - let mut flags = parse_flags(&matches.clone()); + let mut flags = parse_flags(&matches.clone(), None); let subcommand = match matches.subcommand() { ("bundle", Some(bundle_match)) => { @@ -711,6 +764,9 @@ pub fn flags_from_vec( .unwrap() .map(String::from) .collect(); + + let (script_args, flags_) = parse_script_args(script_args, flags); + flags = flags_; argv.extend(script_args); } DenoSubcommand::Run @@ -746,6 +802,9 @@ pub fn flags_from_vec( .unwrap() .map(String::from) .collect(); + + let (script_args, flags_) = parse_script_args(script_args, flags); + flags = flags_; argv.extend(script_args); } DenoSubcommand::Run @@ -933,7 +992,7 @@ mod tests { #[test] fn test_flags_from_vec_10() { - // notice that flags passed after script name will not + // notice that flags passed after double dash will not // be parsed to DenoFlags but instead forwarded to // script args as Deno.args let (flags, subcommand, argv) = flags_from_vec(svec![ @@ -941,6 +1000,7 @@ mod tests { "run", "--allow-write", "script.ts", + "--", "-D", "--allow-net" ]); @@ -952,7 +1012,7 @@ mod tests { } ); assert_eq!(subcommand, DenoSubcommand::Run); - assert_eq!(argv, svec!["deno", "script.ts", "-D", "--allow-net"]); + assert_eq!(argv, svec!["deno", "script.ts", "--", "-D", "--allow-net"]); } #[test] @@ -1436,4 +1496,43 @@ mod tests { assert_eq!(subcommand, DenoSubcommand::Completions); assert_eq!(argv, svec!["deno"]) } + + #[test] + fn test_flags_from_vec_33() { + let (flags, subcommand, argv) = + flags_from_vec(svec!["deno", "script.ts", "--allow-read", "--allow-net"]); + assert_eq!( + flags, + DenoFlags { + allow_net: true, + allow_read: true, + ..DenoFlags::default() + } + ); + assert_eq!(subcommand, DenoSubcommand::Run); + assert_eq!(argv, svec!["deno", "script.ts"]); + + let (flags, subcommand, argv) = flags_from_vec(svec![ + "deno", + "--allow-read", + "run", + "script.ts", + "--allow-net", + "-r", + "--help", + "--foo", + "bar" + ]); + assert_eq!( + flags, + DenoFlags { + allow_net: true, + allow_read: true, + reload: true, + ..DenoFlags::default() + } + ); + assert_eq!(subcommand, DenoSubcommand::Run); + assert_eq!(argv, svec!["deno", "script.ts", "--help", "--foo", "bar"]); + } } From 5a4bebb77080d8a72a3faa594a388c6bce46e346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 30 Jun 2019 00:35:56 +0200 Subject: [PATCH 5/8] fix: test output for completions (#2597) --- cli/flags.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/flags.rs b/cli/flags.rs index 5e15a1e75ba6e6..4d68ac726128da 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -8,6 +8,7 @@ use clap::SubCommand; use crate::deno_dir; use log::Level; use std; +use std::str; use std::str::FromStr; // Creates vector of strings, Vec @@ -671,11 +672,13 @@ pub fn flags_from_vec( } ("completions", Some(completions_match)) => { let shell: &str = completions_match.value_of("shell").unwrap(); + let mut buf: Vec = vec![]; create_cli_app().gen_completions_to( "deno", Shell::from_str(shell).unwrap(), - &mut std::io::stdout(), + &mut buf, ); + print!("{}", std::str::from_utf8(&buf).unwrap()); DenoSubcommand::Completions } ("eval", Some(eval_match)) => { From 1068b4848c4d6d9a444d2d2bca5f25d822c42ff5 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Sun, 30 Jun 2019 23:52:28 +0900 Subject: [PATCH 6/8] ts_library_builder: update README (#2604) --- tools/ts_library_builder/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ts_library_builder/README.md b/tools/ts_library_builder/README.md index 187d753e639678..c96fba16b01bb1 100644 --- a/tools/ts_library_builder/README.md +++ b/tools/ts_library_builder/README.md @@ -2,13 +2,13 @@ This tool allows us to produce a single TypeScript declaration file that describes the complete Deno runtime, including global variables and the built-in -`deno` module. The output of this tool, `lib.deno_runtime.d.ts`, serves several -purposes: +`Deno` global object. The output of this tool, `lib.deno_runtime.d.ts`, serves +several purposes: 1. It is passed to the TypeScript compiler `js/compiler.ts`, so that TypeScript knows what types to expect and can validate code against the runtime environment. -2. It is outputted to stdout by `deno --types`, so that users can easily have +2. It is outputted to stdout by `deno types`, so that users can easily have access to the complete declaration file. Editors can use this in the future to perform type checking. 3. Because JSDocs are maintained, this serves as a simple documentation page for From 9d18f97327e94ecf6fd0ae7b75a88abfeac07d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 30 Jun 2019 19:32:24 +0200 Subject: [PATCH 7/8] fix: normalize Deno.execPath (#2598) --- cli/ops.rs | 7 ++++++- tools/target_test.py | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cli/ops.rs b/cli/ops.rs index bf4016366059ac..0664d8077f2c1d 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -57,6 +57,7 @@ use tokio::net::TcpListener; use tokio::net::TcpStream; use tokio_process::CommandExt; use tokio_threadpool; +use url::Url; use utime; #[cfg(unix)] @@ -345,8 +346,12 @@ fn op_start( let cwd_off = builder.create_string(deno_fs::normalize_path(cwd_path.as_ref()).as_ref()); + let current_exe = std::env::current_exe().unwrap(); + // Now apply URL parser to current exe to get fully resolved path, otherwise we might get + // `./` and `../` bits in `exec_path` + let exe_url = Url::from_file_path(current_exe).unwrap(); let exec_path = - builder.create_string(std::env::current_exe().unwrap().to_str().unwrap()); + builder.create_string(exe_url.to_file_path().unwrap().to_str().unwrap()); let v8_version = version::v8(); let v8_version_off = builder.create_string(v8_version); diff --git a/tools/target_test.py b/tools/target_test.py index 98eb4a0eb8146a..58c5d43c762637 100644 --- a/tools/target_test.py +++ b/tools/target_test.py @@ -55,8 +55,11 @@ def test_no_color(self): assert result.out.strip() == "noColor false" def test_exec_path(self): - cmd = [self.deno_exe, "run", "tests/exec_path.ts"] + cmd = [self.deno_exe, "run", "--allow-run", "tests/exec_path.ts"] result = run_output(cmd, quiet=True) + print "exec_path", result.code + print result.out + print result.err assert self.deno_exe in result.out.strip() self.assertEqual(result.code, 0) From 32cde32e54a0c8c73b7bc3da9a3ade8d739cc0b5 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Sun, 30 Jun 2019 19:45:59 +0200 Subject: [PATCH 8/8] core: return useful error when import path has no prefix like ./ --- cli/deno_error.rs | 56 ++++++--- cli/msg.fbs | 1 + core/lib.rs | 2 +- core/module_specifier.rs | 109 ++++++++++++------ tests/error_011_bad_module_specifier.ts.out | 2 +- ...or_012_bad_dynamic_import_specifier.ts.out | 2 +- 6 files changed, 119 insertions(+), 53 deletions(-) diff --git a/cli/deno_error.rs b/cli/deno_error.rs index 6e14f39025c2c0..2e683c504e6ac8 100644 --- a/cli/deno_error.rs +++ b/cli/deno_error.rs @@ -7,6 +7,7 @@ use crate::resolve_addr::ResolveAddrError; use crate::source_maps::apply_source_map; use crate::source_maps::SourceMapGetter; use deno::JSError; +use deno::ModuleResolutionError; use hyper; #[cfg(unix)] use nix::{errno::Errno, Error as UnixError}; @@ -30,6 +31,7 @@ enum Repr { UrlErr(url::ParseError), HyperErr(hyper::Error), ImportMapErr(import_map::ImportMapError), + ModuleResolutionErr(ModuleResolutionError), Diagnostic(diagnostics::Diagnostic), JSError(JSError), } @@ -42,6 +44,24 @@ pub fn new(kind: ErrorKind, msg: String) -> DenoError { } impl DenoError { + fn url_error_kind(err: url::ParseError) -> ErrorKind { + use url::ParseError::*; + match err { + EmptyHost => ErrorKind::EmptyHost, + IdnaError => ErrorKind::IdnaError, + InvalidPort => ErrorKind::InvalidPort, + InvalidIpv4Address => ErrorKind::InvalidIpv4Address, + InvalidIpv6Address => ErrorKind::InvalidIpv6Address, + InvalidDomainCharacter => ErrorKind::InvalidDomainCharacter, + RelativeUrlWithoutBase => ErrorKind::RelativeUrlWithoutBase, + RelativeUrlWithCannotBeABaseBase => { + ErrorKind::RelativeUrlWithCannotBeABaseBase + } + SetHostOnCannotBeABaseUrl => ErrorKind::SetHostOnCannotBeABaseUrl, + Overflow => ErrorKind::Overflow, + } + } + pub fn kind(&self) -> ErrorKind { match self.repr { Repr::Simple(kind, ref _msg) => kind, @@ -70,23 +90,7 @@ impl DenoError { _ => unreachable!(), } } - Repr::UrlErr(ref err) => { - use url::ParseError::*; - match err { - EmptyHost => ErrorKind::EmptyHost, - IdnaError => ErrorKind::IdnaError, - InvalidPort => ErrorKind::InvalidPort, - InvalidIpv4Address => ErrorKind::InvalidIpv4Address, - InvalidIpv6Address => ErrorKind::InvalidIpv6Address, - InvalidDomainCharacter => ErrorKind::InvalidDomainCharacter, - RelativeUrlWithoutBase => ErrorKind::RelativeUrlWithoutBase, - RelativeUrlWithCannotBeABaseBase => { - ErrorKind::RelativeUrlWithCannotBeABaseBase - } - SetHostOnCannotBeABaseUrl => ErrorKind::SetHostOnCannotBeABaseUrl, - Overflow => ErrorKind::Overflow, - } - } + Repr::UrlErr(err) => Self::url_error_kind(err), Repr::HyperErr(ref err) => { // For some reason hyper::errors::Kind is private. if err.is_parse() { @@ -102,6 +106,13 @@ impl DenoError { } } Repr::ImportMapErr(ref _err) => ErrorKind::ImportMapError, + Repr::ModuleResolutionErr(err) => { + use ModuleResolutionError::*; + match err { + InvalidUrl(err) | InvalidBaseUrl(err) => Self::url_error_kind(err), + ImportPathPrefixMissing => ErrorKind::ImportPathPrefixMissing, + } + } Repr::Diagnostic(ref _err) => ErrorKind::Diagnostic, Repr::JSError(ref _err) => ErrorKind::JSError, } @@ -126,6 +137,7 @@ impl fmt::Display for DenoError { Repr::UrlErr(ref err) => err.fmt(f), Repr::HyperErr(ref err) => err.fmt(f), Repr::ImportMapErr(ref err) => f.pad(&err.msg), + Repr::ModuleResolutionErr(ref err) => err.fmt(f), Repr::Diagnostic(ref err) => err.fmt(f), Repr::JSError(ref err) => JSErrorColor(err).fmt(f), } @@ -140,6 +152,7 @@ impl std::error::Error for DenoError { Repr::UrlErr(ref err) => err.description(), Repr::HyperErr(ref err) => err.description(), Repr::ImportMapErr(ref err) => &err.msg, + Repr::ModuleResolutionErr(ref err) => err.description(), Repr::Diagnostic(ref err) => &err.items[0].message, Repr::JSError(ref err) => &err.description(), } @@ -152,6 +165,7 @@ impl std::error::Error for DenoError { Repr::UrlErr(ref err) => Some(err), Repr::HyperErr(ref err) => Some(err), Repr::ImportMapErr(ref _err) => None, + Repr::ModuleResolutionErr(ref err) => err.source(), Repr::Diagnostic(ref _err) => None, Repr::JSError(ref err) => Some(err), } @@ -241,6 +255,14 @@ impl From for DenoError { } } +impl From for DenoError { + fn from(err: ModuleResolutionError) -> Self { + Self { + repr: Repr::ModuleResolutionErr(err), + } + } +} + impl From for DenoError { fn from(diagnostic: diagnostics::Diagnostic) -> Self { Self { diff --git a/cli/msg.fbs b/cli/msg.fbs index ad9fb444ee9c46..da181af435d989 100644 --- a/cli/msg.fbs +++ b/cli/msg.fbs @@ -141,6 +141,7 @@ enum ErrorKind: byte { NoAsyncSupport, NoSyncSupport, ImportMapError, + ImportPathPrefixMissing, // other kinds Diagnostic, diff --git a/core/lib.rs b/core/lib.rs index 88c0fe1d1905f8..5bbe2fb8620bed 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -17,7 +17,7 @@ pub use crate::isolate::*; pub use crate::js_errors::*; pub use crate::libdeno::deno_mod; pub use crate::libdeno::PinnedBuf; -pub use crate::module_specifier::ModuleSpecifier; +pub use crate::module_specifier::*; pub use crate::modules::*; pub fn v8_version() -> &'static str { diff --git a/core/module_specifier.rs b/core/module_specifier.rs index 1bdd5beee2b4ea..8b8ccf4a675ee7 100644 --- a/core/module_specifier.rs +++ b/core/module_specifier.rs @@ -1,6 +1,40 @@ +use std::error::Error; use std::fmt; +use url::ParseError; use url::Url; +/// Error indicating the reason resolving a module specifier failed. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ModuleResolutionError { + InvalidUrl(ParseError), + InvalidBaseUrl(ParseError), + ImportPathPrefixMissing, +} +use ModuleResolutionError::*; + +impl Error for ModuleResolutionError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + InvalidUrl(ref err) | InvalidBaseUrl(ref err) => Some(err), + _ => None, + } + } +} + +impl fmt::Display for ModuleResolutionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + InvalidUrl(ref err) => write!(f, "invalid URL: {}", err), + InvalidBaseUrl(ref err) => { + write!(f, "invalid base URL for relative import: {}", err) + } + ImportPathPrefixMissing => { + write!(f, "relative import path not prefixed with / or ./ or ../") + } + } + } +} + #[derive(Debug, Clone, PartialEq)] /// Resolved module specifier pub struct ModuleSpecifier(Url); @@ -15,32 +49,39 @@ impl ModuleSpecifier { pub fn resolve( specifier: &str, base: &str, - ) -> Result { - // 1. Apply the URL parser to specifier. If the result is not failure, return - // the result. - // let specifier = parse_local_or_remote(specifier)?.to_string(); - if let Ok(url) = Url::parse(specifier) { - return Ok(ModuleSpecifier(url)); - } + ) -> Result { + let url = match Url::parse(specifier) { + // 1. Apply the URL parser to specifier. + // If the result is not failure, return he result. + Ok(url) => url, - // 2. If specifier does not start with the character U+002F SOLIDUS (/), the - // two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./), or the - // three-character sequence U+002E FULL STOP, U+002E FULL STOP, U+002F - // SOLIDUS (../), return failure. - if !specifier.starts_with('/') - && !specifier.starts_with("./") - && !specifier.starts_with("../") - { - // TODO This is (probably) not the correct error to return here. - // TODO: This error is very not-user-friendly - return Err(url::ParseError::RelativeUrlWithCannotBeABaseBase); - } + // 2. If specifier does not start with the character U+002F SOLIDUS (/), + // the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./), + // or the three-character sequence U+002E FULL STOP, U+002E FULL STOP, + // U+002F SOLIDUS (../), return failure. + Err(ParseError::RelativeUrlWithoutBase) + if !(specifier.starts_with('/') + || specifier.starts_with("./") + || specifier.starts_with("../")) => + { + Err(ImportPathPrefixMissing)? + } - // 3. Return the result of applying the URL parser to specifier with base URL - // as the base URL. - let base_url = Url::parse(base)?; - let u = base_url.join(&specifier)?; - Ok(ModuleSpecifier(u)) + // 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)?; + base.join(&specifier).map_err(InvalidUrl)? + } + + // If parsing the specifier as a URL failed for a different reason than + // it being relative, always return the original error. We don't want to + // return `ImportPathPrefixMissing` or `InvalidBaseUrl` if the real + // problem lies somewhere else. + Err(err) => Err(InvalidUrl(err))?, + }; + + Ok(ModuleSpecifier(url)) } /// Takes a string representing a path or URL to a module, but of the type @@ -51,15 +92,17 @@ impl ModuleSpecifier { /// directory and returns an absolute URL. pub fn resolve_root( root_specifier: &str, - ) -> Result { - if let Ok(url) = Url::parse(root_specifier) { - Ok(ModuleSpecifier(url)) - } else { - let cwd = std::env::current_dir().unwrap(); - let base = Url::from_directory_path(cwd).unwrap(); - let url = base.join(root_specifier)?; - Ok(ModuleSpecifier(url)) - } + ) -> Result { + let url = match Url::parse(root_specifier) { + Ok(url) => url, + Err(..) => { + let cwd = std::env::current_dir().unwrap(); + let base = Url::from_directory_path(cwd).unwrap(); + base.join(&root_specifier).map_err(InvalidUrl)? + } + }; + + Ok(ModuleSpecifier(url)) } } diff --git a/tests/error_011_bad_module_specifier.ts.out b/tests/error_011_bad_module_specifier.ts.out index 4225327653655e..d5a3efd7e2aefb 100644 --- a/tests/error_011_bad_module_specifier.ts.out +++ b/tests/error_011_bad_module_specifier.ts.out @@ -1,4 +1,4 @@ -[WILDCARD]error: Uncaught RelativeUrlWithCannotBeABaseBase: relative URL with a cannot-be-a-base base +[WILDCARD]error: Uncaught ImportPathPrefixMissing: relative import path not prefixed with / or ./ or ../ [WILDCARD] js/errors.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) at maybeError (js/errors.ts:[WILDCARD]) diff --git a/tests/error_012_bad_dynamic_import_specifier.ts.out b/tests/error_012_bad_dynamic_import_specifier.ts.out index 1337028b2141b8..1a20b60a1750bf 100644 --- a/tests/error_012_bad_dynamic_import_specifier.ts.out +++ b/tests/error_012_bad_dynamic_import_specifier.ts.out @@ -1,4 +1,4 @@ -[WILDCARD]error: Uncaught RelativeUrlWithCannotBeABaseBase: relative URL with a cannot-be-a-base base +[WILDCARD]error: Uncaught ImportPathPrefixMissing: relative import path not prefixed with / or ./ or ../ [WILDCARD] js/errors.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) at maybeError (js/errors.ts:[WILDCARD])