Skip to content

Commit 70f3821

Browse files
committed
Change scraping strategy to embed in existing unit graph, add CompileMode::Docscrape
1 parent 82d937e commit 70f3821

File tree

10 files changed

+157
-122
lines changed

10 files changed

+157
-122
lines changed

src/cargo/core/compiler/build_config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub enum CompileMode {
149149
Doc { deps: bool },
150150
/// A target that will be tested with `rustdoc`.
151151
Doctest,
152+
Docscrape,
152153
/// A marker for Units that represent the execution of a `build.rs` script.
153154
RunCustomBuild,
154155
}
@@ -166,6 +167,7 @@ impl ser::Serialize for CompileMode {
166167
Bench => "bench".serialize(s),
167168
Doc { .. } => "doc".serialize(s),
168169
Doctest => "doctest".serialize(s),
170+
Docscrape => "docscrape".serialize(s),
169171
RunCustomBuild => "run-custom-build".serialize(s),
170172
}
171173
}
@@ -187,6 +189,11 @@ impl CompileMode {
187189
self == CompileMode::Doctest
188190
}
189191

192+
/// Returns `true` if this is scraping examples for documentation.
193+
pub fn is_doc_scrape(self) -> bool {
194+
self == CompileMode::Docscrape
195+
}
196+
190197
/// Returns `true` if this is any type of test (test, benchmark, doc test, or
191198
/// check test).
192199
pub fn is_any_test(self) -> bool {

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pub struct BuildContext<'a, 'cfg> {
4848
/// The dependency graph of units to compile.
4949
pub unit_graph: UnitGraph,
5050

51+
pub scrape_units: Vec<Unit>,
52+
5153
/// The list of all kinds that are involved in this build
5254
pub all_kinds: HashSet<CompileKind>,
5355
}
@@ -62,6 +64,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
6264
target_data: RustcTargetData<'cfg>,
6365
roots: Vec<Unit>,
6466
unit_graph: UnitGraph,
67+
scrape_units: Vec<Unit>,
6568
) -> CargoResult<BuildContext<'a, 'cfg>> {
6669
let all_kinds = unit_graph
6770
.keys()
@@ -80,6 +83,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
8083
target_data,
8184
roots,
8285
unit_graph,
86+
scrape_units,
8387
all_kinds,
8488
})
8589
}

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,10 @@ impl TargetInfo {
461461
}
462462
}
463463
CompileMode::Check { .. } => Ok((vec![FileType::new_rmeta()], Vec::new())),
464-
CompileMode::Doc { .. } | CompileMode::Doctest | CompileMode::RunCustomBuild => {
464+
CompileMode::Doc { .. }
465+
| CompileMode::Doctest
466+
| CompileMode::Docscrape
467+
| CompileMode::RunCustomBuild => {
465468
panic!("asked for rustc output for non-rustc mode")
466469
}
467470
}

src/cargo/core/compiler/context/compilation_files.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,10 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
417417
// but Cargo does not know about that.
418418
vec![]
419419
}
420+
CompileMode::Docscrape => {
421+
// FIXME(wcrichto): should this include the *.examples files?
422+
vec![]
423+
}
420424
CompileMode::Test
421425
| CompileMode::Build
422426
| CompileMode::Bench

src/cargo/core/compiler/job_queue.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ impl<'cfg> DrainState<'cfg> {
10011001
let target_name = unit.target.name();
10021002
match unit.mode {
10031003
CompileMode::Doc { .. } => format!("{}(doc)", pkg_name),
1004+
CompileMode::Docscrape { .. } => format!("{}(docscrape)", pkg_name),
10041005
CompileMode::RunCustomBuild => format!("{}(build)", pkg_name),
10051006
CompileMode::Test | CompileMode::Check { test: true } => match unit.target.kind() {
10061007
TargetKind::Lib(_) => format!("{}(test)", target_name),

src/cargo/core/compiler/mod.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ fn compile<'cfg>(
165165
let force = exec.force_rebuild(unit) || force_rebuild;
166166
let mut job = fingerprint::prepare_target(cx, unit, force)?;
167167
job.before(if job.freshness() == Freshness::Dirty {
168-
let work = if unit.mode.is_doc() {
168+
let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() {
169169
rustdoc(cx, unit)?
170170
} else {
171171
rustc(cx, unit, exec)?
@@ -647,6 +647,48 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
647647
rustdoc.args(args);
648648
}
649649

650+
let scrape_output_path = |unit: &Unit| -> CargoResult<PathBuf> {
651+
let layout = cx.files().layout(unit.kind);
652+
let output_dir = layout.prepare_tmp()?;
653+
Ok(output_dir.join(format!("{}.examples", unit.buildkey())))
654+
};
655+
656+
if unit.mode.is_doc_scrape() {
657+
rustdoc.arg("-Zunstable-options");
658+
659+
rustdoc
660+
.arg("--scrape-examples-output-path")
661+
.arg(scrape_output_path(unit)?);
662+
663+
for root in &cx.bcx.roots {
664+
rustdoc
665+
.arg("--scrape-examples-target-crate")
666+
.arg(root.pkg.name());
667+
}
668+
} else if cx.bcx.scrape_units.len() > 0 {
669+
rustdoc.arg("-Zunstable-options");
670+
671+
for scrape_unit in &cx.bcx.scrape_units {
672+
rustdoc
673+
.arg("--with-examples")
674+
.arg(scrape_output_path(scrape_unit)?);
675+
}
676+
677+
let mut all_units = cx
678+
.bcx
679+
.unit_graph
680+
.values()
681+
.map(|deps| deps.iter().map(|dep| &dep.unit))
682+
.flatten();
683+
let check_unit = all_units
684+
.find(|other| {
685+
unit.pkg == other.pkg && unit.target == other.target && other.mode.is_check()
686+
})
687+
.with_context(|| format!("Could not find check unit for {:?}", unit))?;
688+
let metadata = cx.files().metadata(check_unit);
689+
rustdoc.arg("-C").arg(format!("metadata={}", metadata));
690+
}
691+
650692
build_deps_args(&mut rustdoc, cx, unit)?;
651693
rustdoc::add_root_urls(cx, unit, &mut rustdoc)?;
652694

src/cargo/core/compiler/timings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ impl<'cfg> Timings<'cfg> {
176176
CompileMode::Bench => target.push_str(" (bench)"),
177177
CompileMode::Doc { .. } => target.push_str(" (doc)"),
178178
CompileMode::Doctest => target.push_str(" (doc test)"),
179+
CompileMode::Docscrape => target.push_str(" (doc scrape)"),
179180
CompileMode::RunCustomBuild => target.push_str(" (run)"),
180181
}
181182
let unit_time = UnitTime {

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct State<'a, 'cfg> {
4747
target_data: &'a RustcTargetData<'cfg>,
4848
profiles: &'a Profiles,
4949
interner: &'a UnitInterner,
50+
scrape_roots: &'a [Unit],
5051

5152
/// A set of edges in `unit_dependencies` where (a, b) means that the
5253
/// dependency from a to b was added purely because it was a dev-dependency.
@@ -61,6 +62,7 @@ pub fn build_unit_dependencies<'a, 'cfg>(
6162
features: &'a ResolvedFeatures,
6263
std_resolve: Option<&'a (Resolve, ResolvedFeatures)>,
6364
roots: &[Unit],
65+
scrape_roots: &[Unit],
6466
std_roots: &HashMap<CompileKind, Vec<Unit>>,
6567
global_mode: CompileMode,
6668
target_data: &'a RustcTargetData<'cfg>,
@@ -91,12 +93,14 @@ pub fn build_unit_dependencies<'a, 'cfg>(
9193
target_data,
9294
profiles,
9395
interner,
96+
scrape_roots,
9497
dev_dependency_edges: HashSet::new(),
9598
};
9699

97100
let std_unit_deps = calc_deps_of_std(&mut state, std_roots)?;
98101

99102
deps_of_roots(roots, &mut state)?;
103+
deps_of_roots(scrape_roots, &mut state)?;
100104
super::links::validate_links(state.resolve(), &state.unit_dependencies)?;
101105
// Hopefully there aren't any links conflicts with the standard library?
102106

@@ -477,6 +481,17 @@ fn compute_deps_doc(
477481
if unit.target.is_bin() || unit.target.is_example() {
478482
ret.extend(maybe_lib(unit, state, unit_for)?);
479483
}
484+
485+
for scrape_unit in state.scrape_roots.iter() {
486+
ret.push(UnitDep {
487+
unit: scrape_unit.clone(),
488+
unit_for: unit_for.with_dependency(scrape_unit, &scrape_unit.target),
489+
extern_crate_name: InternedString::new(""),
490+
public: false,
491+
noprelude: false,
492+
});
493+
}
494+
480495
Ok(ret)
481496
}
482497

@@ -568,7 +583,7 @@ fn dep_build_script(
568583
/// Choose the correct mode for dependencies.
569584
fn check_or_build_mode(mode: CompileMode, target: &Target) -> CompileMode {
570585
match mode {
571-
CompileMode::Check { .. } | CompileMode::Doc { .. } => {
586+
CompileMode::Check { .. } | CompileMode::Doc { .. } | CompileMode::Docscrape => {
572587
if target.for_host() {
573588
// Plugin and proc macro targets should be compiled like
574589
// normal.

src/cargo/core/profiles.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl Profiles {
323323
(InternedString::new("dev"), None)
324324
}
325325
}
326-
CompileMode::Doc { .. } => (InternedString::new("doc"), None),
326+
CompileMode::Doc { .. } | CompileMode::Docscrape => (InternedString::new("doc"), None),
327327
}
328328
} else {
329329
(self.requested_profile, None)

0 commit comments

Comments
 (0)