summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-10-30 23:58:57 +0100
committerGitHub <noreply@github.com>2023-10-30 23:58:57 +0100
commit48c5c3a3fb2f43716528db8915b36e55c411d94f (patch)
tree557d833f997ab96652ef4a64dfd59348d5e4017e
parentb75f3b5ca0952db8b50cf417c107f3f14fe582d5 (diff)
feat(doc): support multiple file entry (#21018)
This commit adds support for multiple entry points to `deno doc`. Unfortunately to achieve that, I had to change the semantics of the command to explicitly require `--filter` parameter for filtering symbols, instead of treating second free argument as the filter argument. `deno doc --builtin` is still supported, but cannot be mixed with actual entrypoints.
-rw-r--r--cli/args/flags.rs118
-rw-r--r--cli/tests/integration/doc_tests.rs5
-rw-r--r--cli/tests/testdata/doc/deno_doc2.ts3
-rw-r--r--cli/tools/doc.rs30
4 files changed, 123 insertions, 33 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 6e8b00cab..5b411e36b 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -96,7 +96,7 @@ pub struct CoverageFlags {
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DocSourceFileFlag {
Builtin,
- Path(String),
+ Paths(Vec<String>),
}
impl Default for DocSourceFileFlag {
@@ -109,7 +109,7 @@ impl Default for DocSourceFileFlag {
pub struct DocFlags {
pub private: bool,
pub json: bool,
- pub source_file: DocSourceFileFlag,
+ pub source_files: DocSourceFileFlag,
pub filter: Option<String>,
}
@@ -1356,17 +1356,23 @@ Show documentation for runtime built-ins:
.help("Output private documentation")
.action(ArgAction::SetTrue),
)
+ .arg(
+ Arg::new("filter")
+ .long("filter")
+ .help("Dot separated path to symbol")
+ .required(false)
+ .conflicts_with("json"),
+ )
// TODO(nayeemrmn): Make `--builtin` a proper option. Blocked by
// https://github.com/clap-rs/clap/issues/1794. Currently `--builtin` is
// just a possible value of `source_file` so leading hyphens must be
// enabled.
.allow_hyphen_values(true)
- .arg(Arg::new("source_file").value_hint(ValueHint::FilePath))
.arg(
- Arg::new("filter")
- .help("Dot separated path to symbol")
- .required(false)
- .conflicts_with("json"),
+ Arg::new("source_file")
+ .num_args(1..)
+ .action(ArgAction::Append)
+ .value_hint(ValueHint::FilePath),
)
})
}
@@ -3090,21 +3096,29 @@ fn doc_parse(flags: &mut Flags, matches: &mut ArgMatches) {
no_npm_arg_parse(flags, matches);
no_remote_arg_parse(flags, matches);
- let source_file = matches
- .remove_one::<String>("source_file")
- .map(|value| {
- if value == "--builtin" {
+ let source_files_val = matches.remove_many::<String>("source_file");
+ let source_files = if let Some(val) = source_files_val {
+ let vals: Vec<String> = val.collect();
+
+ if vals.len() == 1 {
+ if vals[0] == "--builtin" {
DocSourceFileFlag::Builtin
} else {
- DocSourceFileFlag::Path(value)
+ DocSourceFileFlag::Paths(vec![vals[0].to_string()])
}
- })
- .unwrap_or_default();
+ } else {
+ DocSourceFileFlag::Paths(
+ vals.into_iter().filter(|v| v != "--builtin").collect(),
+ )
+ }
+ } else {
+ DocSourceFileFlag::Builtin
+ };
let private = matches.get_flag("private");
let json = matches.get_flag("json");
let filter = matches.remove_one::<String>("filter");
flags.subcommand = DenoSubcommand::Doc(DocFlags {
- source_file,
+ source_files,
json,
filter,
private,
@@ -5918,7 +5932,7 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Doc(DocFlags {
- source_file: DocSourceFileFlag::Path("script.ts".to_owned()),
+ source_files: DocSourceFileFlag::Paths(vec!["script.ts".to_owned()]),
private: false,
json: false,
filter: None,
@@ -7178,7 +7192,9 @@ mod tests {
subcommand: DenoSubcommand::Doc(DocFlags {
private: false,
json: true,
- source_file: DocSourceFileFlag::Path("path/to/module.ts".to_string()),
+ source_files: DocSourceFileFlag::Paths(vec![
+ "path/to/module.ts".to_string()
+ ]),
filter: None,
}),
..Flags::default()
@@ -7188,8 +7204,9 @@ mod tests {
let r = flags_from_vec(svec![
"deno",
"doc",
+ "--filter",
+ "SomeClass.someField",
"path/to/module.ts",
- "SomeClass.someField"
]);
assert_eq!(
r.unwrap(),
@@ -7197,7 +7214,9 @@ mod tests {
subcommand: DenoSubcommand::Doc(DocFlags {
private: false,
json: false,
- source_file: DocSourceFileFlag::Path("path/to/module.ts".to_string()),
+ source_files: DocSourceFileFlag::Paths(vec![
+ "path/to/module.ts".to_string()
+ ]),
filter: Some("SomeClass.someField".to_string()),
}),
..Flags::default()
@@ -7211,21 +7230,27 @@ mod tests {
subcommand: DenoSubcommand::Doc(DocFlags {
private: false,
json: false,
- source_file: Default::default(),
+ source_files: Default::default(),
filter: None,
}),
..Flags::default()
}
);
- let r = flags_from_vec(svec!["deno", "doc", "--builtin", "Deno.Listener"]);
+ let r = flags_from_vec(svec![
+ "deno",
+ "doc",
+ "--filter",
+ "Deno.Listener",
+ "--builtin"
+ ]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Doc(DocFlags {
private: false,
json: false,
- source_file: DocSourceFileFlag::Builtin,
+ source_files: DocSourceFileFlag::Builtin,
filter: Some("Deno.Listener".to_string()),
}),
..Flags::default()
@@ -7246,7 +7271,9 @@ mod tests {
subcommand: DenoSubcommand::Doc(DocFlags {
private: true,
json: false,
- source_file: DocSourceFileFlag::Path("path/to/module.js".to_string()),
+ source_files: DocSourceFileFlag::Paths(vec![
+ "path/to/module.js".to_string()
+ ]),
filter: None,
}),
no_npm: true,
@@ -7254,6 +7281,51 @@ mod tests {
..Flags::default()
}
);
+
+ let r = flags_from_vec(svec![
+ "deno",
+ "doc",
+ "path/to/module.js",
+ "path/to/module2.js"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Doc(DocFlags {
+ private: false,
+ json: false,
+ source_files: DocSourceFileFlag::Paths(vec![
+ "path/to/module.js".to_string(),
+ "path/to/module2.js".to_string()
+ ]),
+ filter: None,
+ }),
+ ..Flags::default()
+ }
+ );
+
+ let r = flags_from_vec(svec![
+ "deno",
+ "doc",
+ "path/to/module.js",
+ "--builtin",
+ "path/to/module2.js"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Doc(DocFlags {
+ private: false,
+ json: false,
+ source_files: DocSourceFileFlag::Paths(vec![
+ "path/to/module.js".to_string(),
+ "path/to/module2.js".to_string()
+ ]),
+ filter: None,
+ }),
+ ..Flags::default()
+ }
+ );
}
#[test]
diff --git a/cli/tests/integration/doc_tests.rs b/cli/tests/integration/doc_tests.rs
index cdbee845b..2afa8ca92 100644
--- a/cli/tests/integration/doc_tests.rs
+++ b/cli/tests/integration/doc_tests.rs
@@ -17,12 +17,13 @@ fn deno_doc() {
let output = context
.new_command()
.env("NO_COLOR", "1")
- .args("doc doc/deno_doc.ts")
+ .args("doc doc/deno_doc.ts doc/deno_doc2.ts")
.split_output()
.run();
output.assert_exit_code(0);
assert_contains!(output.stdout(), "function foo");
+ assert_contains!(output.stdout(), "function bar");
}
}
@@ -54,7 +55,7 @@ itest!(deno_doc_referenced_private_types {
itest!(_060_deno_doc_displays_all_overloads_in_details_view {
args:
- "doc doc/060_deno_doc_displays_all_overloads_in_details_view.ts NS.test",
+ "doc --filter NS.test doc/060_deno_doc_displays_all_overloads_in_details_view.ts",
output: "doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out",
});
diff --git a/cli/tests/testdata/doc/deno_doc2.ts b/cli/tests/testdata/doc/deno_doc2.ts
new file mode 100644
index 000000000..ee6fc22dc
--- /dev/null
+++ b/cli/tests/testdata/doc/deno_doc2.ts
@@ -0,0 +1,3 @@
+/** Some JSDoc */
+export function bar() {
+}
diff --git a/cli/tools/doc.rs b/cli/tools/doc.rs
index 1a770b2d3..5e87e7917 100644
--- a/cli/tools/doc.rs
+++ b/cli/tools/doc.rs
@@ -33,7 +33,7 @@ pub async fn print_docs(
let capturing_parser =
CapturingModuleParser::new(Some(&source_parser), &store);
- let mut doc_nodes = match doc_flags.source_file {
+ let mut doc_nodes = match doc_flags.source_files {
DocSourceFileFlag::Builtin => {
let source_file_specifier =
ModuleSpecifier::parse("internal://lib.deno.d.ts").unwrap();
@@ -64,18 +64,23 @@ pub async fn print_docs(
doc::DocParser::new(&graph, doc_flags.private, capturing_parser)?;
doc_parser.parse_module(&source_file_specifier)?.definitions
}
- DocSourceFileFlag::Path(source_file) => {
+ DocSourceFileFlag::Paths(source_files) => {
let module_graph_builder = factory.module_graph_builder().await?;
let maybe_lockfile = factory.maybe_lockfile();
- let module_specifier =
- resolve_url_or_path(&source_file, cli_options.initial_cwd())?;
-
+ let module_specifiers: Result<Vec<ModuleSpecifier>, AnyError> =
+ source_files
+ .iter()
+ .map(|source_file| {
+ Ok(resolve_url_or_path(source_file, cli_options.initial_cwd())?)
+ })
+ .collect();
+ let module_specifiers = module_specifiers?;
let mut loader = module_graph_builder.create_graph_loader();
let graph = module_graph_builder
.create_graph_with_options(CreateGraphOptions {
graph_kind: GraphKind::TypesOnly,
- roots: vec![module_specifier.clone()],
+ roots: module_specifiers.clone(),
loader: &mut loader,
analyzer: &analyzer,
})
@@ -85,8 +90,17 @@ pub async fn print_docs(
graph_lock_or_exit(&graph, &mut lockfile.lock());
}
- doc::DocParser::new(&graph, doc_flags.private, capturing_parser)?
- .parse_with_reexports(&module_specifier)?
+ let doc_parser =
+ doc::DocParser::new(&graph, doc_flags.private, capturing_parser)?;
+
+ let mut doc_nodes = vec![];
+
+ for module_specifier in module_specifiers {
+ let nodes = doc_parser.parse_with_reexports(&module_specifier)?;
+ doc_nodes.extend_from_slice(&nodes);
+ }
+
+ doc_nodes
}
};