
Detect whether a paper pinned its R/package versions
Source:R/code_check.R
dot-code_version_pin_check.RdChecks a repository's files for the three ways authors commonly pin the
environment their analysis depended on, so a later reproduction attempt
knows which R and package versions were actually used rather than
whatever happens to be current: an renv.lock file (parsed for the R
version and every locked package + its version/source), a sessionInfo()
/ sessioninfo::session_info() text dump (matched by filename, since
authors deposit these as a dedicated file rather than burying them in
unrelated text — see @details), or a groundhog::groundhog.library() /
checkpoint::checkpoint() call in the R code, which pin by date instead of
a lockfile. Static analysis only: this reports what was DECLARED, not
whether the declared versions still install today (that risk is what
repro_install_deps()'s CRAN Archive fallback exists for).
Usage
.code_version_pin_check(
all_files,
code_text_list = list(),
max_file_size = 100,
max_download_size = 500,
cache = FALSE,
skip_on_api_limit = FALSE,
max_files_per_repo = Inf
)Arguments
- all_files
the full repo file listing (
repo_check's table: needsfile_name,file_url,repo_url,file_locationwhere available)- code_text_list
a named list of already-read R file text (names are file_names) — reused for the groundhog/checkpoint scan and for records pasted into scripts, so no file is downloaded or read twice
- max_file_size
passed to
download_repo_files()for any candidate file not yet local- max_download_size
passed to
download_repo_files()- cache
passed to
download_repo_files()- skip_on_api_limit
passed to
download_repo_files()
Value
a list:
pinned (logical, TRUE if any mechanism was found),
mechanisms (character vector, any of
renv.lock, sessionInfo, groundhog, checkpoint),
r_versions (character vector of R version strings found, one per source),
renv_files (character vector of renv.lock file_names found),
renv_packages (data frame file_name, package, version, source,
remote ("user/repo@ref" for a package from GitHub, else NA)
— one row per locked package, across all renv.lock files found),
sessioninfo_files (character vector of matched file_names),
session_packages (data frame with the same columns — one row per package
version the sessionInfo()/session_info() records list),
pin_dates (data frame mechanism (groundhog or checkpoint), date
— one row per distinct date),
python_files (character vector of the file_names of Python package
lists: requirements*.txt, environment.yml, Pipfile(.lock),
poetry.lock, uv.lock, pyproject.toml),
python_pinned (logical, TRUE if any Python package list was found;
pinned stays about R only),
file_location (named character vector, file_name -> resolved local
path, for every candidate file this call downloaded — a caller
re-checking a SUBSET of all_files per paper can splice these back
into its own copy of all_files first, so the same file is never
downloaded twice across repeat calls)
Details
The sessionInfo() scan is filename-gated, not a blanket content scan of
every text file in the repository: it looks at files whose name suggests
they ARE such a dump (sessioninfo/session_info/session-info,
case-insensitive, any extension — the two forms actually seen in a real
corpus are sessionInfo.txt and session_info.txt) plus any readme*
file, since authors sometimes paste the dump into a README instead of a
dedicated file. A blanket scan of every .txt/.md/.log file was
considered and rejected: it would also match a paper's own methods prose
mentioning an R version in a sentence, which is not a pinned-environment
record.
renv.lock is matched by its fixed, case-sensitive filename (that is the
one name renv itself ever writes) and searched for anywhere in the
repository tree, not just the top level — a paper can deposit more than
one (e.g. one per study folder), and all are reported.
groundhog/checkpoint are detected by the PINNING CALL itself
(groundhog.library(pkg, "YYYY-MM-DD"), checkpoint("YYYY-MM-DD")), not
merely library(groundhog)/library(checkpoint): loading the package is
not evidence it was used to pin anything, so a bare library() call does
not count. The date may be held in a variable the same script assigns it
to; a call in a comment does not count.
The packages a sessionInfo() or session_info() record lists are read by
.code_session_packages(). A file that only mentions an R version still
counts as a sessionInfo record, but has no rows in session_packages.
A record pasted into an R script, usually as comments, also counts, but only
when it lists packages: a comment such as "needs R version 4.2.0" does not.