-
renv::install()andrenv::restore()with pak enabled can now handle
packages hosted on a self-hosted GitLab instance. renv previously handed
pak remotes of the formgitlab@<host>::<group>/<project>, which pak was
unable to parse; renv now translates these into pkgdepends' own syntax,
gitlab::https://<host>/<group>/<project>. GitLab sub-directories are
likewise translated to pkgdepends'/-/<subdir>syntax. (#2180) -
When a package fails to download, renv now reports the reason for the
failure, rather than a generic "failed to download" message. For example,
when the download destination within the renv root is not writable (as can
happen with a misconfigured shared cache), the error now says so directly.
(#2340) -
Failed package downloads are now reported quietly when a later retrieval
candidate succeeds -- for example, when a binary package fails to download,
but the source fallback succeeds. If all candidates fail, the download
output is still emitted, and download errors are no longer reported twice.
(#1727) -
renv::use()with pak enabled now honours the requested remotes, rather than
installing the latest version of each package from the active repositories.
Previously, a call likerenv::use("generics@0.1.3")would install the
current CRAN version of generics.renv::rebuild()andrenv::repair()were
affected in the same way. (#2341) -
renv::remove()gains apromptargument, and now asks for confirmation
before removing packages from a library other than the project library --
for example, when called without an activated renv project, where the
target library would be the user library. (#2331) -
Removing a package record from the lockfile by setting it to
NULL, e.g.
withrenv::record(list(dplyr = NULL)), is now documented. (#2331) -
Package projects can now request that the package itself be included in the
lockfile, by settingConfig/renv/snapshot/include-self: TRUEin the package
DESCRIPTIONfile. This can be useful when deploying a Shiny application
that is developed as part of a package. See?renv::snapshotfor more
details. (#2285) -
renv::dependencies()now detects packages referenced via
rlang::check_installed()andrlang::is_installed(). (#1936) -
renv::dependencies()now infers the optional packages required by certain
testthat functions; for example,skip_if_offline()implies a dependency on
curl, andsnapshot_review()implies dependencies on shiny and diffviewer.
In addition, usage of the Junit reporter is now also detected in calls to
test_check()andtest_local(). (#1936) -
renv::dependencies()now detects a dependency on the ragg package when the
ragg_pnggraphics device is requested via knitr chunk options set in a
document's YAML header. Previously, only calls of the form
knitr::opts_chunk$set(dev = "ragg_png")in code chunks were detected.
(#2311) -
renv::install()with pak enabled no longer upgrades already-installed
dependencies that are only pulled in transitively -- most visibly recommended
packages such asclusterorMatrix, which previously could be rebuilt when
installing an unrelated package. renv now passesupgrade = FALSEto pak,
matching renv's own installer, while still forcing a (re)install of the
packages you explicitly request. (#2329) -
Internal DESCRIPTION reads that request a package by name now error when that
package is not installed, rather than silently falling back to the DESCRIPTION
in the current working directory. (#2327) -
renv now guards against corrupted cache entries that contain the wrong
package. Before installing a package from the cache, renv verifies that the
cache entry'sDESCRIPTIONreports the expected package name; if it does not
(for example, due to a concurrent write race on a shared cache), renv ignores
the entry and reinstalls the package instead of installing the wrong one.
renv::diagnostics()also reports any such cache entries. (#2322) -
renv's file locks now record the host and process that own them. A lock held
by a process that is still alive on the same machine is no longer treated as
orphaned, even if its timestamp is stale (for example, when a large package
copy onto a shared cache takes longer than the lock timeout and the watchdog
is not refreshing the lock). This reduces the chance of a lock being stolen
from a live process, which could otherwise corrupt a shared cache. (#2322) -
renv::rehash()now reminds you to runrenv::repair()when it moves
packages within the active cache, since project libraries that still link to
a package's previous cache location are left with broken links. The
function's documentation has also been corrected: it no longer claims that
links to the old locations are retained. -
When
renv::snapshot()aborts due to a pre-flight validation failure, the
error now includes a summary of the problems that were detected (for example,
the missing packages or unsatisfied dependencies). Previously these details
were only printed to the console, so they could be lost when that output was
not visible (such as when stdout is captured). -
The new
lockfile()function provides a generic entry point for creating an
renv lockfile from a variety of sources. For example,
lockfile(from = "manifest.json")converts a Posit Connectmanifest.json
file into a lockfile. Supplytoto also write the result to disk, as in
lockfile(from = "manifest.json", to = "renv.lock"). The set of supported
sources may be expanded in future releases. (#2245) -
renv::snapshot()gains adescriptionparameter, which converts a package
DESCRIPTION(provided either as a named list of fields, or as a path to a
package directory orDESCRIPTIONfile) into a single lockfile record,
without requiring the package to be installed. This allows tools like
rsconnect to perform manifest-to-lockfile conversion using exported renv
APIs. (#2250) -
When resolving the dependencies of a pinned package version that is absent
from the configured repositories'PACKAGESmetadata and cannot be found via
crandb (for example, when offline, when using an internal mirror that cannot
reachcrandb.r-pkg.org, or for non-CRAN packages), renv now downloads the
archived source tarball for that version and reads itsDESCRIPTIONdirectly.
This is authoritative wherever the package itself is reachable, and the
downloaded tarball is reused by the subsequent retrieve step. As a last
resort, if the archived tarball also cannot be read, renv falls back to the
latest version's dependencies and warns, since those dependencies may differ
from the pinned version's and could lead to an incorrect install order.
(#2315) -
Fixed a regression introduced in renv 1.2.0 where installing a package from
the cellar (viainstall()oruse()) failed to install that package's
dependencies. The graph-based installer resolved cellar packages from
metadata that omitted theirDepends/Imports/LinkingTofields; renv
now reads the package'sDESCRIPTIONfrom the cellar archive so that its
dependencies are discovered and installed. (#2313) -
renv now infers some "implied" dependencies that cannot be discovered via
static analysis because they are loaded indirectly at runtime by another
package. For example, dplyr lazily loads dbplyr when working with a database
backend, so dbplyr is now recorded when a project uses both dplyr and a DBI
backend (e.g. RSQLite, RPostgres, duckdb). The rules are configurable via the
renv.dependencies.impliedR option; set it to an empty list to disable this
inference entirely. (#2308) -
renv::restore()gains aretryargument, controlling whether packages
that fail to install successfully are retried with their latest available
versions. This recovery was previously only offered via an interactive
prompt;retry = TRUEnow enables it without prompting (useful in
non-interactive sessions such as CI), whileretry = FALSEdisables it
entirely. (#1893) -
renv no longer treats the mere presence of a
biocViewsfield in a
package'sDESCRIPTIONas proof that the package came from Bioconductor.
Some CRAN packages declarebiocViews, and Posit Package Manager can serve
Bioconductor packages from a CRAN-like "R repository"; in both cases renv
now uses theRepositoryfield to decide where a package was obtained, so
such packages are recorded as repository packages and restored from the
repository they came from. Genuine Bioconductor packages are still recognized
by theirRepositorystamp, including binaries served via r-universe
(stamped with ahttps://bioc-*.r-universe.devURL); and when a package has
noRepositorystamp at all (as for bioconductor.org binaries, or very old
or source-installed packages), renv trusts thebiocViewsfield. (#2128) -
A new project setting,
settings$bioconductor.enabled(), can be set to
FALSEto opt a project out of Bioconductor entirely. When disabled, renv
will not infer a Bioconductor source, activate Bioconductor repositories, or
write a Bioconductor entry into the lockfile. (#2128) -
renv's internal DCF and properties readers now match their (ASCII)
regular expressions withuseBytes = TRUE. This avoids forcing PCRE
into UTF mode, which could fail with "this version of PCRE is compiled
without UTF support" -- in some environments preventing renv from even
loading -- when R is linked against a PCRE library lacking UTF support
or left in a state where it believes UTF is unsupported. -
renv::install(<package>, type = "source")once again installs from
source when a binary Posit Package Manager (PPM) repository is
configured. Previously, the dependency graph was resolved against the
un-transformed (binary) repository URL, so a binary package could be
installed even though source was requested. (#2303) -
The presence of an
rsconnect/folder in a project is now treated as a
development dependency on thersconnectpackage, rather than a runtime
dependency. This meansrsconnectwill no longer be automatically
recorded byrenv::snapshot()unless the project actually uses it at
run time (orsettings$snapshot.dev(TRUE)is set). (#2290) -
renv::install()no longer treats a package as already installed when
its namespace is loaded from a path that is no longer on.libPaths()
(e.g. when a global~/.Rprofileloads the package before renv
activates). Previously,install()would silently skip these packages
andsnapshot()could not record them, leaving the project stuck.
(#2300) -
On project load, renv now warns when one or more package namespaces
have already been loaded from a path outside the active library
paths. Such packages are not managed by renv and can cause
renv::status()andrenv::snapshot()to report inconsistencies.
The check can be disabled via thenamespaces.checkconfig option
(or theRENV_CONFIG_NAMESPACES_CHECKenvironment variable). (#2300)