Skip to contents

A 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).

Usage

.repro_redirect_writes(code_text, lang = "R")

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's open(path, "w") is deliberately NOT included in write_fns here even though it is a write call (see .py_open_writes(), which repro_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 (see hit below).

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 on Sys.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.