Skip to content

Fix subscript out of bounds when repos include an R-universe repository - #107

Open
ddsjoberg wants to merge 1 commit into
Genentech:mainfrom
ddsjoberg:fix-106-r-universe-repos
Open

Fix subscript out of bounds when repos include an R-universe repository#107
ddsjoberg wants to merge 1 commit into
Genentech:mainfrom
ddsjoberg:fix-106-r-universe-repos

Conversation

@ddsjoberg

Copy link
Copy Markdown

Fixes #106.

What changed

strip_src_contrib() (R/utils-pkg-source.R) now matches a package's Repository field against each repository's contrib url by prefix instead of equality.

Why

For CRAN-like repositories, available.packages() reports Repository as exactly the contrib url, so contrib.url(repo) == Repository holds. R-universe instead reports it as the full, per-package tarball url:

Repository:     https://<user>.r-universe.dev/src/contrib/<pkg>_<ver>.tar.gz?sha256=...&file=
contrib.url():  https://<user>.r-universe.dev/src/contrib

The equality check never matched, so strip_src_contrib() returned character(0), pkg_origin_repo() stored an empty repos, and at check time get_package_source() indexed an empty available.packages() database:

Error in db[package, ] : subscript out of bounds
Calls: <Anonymous> ... check_path -> check_path.pkg_origin_repo -> get_package_source

Notes for the reviewer

contrib.url() type. The issue suggested utils::contrib.url(r, type = "source"). I deliberately left the default type in place: pkg_origin_repo() reads Repository out of available_packages(repos = repos) at the session's default pkgType, so contrib.url() must use the same type or matching would break for genuine binary repositories (e.g. pkgType = "win.binary", where Repository is .../bin/windows/contrib/4.5). With pkgType = "both" both sides resolve to src/contrib, which is the case in the reported scenario.

get_package_source() needs no change. The issue also suggested rebuilding the archive url or switching to utils::download.packages(). That turns out to be unnecessary — R-universe crafts the Repository field to end in &file= precisely so that appending /<pkg>_<ver>.tar.gz (exactly what download.packages() does internally, and what get_package_source() already did) produces a valid url:

https://ddsjoberg.r-universe.dev/src/contrib/gtsummary_2.6.0.9003.tar.gz?sha256=1b26...&file=/gtsummary_2.6.0.9003.tar.gz

I verified this downloads (1,981,048 bytes) and untars cleanly. basename() of that url is also a clean gtsummary_2.6.0.9003.tar.gz, so fetch_package_source()'s destfile is correct too. Keeping the existing code avoids a behavioural change to the destdir = NULL branch.

Tests

New tests/testthat/test-pkg-source.R:

  • offline unit tests covering both Repository styles, the no-match case, and archive url construction for CRAN-style and R-universe-style Repository fields;
  • a network test (skip_on_cran(), skips if the repos are unreachable) resolving gtsummary end-to-end through pkg_origin_repo()check_path() against https://ddsjoberg.r-universe.dev.

All 7 pass. The rest of the suite is unaffected by this change; the only failures I see locally are pre-existing environment issues (visNetwork not installed, and a NOTE-count difference in test-check.R / test-results-utils.R).

🤖 Generated with Claude Code

R-universe repositories report the `Repository` field of
`available.packages()` as a full, per-package tarball url
(`.../src/contrib/<pkg>_<ver>.tar.gz?sha256=...&file=`) rather than the
plain contrib url that CRAN-like repositories report. Comparing that
field to `contrib.url(repo)` with `==` therefore never matched, so
`strip_src_contrib()` returned `character(0)`, `pkg_origin_repo()`
stored an empty `repos`, and `get_package_source()` failed at check time
with `subscript out of bounds`.

Match by prefix instead, so a per-package tarball url still resolves back
to its originating repository. `contrib.url()` is left at its default
`type`, matching the type `available_packages()` uses to produce the
`Repository` field, so binary repositories keep working.

No change is needed in `get_package_source()`: R-universe crafts the
`Repository` field so that appending `/<pkg>_<ver>.tar.gz` (what
`utils::download.packages()` does, and what `get_package_source()`
already did) yields a valid download url.

Fixes Genentech#106

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subscript out of bounds when repos include an R-universe repository

1 participant