Scripts in a repository usually depend on each other: a preparation script
writes a file a later analysis script reads, or one source()s another.
Running them in the wrong order fails for reasons that have nothing to do with
reproducibility, so a run must order them first. This derives an order from
three signals, in decreasing strength:
Arguments
- files
a data frame with one row per code file, columns
file_name, andreads/writes/sourceslist-columns of basenames (as produced byrepro_file_io()). Whenreads/writes/sourcesare absent they are derived from acode_textlist-column if present. An optionalfile_pathcolumn holds each file's path, and an optionalsource_refslist-column eachsource()reference as written, in the order ofsources: when several files share the name asource()call gives, these decide which one it means, and if they cannot, no edge is added.- extra_edges
a list of
c(from_file_name, to_file_name)pairs, orNULL(default). Each pair adds the rule that the filefrom_file_nameruns before the fileto_file_name, such as when an error about an undefined variable shows that the file defining it must run first.
Value
a data frame with columns file_name, order (1-based run
position, NA when unplaceable), depends_on (comma-joined file_names that
must run earlier), and order_basis (dependency, numeric, or none).
Attribute "cycle" is a character vector of file_names in a dependency
cycle (empty when acyclic); attribute "ambiguous" is TRUE when no ordering
signal placed a multi-file set (they share order = NA, basis none).
Attribute "fuzzy_sources" is a data frame (from, to) of source()
edges that only resolved after normalising both basenames (a renumbered/
reworded script reference — see .repro_normalize_basename()), empty
when every source() reference matched an exact basename. Attribute
"source_edges" is a data frame (from, to) of every resolved
source() edge, exact or fuzzy: from is the sourced file, to the
file that sources it.
Details
read-after-write — if file A's code writes
x.csvand file B's code readsx.csv, A must precede B (hard data dependency);numeric filename prefixes —
0_prep.Rbefore1_analysis.R(a weak tie-breaker, not a dependency).
The read/write and source references come from the shared static analysis
(code_file_refs() and a source scan); matching is by basename (as
elsewhere). The dependency graph is topologically sorted; a cycle (A reads a
file B writes and vice versa) cannot be ordered and is reported.
Examples
files <- data.frame(file_name = c("1_analysis.R", "0_prep.R"))
files$reads <- list("clean.csv", character(0))
files$writes <- list(character(0), "clean.csv")
files$sources <- list(character(0), character(0))
repro_run_order(files)
#> file_name order depends_on order_basis
#> 1 1_analysis.R 2 0_prep.R dependency
#> 2 0_prep.R 1 numeric
