Skip to content

Preserve renv package sources and derive Bioconductor identities - #127

Merged
andrew merged 2 commits into
git-pkgs:mainfrom
abhinavgautam01:issue-123-renv-package-sources
Oct 28, 2026
Merged

andrew merged 2 commits into
git-pkgs:mainfrom
abhinavgautam01:issue-123-renv-package-sources

Conversation

@abhinavgautam01

Copy link
Copy Markdown
Contributor

Fixes #123

Problem

The renv.lock parser read only Package, Version and Hash. It dropped Source and Repository, so every locked package got a CRAN identity. A package recorded as Bioconductor came out as pkg:cran/BiocGenerics@0.58.1 with an empty source. Consumers could not tell it apart from a CRAN package with the same name. GitHub, local and custom repository packages also picked up a CRAN identity they were never installed from.

Changes

The parser now reads Source, Repository, the Remote* fields and the lockfile's top-level R.Repositories list. It records the source on each dependency and uses it to choose the package identity.

renv source PURL Source
Repository from CRAN pkg:cran/... registry: CRAN
Bioconductor, or a repository such as BioCsoft pkg:bioconductor/... registry: <repository>
Repository from another repository listed in R.Repositories, or a repository URL pkg:cran/...?repository_url=... registry: <repository>
Repository from a repository with no known URL none (NoPURL) registry: <repository>
GitHub none (NoPURL) github: owner/repo
GitLab / Bitbucket none (NoPURL) git: gitlab::owner/repo
git none (NoPURL) git: <RemoteUrl>
URL none (NoPURL) url: <RemoteUrl>
Local none (NoPURL) path: <RemoteUrl>
Unrecognised source none (NoPURL) empty
No source recorded pkg:cran/... empty

Git sources keep RemoteSha in Ref, or RemoteRef when no commit is recorded. RemoteSubdir goes in Rel.

Lockfiles that record no source keep their CRAN identity, so older files parse as before. Version, integrity and Direct: false are unchanged.

The README documents the mapping. The Rel field comment now says "package path" since renv uses it as well as Chef.

Consumer impact

Packages from GitHub, local paths, URLs, unknown repositories or unrecognised sources now have an empty PURL with NoPURL set. They no longer get a CRAN identity. Brief currently skips dependencies with an empty PURL. That needs handling in git-pkgs/brief#214 before Brief adds renv.lock to discovery.

Tests

  • New TestRenvLockSources test goes through the public Parse. It covers mixed CRAN and Bioconductor entries, missing source fields, custom, URL and unknown repositories, every remote type and an unrecognised source. It also checks version, integrity and Direct.
  • The existing TestRenvLock still passes.
  • go build ./..., go vet ./..., go test -race ./... and golangci-lint run all pass.

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, the mapping is right and the test coverage through public Parse is exactly what the issue asked for. One behavioural gap to close before merge.

internal/cran/cran.go:310 — Posit Package Manager repository names fall through to NoPURL. renv stamps packages installed via Posit Package Manager with "Repository": "RSPM" (older) or "PPM" / "P3M" (newer), while the lockfile's top-level R.Repositories list typically names the entry CRAN (pointing at the PPM URL), not RSPM. Example from phuse-org/OSTCDA's renv.lock: R.Repositories is [{Name: CRAN, URL: packagemanager.rstudio.com/...}, {Name: AtorusPackages, ...}] and 6 packages carry "Repository": "RSPM". With this change those hit the default branch of applyRenvRepository and lose their pkg:cran/... identity, which regresses against main for a very common lockfile shape. PPM serves CRAN packages and renv's own restore path treats these names as CRAN, so extend the first case to name == "CRAN" || name == "RSPM" || name == "PPM" || name == "P3M" and add an "RSPM" package to TestRenvLockSources expecting pkg:cran/... with Source{registry, "RSPM"}.

internal/cran/cran.go:256-261 and 298-303 — doc comments narrate the switch. Trim each to the one sentence the code doesn't already say: on applyRenvSource keep only "Entries without a recorded source keep the CRAN identity older lockfiles implied"; on applyRenvRepository keep only "A repository whose URL is unknown has no package identity." The rest restates the case list.

@abhinavgautam01

Copy link
Copy Markdown
Contributor Author

Thanks, both fixed

  • RSPM, PPM and P3M now resolve to pkg:cran/... like CRAN, keeping the recorded name in a registry source. TestRenvLockSources covers all three. The README mentions them too.
  • Trimmed the applyRenvSource and applyRenvRepository doc comments to the sentences you suggested.

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, both landed as asked — RSPM/PPM/P3M now keep their CRAN identity with test coverage for each, and the doc comments are trimmed.

@andrew
andrew merged commit 7777383 into git-pkgs:main Oct 28, 2026
2 checks passed
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.

Preserve explicit package sources in renv lockfiles

2 participants