Skip to content

Commit 1318e53

Browse files
committed
Persist doc test executables to given path.
1 parent daa53a5 commit 1318e53

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

src/librustdoc/config.rs

+4
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ pub struct Options {
6868
pub should_test: bool,
6969
/// List of arguments to pass to the test harness, if running tests.
7070
pub test_args: Vec<String>,
71+
/// Whether to persist the doctest executables.
72+
pub persist_doctests: Option<PathBuf>,
7173

7274
// Options that affect the documentation process
7375

@@ -431,6 +433,7 @@ impl Options {
431433
let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
432434
let static_root_path = matches.opt_str("static-root-path");
433435
let generate_search_filter = !matches.opt_present("disable-per-crate-search");
436+
let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
434437

435438
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
436439

@@ -456,6 +459,7 @@ impl Options {
456459
manual_passes,
457460
display_warnings,
458461
crate_version,
462+
persist_doctests,
459463
render_options: RenderOptions {
460464
output,
461465
external_html,

src/librustdoc/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ fn opts() -> Vec<RustcOptGroup> {
340340
o.optflag("",
341341
"disable-per-crate-search",
342342
"disables generating the crate selector on the search box")
343+
unstable("persist-doctests", |o| {
344+
o.optopt("",
345+
"persist-doctests",
346+
"Persists the rustdoc test executables",
347+
"PATH")
343348
}),
344349
]
345350
}

src/librustdoc/markdown.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> isize {
142142
options.libs, options.codegen_options, options.externs,
143143
true, opts, options.maybe_sysroot, None,
144144
Some(options.input),
145-
options.linker, options.edition);
145+
options.linker, options.edition, options.persist_doctests);
146146
collector.set_position(DUMMY_SP);
147147
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
148148
let res = find_testable_code(&input_str, &mut collector, codes);

src/librustdoc/test.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ pub fn run(mut options: Options) -> isize {
120120
Some(source_map),
121121
None,
122122
options.linker,
123-
options.edition
123+
options.edition,
124+
options.persist_doctests,
124125
);
125126

126127
{
@@ -184,7 +185,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
184185
cg: CodegenOptions, externs: Externs,
185186
should_panic: bool, no_run: bool, as_test_harness: bool,
186187
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
187-
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) {
188+
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
189+
persist_doctests: Option<PathBuf>) {
188190
// The test harness wants its own `main` and top-level functions, so
189191
// never wrap the test in `fn main() { ... }`.
190192
let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts);
@@ -249,6 +251,20 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
249251
let old = io::set_panic(Some(box Sink(data.clone())));
250252
let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
251253

254+
enum DirState {
255+
Temp(tempfile::TempDir),
256+
Perm(PathBuf),
257+
}
258+
259+
impl DirState {
260+
fn path(&self) -> &std::path::Path {
261+
match self {
262+
DirState::Temp(t) => t.path(),
263+
DirState::Perm(p) => p.as_path(),
264+
}
265+
}
266+
}
267+
252268
let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| {
253269
let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping()));
254270
let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
@@ -267,7 +283,17 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
267283
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
268284

269285
let outdir = Mutex::new(
270-
TempFileBuilder::new().prefix("rustdoctest").tempdir().expect("rustdoc needs a tempdir")
286+
if let Some(mut path) = persist_doctests {
287+
path.push(format!("{}_{}", filename.to_string().rsplit('/').next().unwrap().replace(".", "_"), line));
288+
std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables");
289+
290+
DirState::Perm(path)
291+
} else {
292+
DirState::Temp(TempFileBuilder::new()
293+
.prefix("rustdoctest")
294+
.tempdir()
295+
.expect("rustdoc needs a tempdir"))
296+
}
271297
);
272298
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
273299
let mut control = driver::CompileController::basic();
@@ -629,13 +655,15 @@ pub struct Collector {
629655
filename: Option<PathBuf>,
630656
linker: Option<PathBuf>,
631657
edition: Edition,
658+
persist_doctests: Option<PathBuf>,
632659
}
633660

634661
impl Collector {
635662
pub fn new(cratename: String, cfgs: Vec<String>, libs: Vec<SearchPath>, cg: CodegenOptions,
636663
externs: Externs, use_headers: bool, opts: TestOptions,
637664
maybe_sysroot: Option<PathBuf>, source_map: Option<Lrc<SourceMap>>,
638-
filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) -> Collector {
665+
filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
666+
persist_doctests: Option<PathBuf>) -> Collector {
639667
Collector {
640668
tests: Vec::new(),
641669
names: Vec::new(),
@@ -652,6 +680,7 @@ impl Collector {
652680
filename,
653681
linker,
654682
edition,
683+
persist_doctests,
655684
}
656685
}
657686

@@ -695,6 +724,8 @@ impl Tester for Collector {
695724
let maybe_sysroot = self.maybe_sysroot.clone();
696725
let linker = self.linker.clone();
697726
let edition = config.edition.unwrap_or(self.edition);
727+
let persist_doctests = self.persist_doctests.clone();
728+
698729
debug!("Creating test {}: {}", name, test);
699730
self.tests.push(testing::TestDescAndFn {
700731
desc: testing::TestDesc {
@@ -727,7 +758,8 @@ impl Tester for Collector {
727758
&opts,
728759
maybe_sysroot,
729760
linker,
730-
edition)
761+
edition,
762+
persist_doctests)
731763
}))
732764
} {
733765
Ok(()) => (),

0 commit comments

Comments
 (0)