-
renv now quotes the URL, ref, and commit of a git record when passing them
togit, and rejects records whose valuesgitcould read as an option
(for example, a ref of--upload-pack=<command>) or as a request to run a
transport helper. Previously, a crafted lockfile record orgit::remote
could have these values run as shell commands. (#2389) -
Fixed an error when detecting the Posit Package Manager platform on an
Enterprise Linux distribution whose/etc/os-releasedeclares an empty
VERSION_ID; renv now falls back to the untransformed repository URL.
(#2386) -
A trailing YAML comment on the
engine:field of a Quarto document's header
(for example,engine: knitr # comment) no longer prevents renv from
inferring that the document is bound to knitr. (#2386) -
renv::restore(retry = TRUE)(and the interactive retry prompt) now keeps
the packages which installed successfully in the first pass when the restore
is transactional. Previously, the transactional rollback of the first pass
discarded those packages, but the retry only re-installed the packages which
had failed, leaving the library incomplete. A transactional rollback is now
also reported as such, rather than as a successful installation, and
renv::install()no longer lists rolled-back packages among the packages
which failed to install. (#2380) -
renv::restore()once again ignores lockfile records for packages built
for a different operating system (for example, a Windows-only package in a
lockfile restored on Linux), rather than reporting them as failed installs.
With a transactional restore, such a failure previously rolled back the
entire restore. (#2380) -
renv::hydrate()(and sorenv::init()) now installs packages
non-transactionally, so a package that cannot be installed no longer causes
the other packages being hydrated to be rolled back. (#2380) -
On Windows,
renv::install()andrenv::restore()no longer let profiles
named byR_PROFILEorR_PROFILE_USERbe sourced by theR CMD INSTALL
processes they launch. Before R 4.3.0,R CMDdid not honor--vanilla
for those processes, so a profile which reset.libPaths()(as callr's
does, e.g. when renv is run under rcmdcheck) could hide already-installed
dependencies from the installer, causing installs to fail with
"dependency is not available". (#2380) -
On Windows, the output reported for a failed package installation now
includes whatR CMD INSTALLwrote to stderr, which is where it reports
the reason for the failure (for example, "dependency 'x' is not available").
Previously, only stdout was captured, so such failures were reported with
no output at all. (#2385) -
HEADrequests made with thewgetdownload method now work. The request
omitted the URL, and relied on shell redirection to capture the response
headers, which was ignored on Windows; the headers wget reports are also
now parsed correctly. (#2385) -
renv::install()now records the commit (RemoteSha) that a package was
installed from when using thegit::remote pathway, so that
renv::snapshot()pins that package to the installed commit, and
renv::restore()retrieves that same commit rather than whatever the
recorded ref points at when the project is restored (including when pak is
enabled). Restoring a git package from a lockfile written by an older
version of renv, which has noRemoteSha, likewise records the commit that
was installed, so the nextrenv::snapshot()pins it; until then, the
installed package is treated as satisfying the lockfile's record, rather
than being reported as a change. If a git server refuses to serve a pinned
commit directly, renv now fetches the recent history of the recorded ref
instead (deepening it as needed), and checks out the commit from there. In
addition,renv::install(),renv::restore(),renv::hydrate(),
renv::update(), andrenv::record()now clone a given commit at most
once, rather than up to three times, and remove those clones once they
complete. (#2378) -
With pak enabled, installing a package from a sub-directory of a git
repository now reports that pak does not support this, rather than asking
pak to install from the repository's root. (#2378) -
renv::update()now checks for updates to packages that renv installed
fromgit::remotes; previously, these packages were skipped. For git
packages, it also now resolves a ref to the commit that git itself would
fetch, rather than to any ref whose name ends with it (e.g.feature/main
formain), and reports refs that no longer exist as errors. Packages
installed from an annotated tag by remotes are no longer reported as out
of date, and git packages with no recorded commit are only reported as out
of date if a newer version is available. (#2378) -
Version constraints declared in the project's
DESCRIPTIONfile (for
example,Imports: dplyr (>= 1.1.0)) are now honored byrenv::install()
and validated byrenv::snapshot(). Previously, these constraints were
only used when they pinned an exact version with==; other constraints
were silently ignored, so an installed dependency could be older than
the version the project declared it required. Versions pinned by the
lockfile duringrenv::restore(), or requested explicitly via
pkg@version, or declared in the project'sRemotesfield, are never
overridden by these constraints; renv reports the unmet constraint
instead. When renv retrieves packages one at a time (for example, in
renv::upgrade()), it also now reports whenever it replaces a package
version that didn't satisfy the constraints of other packages, rather
than only when that package was explicitly requested.!=constraints
are now parsed as well. (#2377) -
renv::dependencies()now follows Quarto's engine-binding rules when
inferring dependencies for.qmddocuments. Documents bound to the knitr
engine, whether via R chunks, an explicitengine: knitrdeclaration, or
knitr:options in the YAML header, infer a dependency onrmarkdown, and
additionally onreticulatewhen they contain Python chunks. Documents
bound to another engine (for example,engine: jupyter) no longer infer a
dependency onrmarkdown. (#2174) -
renv::restore()now resolves the dependencies of a package installed from
r-universe using the git commit recorded in the lockfile (via theRemoteUrl
andRemoteShafields) when the recorded version is no longer available
from the repository. Previously, the dependencies of the latest version were
used instead, which could cause packages to be installed in the wrong order
or force other locked packages to be upgraded. (#2370) -
renv now falls back to its R implementations, with a warning, if its
compiled extensions exist but cannot be loaded. For example, when a binary
package accidentally ships a shared library built for a different
architecture. (eddelbuettel/r2u#162) -
renv::restore()can now restore Bioconductor packages whose recorded
version is no longer available from the Bioconductor repositories. This is
most often seen with the devel branch of Bioconductor, which does not archive
superseded package versions. In such cases, renv now retrieves the package
sources from the git commit recorded in the lockfile (via thegit_urland
git_last_commitfields), and installs the package from those. (#2370) -
Staged package installations now use the project library root by default.
This allows projects on network drives to retain cache junctions on Windows
when their libraries and cache are stored locally. Installs into a different
library stage within that library, andRENV_PATHS_LIBRARY_STAGINGcontinues
to override the staging location. (#2368) -
The large-file-count warning during
renv::dependencies()now accounts
for whether an.renvignorefile already exists, and suggests modifying it
instead of creating one. (#2193, @jkylearmstrong) -
When bootstrapping renv from GitHub, errors while extracting the commit SHA
from the downloaded archive are now reported without aborting the bootstrap
process. Installation is attempted without adding GitHub metadata.
(#2366, @jkylearmstrong) -
renv::update()no longer tries to fork the R session when checking
packages installed from non-CRAN remotes within Positron, whose R kernel
forbids forking. Such checks now run sequentially there, as they already do
on Windows. (#2364) -
renv::dependencies()no longer emits encoding warnings when checking R
script headers containing non-ASCII text in a different encoding from the
current locale. This also avoids failures when warnings are treated as
errors. (#2362) -
Fixed an issue where renv computed the wrong Posit Package Manager binary
URL on some Enterprise Linux distributions. CentOS Stream 9 and 10 were
mapped to the non-existentcentos9andcentos1platforms rather than
rhel9andrhel10, and Rocky Linux 10 and AlmaLinux 10 were mapped to
rhel1rather thanrhel10, causing package downloads to fail with 404
errors. (#2354) -
Fixed an issue where renv would busy-wait, consuming an entire CPU core,
while waiting to acquire a lock. The retry loop's backoff had become
unreachable, so renv retried as fast as it could rather than at the intended
0.2s interval. In addition, when the lock path was not writable at all (for
example, under an OS sandbox denying writes outside the project), the loop
had no terminating condition and renv would hang indefinitely -- silently,
and uninterruptibly when reached viarenv/activate.Rduring startup. renv
now backs off between attempts, and reports an error (including the reason
reported by the operating system) when the lock path cannot be written.
(#2358) -
Fixed an issue where, with the
renv.install.allowArchivedPackagesoption
enabled, a package available only from a repository's archive would resolve
to nothing at all. The archive was queried, but the result was then
discarded: the lookup only ever returned the repository or crandb candidate.
Archived candidates are now used when neither of those can supply the
package. Records resolved this way also carry the URL of the repository's
archive, so they can be downloaded in the same parallel batch as everything
else, and they retain their repository even whengetOption("repos")is
unnamed. Their archivedDESCRIPTIONis read before dependency resolution,
so strong dependencies are not omitted, and binary-only requests continue
to reject these source-only candidates. (#2356) -
The available-package lookup now stops at the first source that can supply
the package, rather than querying every source and discarding the extra
answers. Repositories still take precedence over P3M, crandb, and the archive,
so renv no longer makes fallback requests whose results it cannot use.
(#2357) -
On Windows and macOS, the available-package lookup once again consults the
P3M historical-binary database when configured repositories have no
candidate. P3M binaries are preferred over crandb version hints and enabled
repository archives, while source-only requests do not consult P3M. Missing
records for newer R or platform versions are treated as an ordinary miss
while the database catches up. (#2360) -
Fixed an issue where
renv::sysreqs()(and the system requirement checks
performed during install and restore) would only report the first system
package required by an R package. When a package'sSystemRequirements
field declared multiple system libraries -- for example,raggdeclares
freetype2, libpng, libtiff, libjpeg, and libwebp -- only the first matching
system dependency was reported. All matching dependencies are now reported.
(#2352) -
Fixed an issue where, if one or more repositories could not be queried for
available packages, the partial result would be cached and served for up to
an hour -- renv would behave as though the failed repositories held no
packages at all, without reporting why. Partial results are no longer
cached, so failed repositories are re-queried (and failures re-reported)
on subsequent calls. Similarly, failed archive queries (used when the
renv.install.allowArchivedPackagesoption is enabled) are no longer
cached, as the failure may be transient; such queries are still only
attempted once per operation. (#2350) -
When the
renv.config.crandb.enabledoption is set, renv now prefers the
record from the active repositories whenever those repositories can supply
the package, rather than taking whichever of the two reports the newer
version. crandb is not restricted to the active repositories, so it could
name a version they don't carry -- for example, when they're pinned to a
dated snapshot such ashttps://p3m.dev/cran/2025-03-28. renv now consults
crandb only when the active repositories have no candidate at all, which is
the case it was added to handle: finding a version compatible with an older
version of R. (#2345) -
Fixed an issue where renv would warn that a package "was loaded before renv
activated this project" when no such thing had happened. Projects using
Bioconductor were affected on every startup, as renv loadsBiocManager
itself when resolving Bioconductor repositories. The check also mistook
packages linked into the project library from the renv cache for packages
loaded from outside the library paths. (#2344) -
renv::install()andrenv::restore()no longer build a package from source
when a binary of the requested version is available, in cases where the
active repositories are pinned to a dated snapshot (for example, a Posit
Package Manager URL likehttps://p3m.dev/cran/2025-03-28) and the
renv.config.crandb.enabledoption is set. renv consulted crandb to find the
newest version of the package, but because crandb is not restricted to the
configured repositories, it could report a version those repositories don't
provide -- and renv then fell back to installing from source. (#2345)