Skip to content

Commit 4640db7

Browse files
committed
Merge branch 'docs.rs-extern-version' into docs.rs
2 parents f89d8d1 + aebd6b5 commit 4640db7

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

src/librustc/session/config.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
12661266
opts.extend_from_slice(&[
12671267
opt::multi_s("", "extern", "Specify where an external rust library is located",
12681268
"NAME=PATH"),
1269+
opt::multi_s("", "extern-version", "", "NAME=CRATE_NAME,VERSION"),
12691270
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
12701271
opt::multi("Z", "", "Set internal debugging options", "FLAG"),
12711272
opt::opt_s("", "error-format",

src/librustdoc/html/render.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use rustc::middle::stability;
6161
use rustc::hir;
6262
use rustc::util::nodemap::{FxHashMap, FxHashSet};
6363
use rustc::session::config::nightly_options::is_nightly_build;
64+
use rustc::session::config::Externs;
6465
use rustc_data_structures::flock;
6566

6667
use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
@@ -429,6 +430,7 @@ pub fn derive_id(candidate: String) -> String {
429430

430431
/// Generates the documentation for `crate` into the directory `dst`
431432
pub fn run(mut krate: clean::Crate,
433+
extern_versions: Externs,
432434
external_html: &ExternalHtml,
433435
playground_url: Option<String>,
434436
dst: PathBuf,
@@ -539,8 +541,10 @@ pub fn run(mut krate: clean::Crate,
539541
Some(p) => p.to_path_buf(),
540542
None => PathBuf::new(),
541543
};
544+
let extern_version = extern_versions.get(&e.name)
545+
.and_then(|e| e.iter().last().map(|e| e.clone()));
542546
cache.extern_locations.insert(n, (e.name.clone(), src_root,
543-
extern_location(e, &cx.dst)));
547+
extern_location(e, extern_version, &cx.dst)));
544548

545549
let did = DefId { krate: n, index: CRATE_DEF_INDEX };
546550
cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
@@ -864,13 +868,24 @@ fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) wh
864868

865869
/// Attempts to find where an external crate is located, given that we're
866870
/// rendering in to the specified source destination.
867-
fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
871+
fn extern_location(e: &clean::ExternalCrate, version: Option<String>, dst: &Path) -> ExternalLocation {
868872
// See if there's documentation generated into the local directory
869873
let local_location = dst.join(&e.name);
870874
if local_location.is_dir() {
871875
return Local;
872876
}
873877

878+
// version is only used in docs.rs' cargo
879+
if let Some(version) = version {
880+
let mut vs = version.split(",");
881+
// FIXME: get rid of this stupid ifs
882+
if let Some(name) = vs.next() {
883+
if let Some(version) = vs.next() {
884+
return Remote(format!("https://docs.rs/{}/{}/", name, version));
885+
}
886+
}
887+
}
888+
874889
// Failing that, see if there's an attribute specifying where to find this
875890
// external crate
876891
e.attrs.lists("doc")

src/librustdoc/lib.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ pub fn opts() -> Vec<RustcOptGroup> {
139139
"DIR")),
140140
stable(optmulti("", "cfg", "pass a --cfg to rustc", "")),
141141
stable(optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")),
142+
stable(optmulti("", "extern-version", "pass an --extern-version to rustc",
143+
"NAME=CRATE_NAME,VERSION")),
142144
stable(optmulti("", "plugin-path", "directory to load plugins from", "DIR")),
143145
stable(optmulti("", "passes",
144146
"list of passes to also run, you might want \
@@ -259,6 +261,14 @@ pub fn main_args(args: &[String]) -> isize {
259261
}
260262
};
261263

264+
let extern_versions = match parse_extern_versions(&matches) {
265+
Ok(ex) => ex,
266+
Err(err) => {
267+
print_error(err);
268+
return 1;
269+
}
270+
};
271+
262272
let test_args = matches.opt_strs("test-args");
263273
let test_args: Vec<String> = test_args.iter()
264274
.flat_map(|s| s.split_whitespace())
@@ -326,7 +336,7 @@ pub fn main_args(args: &[String]) -> isize {
326336
info!("going to format");
327337
match output_format.as_ref().map(|s| &**s) {
328338
Some("html") | None => {
329-
html::render::run(krate, &external_html, playground_url,
339+
html::render::run(krate, extern_versions, &external_html, playground_url,
330340
output.unwrap_or(PathBuf::from("doc")),
331341
passes.into_iter().collect(),
332342
css_file_extension,
@@ -388,6 +398,23 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
388398
Ok(Externs::new(externs))
389399
}
390400

401+
/// Extracts `--extern CRATE=CRATE_NAME,VERSION` arguments from `matches` and
402+
/// returns a map mapping crate names to their paths or else an
403+
/// error message.
404+
fn parse_extern_versions(matches: &getopts::Matches) -> Result<Externs, String> {
405+
let mut externs = BTreeMap::new();
406+
for arg in &matches.opt_strs("extern-version") {
407+
let mut parts = arg.splitn(2, '=');
408+
let name = parts.next().ok_or("--extern-version value must not be empty".to_string())?;
409+
let location = parts.next()
410+
.ok_or("--extern-version value must be of the format `foo=bar`"
411+
.to_string())?;
412+
let name = name.to_string();
413+
externs.entry(name).or_insert_with(BTreeSet::new).insert(location.to_string());
414+
}
415+
Ok(Externs::new(externs))
416+
}
417+
391418
/// Interprets the input file as a rust source file, passing it through the
392419
/// compiler all the way through the analysis passes. The rustdoc output is then
393420
/// generated from the cleaned AST of the crate.

0 commit comments

Comments
 (0)