
Run the paper's scripts, in order, in isolated subprocesses
Source:R/reproducibility_check.R
repro_run_scripts.RdRuns each script with callr::r() from run_dir, with lib_dir prepended to
the subprocess .libPaths() so the throwaway library is seen. Each run is
bounded by timeout seconds; its exit, error, stdout and stderr are captured.
A script whose inputs are known-missing (in skip) is not run — it is
recorded skipped_missing_inputs, since it cannot succeed and would only
produce a confusing error. callr isolates a crash to the subprocess; it does
not sandbox the filesystem or network, so this only runs on explicit opt-in.
Arguments
- run_tbl
repro_write_scripts()output (file_name,script_path,run_dir)- order
a vector of
file_names in the order to run (unplaceable files are appended at the end in input order)- lib_dir
throwaway library to expose to each subprocess (or NULL)
- timeout
per-script timeout in seconds
- skip
character vector of
file_names to record asskipped_missing_inputsinstead of running- parses
named logical (by file_name); a file that will not parse is recorded
not_parsedand not run- failed_deps
character vector of package names that
repro_install_deps()could not install (CRAN Archive retry included) — used only to tell apart a script that failed because ITS OWN dependency is genuinely unavailable (dependency_unavailable) from a script that failed for any other reason (errored), so an unavailable package does not read as a bug in the paper's code- deadline
the time (
Sys.time()plus the time for all scripts together) after which no script is started, recorded asskipped_time_limit; a running script is stopped then.NULL(the default) sets no such limit.
Value
a data frame with file_name, outcome (one of ran_ok,
errored, timed_out, not_parsed, skipped_missing_inputs,
dependency_unavailable), error (message or ""), error_type
(undefined_variable, timeout, dependency_unavailable, runtime, or
NA), undefined_var (the missing variable name when
error_type == "undefined_variable", else NA), stdout, stderr,
elapsed (seconds), and script_lines (list-column: the EXECUTED script's
own text, one element per source line — the exact text stdout's echoed
statements were run from, so read_r_output() can match them back to a
line number; empty character(0) for a script that did not run).
Examples
# \donttest{
if (requireNamespace("callr", quietly = TRUE)) {
root <- file.path(tempdir(), "run_demo")
plan <- data.frame(file_name = "analysis.R", target_path = "analysis/analysis.R")
code <- list(analysis.R = c("x <- c(1, 2, 3)", "print(mean(x))"))
run_tbl <- repro_write_scripts(code, list(), plan, root)
res <- repro_run_scripts(run_tbl, order = "analysis.R")
res[, c("file_name", "outcome")]
}
#> [repro] rewriting 'analysis.R' (29 bytes) ...
#> [repro] -> running 'analysis.R' (timeout 600s) ...
#> [repro] <- 'analysis.R' done in 0.5s (ok; stdout 40 chars, stderr 0 chars)
#> file_name outcome
#> 1 analysis.R ran_ok
# }