
Find file paths built at runtime with sprintf()/paste()/paste0()/file.path()
Source:R/reproducibility_check.R
dot-repro_format_call_refs.RdA path is sometimes not written as a literal string but assembled from
variables — read_csv(sprintf("%s/%s/x.csv", wd, wd_data)). This is fragile
authoring (it silently breaks whenever the code runs from a different
working directory than the author's own), and it also defeats
code_file_refs()'s literal-string extraction: the "reference" it returns
is really the RAW FORMAT STRING ("%s/%s/x.csv", placeholders and all), so a
naive substring replacement of that text later corrupts the call — the
surrounding sprintf(...) keeps its now-meaningless trailing arguments,
, wd, wd_data), uselessly attached after the plan's target path was
spliced in as if it were the whole first argument.
Value
a data frame with call_text (the full matched call, e.g.
sprintf("%s/%s/x.csv", wd, wd_data)), fmt (the raw format string),
resolved (the format string with resolvable placeholders substituted, or
NA if any placeholder could not be resolved), and line (1-based line
number the call starts on). Empty frame when the script has no such calls.
Details
This finds every such call in a script, and reports enough to fix it
properly: the call's own full text (so the whole expression, not just the
quoted substring, can be replaced), the raw format string, and — when every
placeholder's corresponding argument is a simple variable resolvable to a
literal string via .repro_simple_string_vars() — the format string with
those values substituted in, which is what basename-matching should key on
instead of the placeholder-laden original.
Only %s/%d placeholders (the common case in practice; a sprintf with a
width/precision modifier like %05d is deliberately out of scope, since a
zero-padded numeric ID is unlikely to appear in a bare data-file reference)
are substituted; anything else in the format leaves that call unresolved
(returned with resolved = NA), never guessed. The arguments after the
format string are split on a plain comma, so an argument that is ITSELF a
call containing a comma (sprintf("%s.csv", paste0(a, b))) is not split
correctly either — this only means that argument then fails to resolve to
any known variable (falling back to resolved = NA, the same safe
unresolved outcome as any other unrecognised argument), never a wrong guess.