mirror of
https://github.com/denoland/deno.git
synced 2024-10-29 08:58:01 -04:00
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.
This commit is contained in:
parent
b75f3b5ca0
commit
48c5c3a3fb
4 changed files with 123 additions and 33 deletions
|
@ -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]
|
||||
|
|
|
@ -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",
|
||||
});
|
||||
|
||||
|
|
3
cli/tests/testdata/doc/deno_doc2.ts
vendored
Normal file
3
cli/tests/testdata/doc/deno_doc2.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/** Some JSDoc */
|
||||
export function bar() {
|
||||
}
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue