From fede13f2eb64f648e6c39aa01e2e0ede4e5be25e Mon Sep 17 00:00:00 2001 From: Valentin Anger Date: Mon, 12 Oct 2020 01:05:46 +0200 Subject: [PATCH] feat(cli): support importmap flag with deno doc subcommand (#7821) Fixes #7783 --- cli/flags.rs | 25 +++++++++ cli/main.rs | 93 ++++++++++++++++++++------------- cli/tests/doc/importmap.json | 5 ++ cli/tests/doc/module/fun.js | 2 + cli/tests/doc/use_importmap.js | 1 + cli/tests/doc/use_importmap.out | 5 ++ cli/tests/integration_tests.rs | 5 ++ 7 files changed, 101 insertions(+), 35 deletions(-) create mode 100644 cli/tests/doc/importmap.json create mode 100644 cli/tests/doc/module/fun.js create mode 100644 cli/tests/doc/use_importmap.js create mode 100644 cli/tests/doc/use_importmap.out diff --git a/cli/flags.rs b/cli/flags.rs index 06fbafdc3d..12d4e9bc6c 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -634,6 +634,7 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) { } fn doc_parse(flags: &mut Flags, matches: &clap::ArgMatches) { + importmap_arg_parse(flags, matches); reload_arg_parse(flags, matches); let source_file = matches.value_of("source_file").map(String::from); @@ -978,6 +979,7 @@ Show documentation for runtime built-ins: deno doc deno doc --builtin Deno.Listener", ) + .arg(importmap_arg()) .arg(reload_arg()) .arg( Arg::with_name("json") @@ -2420,6 +2422,29 @@ mod tests { ); } + #[test] + fn doc_importmap() { + let r = flags_from_vec_safe(svec![ + "deno", + "doc", + "--importmap=importmap.json", + "script.ts" + ]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Doc { + source_file: Some("script.ts".to_owned()), + private: false, + json: false, + filter: None, + }, + import_map_path: Some("importmap.json".to_owned()), + ..Flags::default() + } + ); + } + #[test] fn cache_multiple() { let r = diff --git a/cli/main.rs b/cli/main.rs index b6b92d7ba9..7a370d555c 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -78,6 +78,7 @@ use deno_doc::parser::DocFileLoader; use flags::DenoSubcommand; use flags::Flags; use global_state::exit_unstable; +use import_map::ImportMap; use log::Level; use log::LevelFilter; use std::env; @@ -319,6 +320,59 @@ async fn bundle_command( Ok(()) } +struct DocLoader { + fetcher: SourceFileFetcher, + maybe_import_map: Option, +} + +impl DocFileLoader for DocLoader { + fn resolve( + &self, + specifier: &str, + referrer: &str, + ) -> Result { + let maybe_resolved = + if let Some(import_map) = self.maybe_import_map.as_ref() { + import_map + .resolve(specifier, referrer) + .map_err(|e| doc::DocError::Resolve(e.to_string()))? + } else { + None + }; + + let resolved_specifier = if let Some(resolved) = maybe_resolved { + resolved + } else { + ModuleSpecifier::resolve_import(specifier, referrer) + .map_err(|e| doc::DocError::Resolve(e.to_string()))? + }; + + Ok(resolved_specifier.to_string()) + } + + fn load_source_code( + &self, + specifier: &str, + ) -> Pin>>> { + let fetcher = self.fetcher.clone(); + let specifier = ModuleSpecifier::resolve_url_or_path(specifier) + .expect("Expected valid specifier"); + async move { + let source_file = fetcher + .fetch_source_file(&specifier, None, Permissions::allow_all()) + .await + .map_err(|e| { + doc::DocError::Io(std::io::Error::new( + std::io::ErrorKind::Other, + e.to_string(), + )) + })?; + Ok(source_file.source_code) + } + .boxed_local() + } +} + async fn doc_command( flags: Flags, source_file: Option, @@ -329,41 +383,10 @@ async fn doc_command( let global_state = GlobalState::new(flags.clone())?; let source_file = source_file.unwrap_or_else(|| "--builtin".to_string()); - impl DocFileLoader for SourceFileFetcher { - fn resolve( - &self, - specifier: &str, - referrer: &str, - ) -> Result { - ModuleSpecifier::resolve_import(specifier, referrer) - .map(|specifier| specifier.to_string()) - .map_err(|e| doc::DocError::Resolve(e.to_string())) - } - - fn load_source_code( - &self, - specifier: &str, - ) -> Pin>>> { - let fetcher = self.clone(); - let specifier = ModuleSpecifier::resolve_url_or_path(specifier) - .expect("Expected valid specifier"); - async move { - let source_file = fetcher - .fetch_source_file(&specifier, None, Permissions::allow_all()) - .await - .map_err(|e| { - doc::DocError::Io(std::io::Error::new( - std::io::ErrorKind::Other, - e.to_string(), - )) - })?; - Ok(source_file.source_code) - } - .boxed_local() - } - } - - let loader = Box::new(global_state.file_fetcher.clone()); + let loader = Box::new(DocLoader { + fetcher: global_state.file_fetcher.clone(), + maybe_import_map: global_state.maybe_import_map.clone(), + }); let doc_parser = doc::DocParser::new(loader, private); let parse_result = if source_file == "--builtin" { diff --git a/cli/tests/doc/importmap.json b/cli/tests/doc/importmap.json new file mode 100644 index 0000000000..244a30296d --- /dev/null +++ b/cli/tests/doc/importmap.json @@ -0,0 +1,5 @@ +{ + "imports": { + "rex/": "./module/" + } +} diff --git a/cli/tests/doc/module/fun.js b/cli/tests/doc/module/fun.js new file mode 100644 index 0000000000..28901d9456 --- /dev/null +++ b/cli/tests/doc/module/fun.js @@ -0,0 +1,2 @@ +/** This is some documentation */ +export function fun(_a, _b) {} diff --git a/cli/tests/doc/use_importmap.js b/cli/tests/doc/use_importmap.js new file mode 100644 index 0000000000..672a7a7bd6 --- /dev/null +++ b/cli/tests/doc/use_importmap.js @@ -0,0 +1 @@ +export { fun } from "rex/fun.js"; diff --git a/cli/tests/doc/use_importmap.out b/cli/tests/doc/use_importmap.out new file mode 100644 index 0000000000..0b27ccf186 --- /dev/null +++ b/cli/tests/doc/use_importmap.out @@ -0,0 +1,5 @@ +Defined in [WILDCARD]/doc/module/fun.js:2:0 + +function fun(_a, _b) + This is some documentation + diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 8e2007b427..1a5e48adaf 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -2633,6 +2633,11 @@ itest!(deno_doc { output: "deno_doc.out", }); +itest!(deno_doc_importmap { + args: "doc --unstable --importmap=doc/importmap.json doc/use_importmap.js", + output: "doc/use_importmap.out", +}); + itest!(compiler_js_error { args: "run --unstable compiler_js_error.ts", output: "compiler_js_error.ts.out",