
Find a script's WRITE calls and redirect their targets into the sandbox
Source:R/reproducibility_check.R
dot-repro_redirect_writes.RdA script writes intermediate/output files by relative path
(write.csv("../Data/Cleaned/x.csv", ...), saveRDS(m, "out/model.rds")).
repro_rewrite_paths() only ever rewrites READ calls (code_file_refs()'s
include_writes defaults to FALSE there) — a write's own path is left
exactly as the author wrote it, so when the materialised sandbox's directory
layout does not match the original repo's (it is Psych-DS's layout, not the
author's), the write's target directory frequently does not exist at all,
and the write fails with "cannot open the connection" — a sandboxing
artefact, not a real reproducibility finding, confirmed against a real
corpus paper whose script wrote to "../Data/Cleaned/..." (a path that only
resolves relative to the AUTHOR's own original working directory).
Arguments
- code_text
the code text for a single file (character vector)
- lang
"R"(default) or"Python"— selects the write-function names matched, and (for the path-like-variable scan) the assignment operator recognised: R's<-/<<-/=vs. Python's=only. Python'sopen(path, "w")is deliberately NOT included inwrite_fnshere even though it is a write call (see.py_open_writes(), whichrepro_file_io()uses):open()returns a file HANDLE, not the path itself — the call that actually names the path to redirect — so this function instead matches the handle variable's own.write(...)/.writelines(...)calls is out of scope for a text-level, no-interpreter rewrite (which handle a later.write()belongs to is not recoverable without actually running the code);open()is left unredirected here and any relative-path failure surfaces as a plain execute-time error instead, same as any other unresolved reference this function already leaves alone (seehitbelow).
Value
a data frame with one row per detected write call: call_text (the
full original call), replacement (the full replacement call text, or
NA when unresolved), redirected_name (the basename the write now
targets, for the read-side basename search to also check), and line
(1-based line the call starts on). Empty frame when the script has no
resolvable write calls.
Details
Every detected write call is redirected to file.path(output_dir, basename(...)) — a single flat folder inside the sandbox that
repro_materialize_layout() always creates, so the write always succeeds
regardless of the original relative structure. Two call shapes are handled:
a LITERAL quoted target (
write.csv("cleaned.csv", ...)) — redirected directly, keeping the literal's own basename;a BARE VARIABLE target (
write.csv(cleaned_file_name, ...), the variable assigned on an earlier line, e.g.cleaned_file_name <- paste0("../Data/ Cleaned/task_level_", Sys.Date(), ".csv")) — the ENTIRE write call is replaced with a fixed literal path, using the VARIABLE's own name (not its unknowable runtime value, which may depend onSys.Date()or other non-literal pieces this scan cannot evaluate) plus the extension its assignment's own last quoted segment declares. This does not need to resolve the variable's exact string value — only that its assignment LOOKS like a file path (ends.<ext>in its last quoted piece) — so it still succeeds even when a placeholder (Sys.Date()) makes the true runtime value unknowable ahead of time.
A write whose target cannot be traced to a literal or a simple top-level
assignment (built from a loop variable, a function argument, a data value)
is left UNREWRITTEN, the same "do not guess" policy
repro_rewrite_paths() already follows for reads.