diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-02-26 16:32:57 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-02-26 18:15:10 -0800 |
| commit | 222cfbec6493d3cd099a7592e7948a7172469a66 (patch) | |
| tree | ca24c8d8a098b09affb44fb1cec11414fafedfd7 | |
| parent | 21650d02121a7ac63de344e901c7946236573c9e (diff) | |
| download | rust-222cfbec6493d3cd099a7592e7948a7172469a66.tar.gz rust-222cfbec6493d3cd099a7592e7948a7172469a66.zip | |
rustdoc: Add command line option parsing and a config record
| -rw-r--r-- | src/rustdoc/config.rs | 257 | ||||
| -rw-r--r-- | src/rustdoc/rustdoc.rc | 1 |
2 files changed, 258 insertions, 0 deletions
diff --git a/src/rustdoc/config.rs b/src/rustdoc/config.rs new file mode 100644 index 00000000000..da84fef584d --- /dev/null +++ b/src/rustdoc/config.rs @@ -0,0 +1,257 @@ +import std::getopts; + +export output_format::{}; +export output_style::{}; +export config; +export parse_config; + +#[doc = "The type of document to output"] +enum output_format { + #[doc = "Markdown"] + markdown, + #[doc = "HTML, via markdown and pandoc"] + pandoc_html +} + +#[doc = "How to organize the output"] +enum output_style { + #[doc = "All in a single document"] + doc_per_crate, + #[doc = "Each module in its own document"] + doc_per_mod +} + +#[doc = "The configuration for a rustdoc session"] +type config = { + input_crate: str, + output_dir: str, + output_format: output_format, + output_style: output_style, + pandoc_cmd: option<str> +}; + +fn opt_output_dir() -> str { "output-dir" } +fn opt_output_format() -> str { "output-format" } +fn opt_output_style() -> str { "output-style" } +fn opt_pandoc_cmd() -> str { "pandoc-cmd" } + +fn opts() -> [(getopts::opt, str)] { + [ + (getopts::optopt(opt_output_dir()), + "put documents here"), + (getopts::optopt(opt_output_format()), + "either 'markdown' or 'html'"), + (getopts::optopt(opt_output_style()), + "either 'doc-per-crate' or 'doc-per-mod'"), + (getopts::optopt(opt_pandoc_cmd()), + "the command for running pandoc") + ] +} + +fn default_config(input_crate: str) -> config { + { + input_crate: input_crate, + output_dir: ".", + output_format: pandoc_html, + output_style: doc_per_mod, + pandoc_cmd: none + } +} + +fn parse_config(args: [str]) -> result::t<config, str> { + let args = vec::tail(args); + let opts = tuple::first(vec::unzip(opts())); + alt getopts::getopts(args, opts) { + result::ok(match) { + if vec::len(match.free) == 1u { + let input_crate = vec::head(match.free); + config_from_opts(input_crate, match) + } else if vec::is_empty(match.free) { + result::err("no crates specified") + } else { + result::err("multiple crates specified") + } + } + result::err(f) { + result::err(getopts::fail_str(f)) + } + } +} + +fn config_from_opts( + input_crate: str, + match: getopts::match +) -> result::t<config, str> { + + let config = default_config(input_crate); + let result = result::ok(config); + let result = result::chain(result) {|config| + let output_dir = getopts::opt_maybe_str(match, opt_output_dir()); + result::ok({ + output_dir: option::from_maybe(config.output_dir, output_dir) + with config + }) + }; + let result = result::chain(result) {|config| + let output_format = getopts::opt_maybe_str( + match, opt_output_format()); + option::maybe(result::ok(config), output_format) {|output_format| + result::chain(parse_output_format(output_format)) {|output_format| + result::ok({ + output_format: output_format + with config + }) + } + } + }; + let result = result::chain(result) {|config| + let output_style = getopts::opt_maybe_str(match, opt_output_style()); + option::maybe(result::ok(config), output_style) {|output_style| + result::chain(parse_output_style(output_style)) {|output_style| + result::ok({ + output_style: output_style + with config + }) + } + } + }; + let result = result::chain(result) {|config| + let pandoc_cmd = getopts::opt_maybe_str(match, opt_pandoc_cmd()); + let pandoc_cmd = maybe_find_pandoc(config, pandoc_cmd); + result::chain(pandoc_cmd) {|pandoc_cmd| + result::ok({ + pandoc_cmd: pandoc_cmd + with config + }) + } + }; + ret result; +} + +fn parse_output_format(output_format: str) -> result::t<output_format, str> { + alt output_format { + "markdown" { result::ok(markdown) } + "html" { result::ok(pandoc_html) } + _ { result::err(#fmt("unknown output format '%s'", output_format)) } + } +} + +fn parse_output_style(output_style: str) -> result::t<output_style, str> { + alt output_style { + "doc-per-crate" { result::ok(doc_per_crate) } + "doc-per-mod" { result::ok(doc_per_mod) } + _ { result::err(#fmt("unknown output style '%s'", output_style)) } + } +} + +fn maybe_find_pandoc( + _config: config, + maybe_pandoc_cmd: option<str> +) -> result::t<option<str>, str> { + // FIXME: When we actually need pandoc then look for it first + // on the path, then in cabal; test to make sure pandoc works + alt maybe_pandoc_cmd { + some(pandoc_cmd) { result::ok(some(pandoc_cmd)) } + none { result::ok(some("pandoc")) } + } +} + +#[test] +fn should_error_with_no_crates() { + let config = parse_config(["rustdoc"]); + assert result::get_err(config) == "no crates specified"; +} + +#[test] +fn should_error_with_multiple_crates() { + let config = parse_config(["rustdoc", "crate1.rc", "crate2.rc"]); + assert result::get_err(config) == "multiple crates specified"; +} + +#[test] +fn should_set_output_dir_to_cwd_if_not_provided() { + let config = parse_config(["rustdoc", "crate.rc"]); + assert result::get(config).output_dir == "."; +} + +#[test] +fn should_set_output_dir_if_provided() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-dir", "snuggles" + ]); + assert result::get(config).output_dir == "snuggles"; +} + +#[test] +fn should_set_output_format_to_pandoc_html_if_not_provided() { + let config = parse_config(["rustdoc", "crate.rc"]); + assert result::get(config).output_format == pandoc_html; +} + +#[test] +fn should_set_output_format_to_markdown_if_requested() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-format", "markdown" + ]); + assert result::get(config).output_format == markdown; +} + +#[test] +fn should_set_output_format_to_pandoc_html_if_requested() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-format", "html" + ]); + assert result::get(config).output_format == pandoc_html; +} + +#[test] +fn should_error_on_bogus_format() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-format", "bogus" + ]); + assert result::get_err(config) == "unknown output format 'bogus'"; +} + +#[test] +fn should_set_output_style_to_doc_per_mod_by_default() { + let config = parse_config(["rustdoc", "crate.rc"]); + assert result::get(config).output_style == doc_per_mod; +} + +#[test] +fn should_set_output_style_to_one_doc_if_requested() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-style", "doc-per-crate" + ]); + assert result::get(config).output_style == doc_per_crate; +} + +#[test] +fn should_set_output_style_to_doc_per_mod_if_requested() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-style", "doc-per-mod" + ]); + assert result::get(config).output_style == doc_per_mod; +} + +#[test] +fn should_error_on_bogus_output_style() { + let config = parse_config([ + "rustdoc", "crate.rc", "--output-style", "bogus" + ]); + assert result::get_err(config) == "unknown output style 'bogus'"; +} + +#[test] +fn should_set_pandoc_command_if_requested() { + let config = parse_config([ + "rustdoc", "crate.rc", "--pandoc-cmd", "panda-bear-doc" + ]); + assert result::get(config).pandoc_cmd == some("panda-bear-doc"); +} + +#[test] +fn should_set_pandoc_command_when_using_pandoc() { + let config = parse_config(["rustdoc", "crate.rc"]); + assert result::get(config).pandoc_cmd == some("pandoc"); +} \ No newline at end of file diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 2991f490ecd..c2bf87475b1 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -12,6 +12,7 @@ use std; use rustc; +mod config; mod parse; mod extract; mod attr_parser; |
