| name | miniextendr-rv |
| description | Use when R/test setup misbehaves (e.g. `testthat` is "not installed" mid-test, `__rv_R_mismatch` temp library appears, `just devtools-test` skips tests silently, `rv sync` complains, or you need to bump the pinned R version). Also use when adding a new R dependency to the dev workflow, understanding why `library()` works in one shell but not another, or coaching contributors through their first `rig` / `rv` setup for this repo. |
miniextendr R version + dependency management (rv + rig)
This repo pins its R version and dev-dependency set in rproject.toml at the
repo root and uses rv to materialize them into rv/library/<r-version>/<arch>/.
Switching the R on PATH is rig's job. Mismatching the two puts rv into safe
mode and quietly breaks every test recipe.
When to use this skill
- "
testthat not installed" or "no package called 'X'" appears mid-test even though deps look correct.
- Logs contain
WARNING: R version specified in config (4.X) does not match session version (4.Y) or creating temporary library: …/__rv_R_mismatch.
just devtools-test exits 0 but no test summary appears in the log.
rv sync complains about missing or incompatible packages.
- A contributor's
R --version doesn't match rproject.toml's r_version.
- You want to bump the pinned R version (e.g. 4.5 → 4.6 after R-devel ships a release).
- You're adding a new dev/test dependency and need it picked up by everyone.
Layout
rproject.toml # Pin: r_version, repositories, dependencies
rv/
library/<r-version>/<arch>/ # rv-installed packages (gitignored)
scripts/
activate.R # sourced via .Rprofile-style mechanism
rvr.R # rv R-side helpers
.gitignore
rproject.toml fields that matter here:
[project]
name = "miniextendr"
r_version = "4.6"
repositories = [
{alias = "CRAN", url = "https://cloud.r-project.org/"},
]
dependencies = [
{name = "minirextendr", dependencies_only = true, path = "minirextendr"},
{name = "miniextendr", dependencies_only = true, path = "rpkg"},
"testthat",
"devtools",
{name = "roxygen2", url = "https://cran.r-project.org/src/contrib/roxygen2_8.0.0.tar.gz"},
]
dependencies_only = true on the local packages means rv installs their
deps but not the local package itself (we install that via
just rcmdinstall / just minirextendr-install).
The pinned roxygen2_8.0.0.tar.gz URL is intentional — current code targets
roxygen2 8.0.0; the CRAN release moved on and would re-render man pages
differently. The pin is the source of truth in rproject.toml, mirrored by
Config/roxygen2/version: 8.0.0 in rpkg/DESCRIPTION.
The R-version contract (the only thing that goes wrong here)
r_version in rproject.toml must equal R --version on PATH. If they
diverge, rv aborts activation and creates a temporary stub library at
/var/folders/.../__rv_R_mismatch. R then runs against that empty library
and every library(testthat) / library(devtools) fails with
no package called ….
The error you'll see in just devtools-test output:
WARNING: R version specified in config (4.5) does not match session version (4.6.0).
rv library will not be activated until the issue is resolved. Entering safe mode...
creating temporary library: /var/folders/_x/…/__rv_R_mismatch
Error in loadNamespace(x) : there is no package called 'testthat'
Calls: loadNamespace -> withRestarts -> withOneRestart -> doWithOneRestart
Execution halted
The just recipe still exits 0 even though no tests ran. CI catches this
because CI installs R deliberately, but locally it's easy to miss.
How to fix
Pick whichever side reflects reality:
Option A — switch R to match rproject.toml (most common):
rig default 4.6
R --version | head -1
just devtools-test
Option B — bump rproject.toml to match a newer R you've adopted:
sed -i '' 's/r_version = "4.5"/r_version = "4.6"/' rproject.toml
rv sync
just devtools-test
If you choose B, mirror the change in the R version (rv + rig) section of
the root CLAUDE.md so future contributors know the current pin.
rig cheat-sheet (R installer)
rig (the R installation manager, not to be confused with rv) installs
and switches between R versions. Not in this repo — it's a global tool.
rig list
rig default 4.6-arm64
rig add 4.6
rig add 4.5
rig system create-lib
The * next to a rig list row indicates the current default. Subshells
and CI use that R unless they override PATH.
rv cheat-sheet (R-side venv-equivalent)
rv is the project-local dependency manager.
rv info --library --r-version --repositories
rv sync
rv add <pkg>
rv add --no-sync <pkg>
rv remove <pkg>
rv status
The justfile has wrapper recipes for the CRAN corpus workflow (bulk add/remove
of a curated list of CRAN packages used for adapter-tests); for everyday dev
deps just edit rproject.toml and run rv sync.
Adding a new dependency for tests
- Edit
rproject.toml:
dependencies = [
"new-package",
]
rv sync — installs new-package and its deps into rv/library/....
- Commit
rproject.toml. The library directory is gitignored; CI's rv sync
step will recreate it.
If the new package needs a non-CRAN source (pinned URL, git ref, local path),
the toml supports the same syntax as the existing roxygen2:
{name = "roxygen2", url = "https://cran.r-project.org/src/contrib/roxygen2_8.0.0.tar.gz"},
{name = "minirextendr", dependencies_only = true, path = "minirextendr"},
{name = "somelib", git = "https://github.com/org/somelib.git", tag = "v1.2.3"},
Bumping the pinned R version
Trigger: a new R release lands and we want to track it.
rig add <new-version> if you don't have it locally.
rig default <new-version> to switch your session.
- Edit
rproject.toml → r_version = "<new-version>".
- Update the R version (rv + rig) section in the root
CLAUDE.md to
match.
rv sync — rebuilds the library under the new R version.
just devtools-test — confirms the new env is usable end-to-end.
- If you bump R minor versions on CI workflows (e.g.
r-lib/actions/setup-r
with explicit version), update those YAMLs too. The release workflow
template (minirextendr/inst/templates/r-release.yml) currently pins
r-version: release so it auto-tracks; check anyway.
Commit rproject.toml and CLAUDE.md together. The library dir stays
gitignored.
Doctor checks for this skill
R --version | head -1 matches r_version in rproject.toml.
rig list shows the matching version marked *.
which rv resolves; rv info doesn't error.
rv sync exits clean (no missing deps, no version conflicts).
R -e 'find.package("testthat")' resolves under rv/library/<r>/<arch>/,
NOT a path containing __rv_R_mismatch.
If any of these fail, you're in safe mode — see the fix recipes above.
What this skill does NOT cover
- Installing
rv itself or rig itself (both are global / system installs;
see their upstream docs).
- CRAN corpus management (
just bindgen-corpus-add-packages / just bindgen-corpus-remove-packages)
— see comments in justfile.
renv migration — this repo is rv-native and has no renv.lock.
Cross-references
- Root
CLAUDE.md § "R version (rv + rig)" — the abbreviated version of this
doc, intended for first-touch contributors.
rproject.toml (the roxygen2 dependency entry) and
rpkg/DESCRIPTION (Config/roxygen2/version) — the source of truth for the
pinned roxygen2_8.0.0.tar.gz URL.
[[miniextendr-build]] skill — what to do after you've sorted R/rv.