mirror of
https://github.com/rust-lang/cargo
synced 2024-10-02 22:13:47 +00:00
Add cargo rustdoc
for passing arbitrary flags to rustdoc
This commit is contained in:
parent
b01770c7ad
commit
4816a2a5d8
|
@ -84,6 +84,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
&options.flag_test,
|
||||
&options.flag_example,
|
||||
&options.flag_bench),
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: None,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -81,6 +81,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
&options.flag_test,
|
||||
&options.flag_example,
|
||||
&options.flag_bench),
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ macro_rules! each_subcommand{ ($mac:ident) => ({
|
|||
$mac!(read_manifest);
|
||||
$mac!(run);
|
||||
$mac!(rustc);
|
||||
$mac!(rustdoc);
|
||||
$mac!(search);
|
||||
$mac!(test);
|
||||
$mac!(uninstall);
|
||||
|
|
|
@ -70,6 +70,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
deps: !options.flag_no_deps,
|
||||
},
|
||||
target_rustc_args: None,
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
bins: &bins, examples: &examples,
|
||||
}
|
||||
},
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
&options.flag_test,
|
||||
&options.flag_example,
|
||||
&options.flag_bench),
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]),
|
||||
};
|
||||
|
||||
|
|
89
src/bin/rustdoc.rs
Normal file
89
src/bin/rustdoc.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use cargo::ops;
|
||||
use cargo::util::{CliResult, CliError, Config};
|
||||
use cargo::util::important_paths::{find_root_manifest_for_cwd};
|
||||
|
||||
#[derive(RustcDecodable)]
|
||||
struct Options {
|
||||
arg_opts: Vec<String>,
|
||||
flag_target: Option<String>,
|
||||
flag_features: Vec<String>,
|
||||
flag_jobs: Option<u32>,
|
||||
flag_manifest_path: Option<String>,
|
||||
flag_no_default_features: bool,
|
||||
flag_no_deps: bool,
|
||||
flag_open: bool,
|
||||
flag_verbose: bool,
|
||||
flag_release: bool,
|
||||
flag_quiet: bool,
|
||||
flag_color: Option<String>,
|
||||
flag_package: Option<String>,
|
||||
}
|
||||
|
||||
pub const USAGE: &'static str = "
|
||||
Build a package's documentation, using specified custom flags.
|
||||
|
||||
Usage:
|
||||
cargo rustdoc [options] [--] [<opts>...]
|
||||
|
||||
Options:
|
||||
-h, --help Print this message
|
||||
--open Opens the docs in a browser after the operation
|
||||
-p SPEC, --package SPEC Package to document
|
||||
--no-deps Don't build documentation for dependencies
|
||||
-j N, --jobs N The number of jobs to run in parallel
|
||||
--release Build artifacts in release mode, with optimizations
|
||||
--features FEATURES Space-separated list of features to also build
|
||||
--no-default-features Do not build the `default` feature
|
||||
--target TRIPLE Build for the target triple
|
||||
--manifest-path PATH Path to the manifest to document
|
||||
-v, --verbose Use verbose output
|
||||
-q, --quiet No output printed to stdout
|
||||
--color WHEN Coloring: auto, always, never
|
||||
|
||||
By default the documentation for the local package and all dependencies is
|
||||
built. The output is all placed in `target/doc` in rustdoc's usual format.
|
||||
|
||||
The specified target for the current package (or package specified by SPEC if
|
||||
provided) will be documented along with all of its dependencies. The specified
|
||||
<opts>... will all be passed to the final rustdoc invocation, not any of the
|
||||
dependencies. Note that rustdoc will still unconditionally receive
|
||||
arguments such as -L, --extern, and --crate-type, and the specified <opts>...
|
||||
will simply be added to the rustdoc invocation.
|
||||
|
||||
If the --package argument is given, then SPEC is a package id specification
|
||||
which indicates which package should be documented. If it is not given, then the
|
||||
current package is documented. For more information on SPEC and its format, see
|
||||
the `cargo help pkgid` command.
|
||||
";
|
||||
|
||||
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
||||
try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet));
|
||||
try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..])));
|
||||
|
||||
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
|
||||
|
||||
let mut doc_opts = ops::DocOptions {
|
||||
open_result: options.flag_open,
|
||||
compile_opts: ops::CompileOptions {
|
||||
config: config,
|
||||
jobs: options.flag_jobs,
|
||||
target: options.flag_target.as_ref().map(|t| &t[..]),
|
||||
features: &options.flag_features,
|
||||
no_default_features: options.flag_no_default_features,
|
||||
spec: options.flag_package.as_ref().map(|s| &s[..]),
|
||||
exec_engine: None,
|
||||
filter: ops::CompileFilter::Everything,
|
||||
release: options.flag_release,
|
||||
mode: ops::CompileMode::Doc {
|
||||
deps: !options.flag_no_deps,
|
||||
},
|
||||
extra_rustdoc_args: options.arg_opts,
|
||||
target_rustc_args: None,
|
||||
},
|
||||
};
|
||||
|
||||
try!(ops::doc(&root, &mut doc_opts).map_err(|err| CliError::from_boxed(err, 101)));
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
|
@ -90,6 +90,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
|
|||
&options.flag_test,
|
||||
&options.flag_example,
|
||||
&options.flag_bench),
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: None,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -112,6 +112,7 @@ pub struct Profile {
|
|||
pub lto: bool,
|
||||
pub codegen_units: Option<u32>, // None = use rustc default
|
||||
pub rustc_args: Option<Vec<String>>,
|
||||
pub rustdoc_args: Option<Vec<String>>,
|
||||
pub debuginfo: bool,
|
||||
pub debug_assertions: bool,
|
||||
pub rpath: bool,
|
||||
|
@ -474,6 +475,7 @@ impl Default for Profile {
|
|||
lto: false,
|
||||
codegen_units: None,
|
||||
rustc_args: None,
|
||||
rustdoc_args: None,
|
||||
debuginfo: false,
|
||||
debug_assertions: false,
|
||||
rpath: false,
|
||||
|
|
|
@ -57,6 +57,8 @@ pub struct CompileOptions<'a> {
|
|||
pub release: bool,
|
||||
/// Mode for this compile.
|
||||
pub mode: CompileMode,
|
||||
/// Extra arguments to be passed to rustdoc (for main crate and dependencies)
|
||||
pub extra_rustdoc_args: Vec<String>,
|
||||
/// The specified target will be compiled with all the available arguments,
|
||||
/// note that this only accounts for the *final* invocation of rustc
|
||||
pub target_rustc_args: Option<&'a [String]>,
|
||||
|
@ -145,6 +147,7 @@ pub fn compile_pkg<'a>(root_package: &Package,
|
|||
let CompileOptions { config, jobs, target, spec, features,
|
||||
no_default_features, release, mode,
|
||||
ref filter, ref exec_engine,
|
||||
ref extra_rustdoc_args,
|
||||
ref target_rustc_args } = *options;
|
||||
|
||||
let target = target.map(|s| s.to_string());
|
||||
|
@ -223,6 +226,24 @@ pub fn compile_pkg<'a>(root_package: &Package,
|
|||
}
|
||||
|
||||
let mut ret = {
|
||||
let mut target_with_rustdoc = None;
|
||||
if !extra_rustdoc_args.is_empty() {
|
||||
let mut target_with_rustdoc_inner = Vec::new();
|
||||
for &(target, profile) in &targets {
|
||||
if profile.doc {
|
||||
let mut profile = profile.clone();
|
||||
profile.rustdoc_args = Some(extra_rustdoc_args.clone());
|
||||
target_with_rustdoc_inner.push((target, profile));
|
||||
}
|
||||
}
|
||||
target_with_rustdoc = Some(target_with_rustdoc_inner);
|
||||
};
|
||||
|
||||
let targets = target_with_rustdoc.as_ref().map_or(targets,
|
||||
|o| o.into_iter()
|
||||
.map(|&(t, ref p)| (t, p))
|
||||
.collect());
|
||||
let ret = {
|
||||
let _p = profile::start("compiling");
|
||||
let mut build_config = try!(scrape_build_config(config, jobs, target));
|
||||
build_config.exec_engine = exec_engine.clone();
|
||||
|
|
|
@ -220,6 +220,7 @@ fn run_verify(config: &Config, pkg: &Package, tar: &Path)
|
|||
exec_engine: None,
|
||||
release: false,
|
||||
mode: ops::CompileMode::Build,
|
||||
extra_rustdoc_args: Vec::new(),
|
||||
target_rustc_args: None,
|
||||
}));
|
||||
|
||||
|
|
|
@ -395,6 +395,10 @@ fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(ref args) = profile.rustdoc_args {
|
||||
rustdoc.args(args);
|
||||
}
|
||||
|
||||
try!(build_deps_args(&mut rustdoc, cx, unit));
|
||||
|
||||
if unit.pkg.has_custom_build() {
|
||||
|
@ -448,6 +452,7 @@ fn build_base_args(cx: &Context,
|
|||
let Profile {
|
||||
opt_level, lto, codegen_units, ref rustc_args, debuginfo,
|
||||
debug_assertions, rpath, test, doc: _doc, run_custom_build,
|
||||
rustdoc_args: _,
|
||||
} = *unit.profile;
|
||||
assert!(!run_custom_build);
|
||||
|
||||
|
|
|
@ -941,6 +941,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
|
|||
lto: lto.unwrap_or(profile.lto),
|
||||
codegen_units: codegen_units,
|
||||
rustc_args: None,
|
||||
rustdoc_args: None,
|
||||
debuginfo: debug.unwrap_or(profile.debuginfo),
|
||||
debug_assertions: debug_assertions.unwrap_or(profile.debug_assertions),
|
||||
rpath: rpath.unwrap_or(profile.rpath),
|
||||
|
|
178
tests/test_cargo_rustdoc.rs
Normal file
178
tests/test_cargo_rustdoc.rs
Normal file
|
@ -0,0 +1,178 @@
|
|||
use std::path::MAIN_SEPARATOR as SEP;
|
||||
use support::{execs, project};
|
||||
use support::{COMPILING, RUNNING};
|
||||
use hamcrest::{assert_that};
|
||||
|
||||
fn setup() {
|
||||
}
|
||||
|
||||
|
||||
test!(rustdoc_simple {
|
||||
let p = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
"#)
|
||||
.file("src/lib.rs", r#" "#);
|
||||
|
||||
assert_that(p.cargo_process("rustdoc").arg("-v"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stdout(format!("\
|
||||
{compiling} foo v0.0.1 ({url})
|
||||
{running} `rustdoc src{sep}lib.rs --crate-name foo \
|
||||
-o {dir}{sep}target{sep}doc \
|
||||
-L dependency={dir}{sep}target{sep}debug \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps`
|
||||
",
|
||||
running = RUNNING, compiling = COMPILING, sep = SEP,
|
||||
dir = p.root().display(), url = p.url())));
|
||||
});
|
||||
|
||||
test!(rustdoc_args {
|
||||
let p = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
"#)
|
||||
.file("src/lib.rs", r#" "#);
|
||||
|
||||
assert_that(p.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stdout(format!("\
|
||||
{compiling} foo v0.0.1 ({url})
|
||||
{running} `rustdoc src{sep}lib.rs --crate-name foo \
|
||||
-o {dir}{sep}target{sep}doc \
|
||||
--no-defaults \
|
||||
-L dependency={dir}{sep}target{sep}debug \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps`
|
||||
",
|
||||
running = RUNNING, compiling = COMPILING, sep = SEP,
|
||||
dir = p.root().display(), url = p.url())));
|
||||
});
|
||||
|
||||
|
||||
|
||||
test!(rustdoc_foo_with_bar_dependency {
|
||||
let foo = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
|
||||
[dependencies.bar]
|
||||
path = "../bar"
|
||||
"#)
|
||||
.file("src/lib.rs", r#"
|
||||
extern crate bar;
|
||||
pub fn foo() {}
|
||||
"#);
|
||||
let bar = project("bar")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "bar"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
"#)
|
||||
.file("src/lib.rs", r#"
|
||||
pub fn baz() {}
|
||||
"#);
|
||||
bar.build();
|
||||
|
||||
assert_that(foo.cargo_process("rustdoc").arg("-v").arg("--").arg("--no-defaults"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stdout(format!("\
|
||||
{compiling} bar v0.0.1 ({url})
|
||||
{running} `rustc {bar_dir}{sep}src{sep}lib.rs [..]`
|
||||
{running} `rustdoc {bar_dir}{sep}src{sep}lib.rs --crate-name bar \
|
||||
-o {dir}{sep}target{sep}doc \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps`
|
||||
{compiling} foo v0.0.1 ({url})
|
||||
{running} `rustdoc src{sep}lib.rs --crate-name foo \
|
||||
-o {dir}{sep}target{sep}doc \
|
||||
--no-defaults \
|
||||
-L dependency={dir}{sep}target{sep}debug \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps \
|
||||
--extern [..]`
|
||||
",
|
||||
running = RUNNING, compiling = COMPILING, sep = SEP,
|
||||
dir = foo.root().display(), url = foo.url(),
|
||||
bar_dir = bar.root().display())));
|
||||
});
|
||||
|
||||
test!(rustdoc_only_bar_dependency {
|
||||
let foo = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
|
||||
[dependencies.bar]
|
||||
path = "../bar"
|
||||
"#)
|
||||
.file("src/main.rs", r#"
|
||||
extern crate bar;
|
||||
fn main() {
|
||||
bar::baz()
|
||||
}
|
||||
"#);
|
||||
let bar = project("bar")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "bar"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
"#)
|
||||
.file("src/lib.rs", r#"
|
||||
pub fn baz() {}
|
||||
"#);
|
||||
bar.build();
|
||||
|
||||
assert_that(foo.cargo_process("rustdoc").arg("-v").arg("-p").arg("bar")
|
||||
.arg("--").arg("--no-defaults"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stdout(format!("\
|
||||
{compiling} bar v0.0.1 ({url})
|
||||
{running} `rustdoc {bar_dir}{sep}src{sep}lib.rs --crate-name bar \
|
||||
-o {dir}{sep}target{sep}doc \
|
||||
--no-defaults \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps \
|
||||
-L dependency={dir}{sep}target{sep}debug{sep}deps`
|
||||
",
|
||||
running = RUNNING, compiling = COMPILING, sep = SEP,
|
||||
dir = foo.root().display(), url = foo.url(),
|
||||
bar_dir = bar.root().display())));
|
||||
});
|
||||
|
||||
|
||||
test!(rustdoc_same_name_err {
|
||||
let p = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
"#)
|
||||
.file("src/main.rs", r#"
|
||||
fn main() {}
|
||||
"#)
|
||||
.file("src/lib.rs", r#" "#);
|
||||
|
||||
assert_that(p.cargo_process("rustdoc").arg("-v")
|
||||
.arg("--").arg("--no-defaults"),
|
||||
execs()
|
||||
.with_status(101)
|
||||
.with_stderr("Cannot document a package where a library and a \
|
||||
binary have the same name. Consider renaming one \
|
||||
or marking the target as `doc = false`"));
|
||||
});
|
|
@ -57,6 +57,7 @@ mod test_cargo_read_manifest;
|
|||
mod test_cargo_registry;
|
||||
mod test_cargo_run;
|
||||
mod test_cargo_rustc;
|
||||
mod test_cargo_rustdoc;
|
||||
mod test_cargo_search;
|
||||
mod test_cargo_test;
|
||||
mod test_cargo_tool_paths;
|
||||
|
|
Loading…
Reference in a new issue