Skip to content

Commit

Permalink
add 'transactional' argument to restore (#1109)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinushey committed Jul 10, 2024
1 parent cb69676 commit 79e3a48
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

# renv (development version)

* `renv::restore()` gains the `transactional` argument, which can be
used to control whether `renv` will allow successfully-installed
packages remain in the project library even if a package fails
to install during a later step. (#1109)

* `renv` now infers a dependency on the `xml2` package for projects
using the `testthat::JunitReporter` for tests. (#1936)

Expand Down
50 changes: 38 additions & 12 deletions R/restore.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,43 @@ the$restore_state <- NULL
#' Restore project library from a lockfile
#'
#' Restore a project's dependencies from a lockfile, as previously generated by
#' [snapshot()]. `renv::restore()` compares packages recorded in the lockfile to
#' [snapshot()].
#'
#' `renv::restore()` compares packages recorded in the lockfile to
#' the packages installed in the project library. Where there are differences
#' it resolves them by installing the lockfile-recorded package into the
#' project library. If `clean = TRUE`, `restore()` will additionally delete any
#' packages in the project library that don't appear in the lockfile.
#'
#' @section Transactional Restore:
#'
#' By default, `renv::restore()` will perform a 'transactional' restore, wherein the
#' project library is mutated only if all packages within the lockfile are successfully
#' restored. The intention here is to prevent the private library from entering
#' an inconsistent state, if some subset of packages were to install successfully
#' but some other subset of packages did not. `renv::restore(transactional = FALSE)`
#' can be useful if you're attempting to restore packages from a lockfile, but would
#' like to update or change certain packages piece-meal if they fail to install.
#'
#' The term 'transactional' here borrows from the parlance of a 'database transaction',
#' where the failure of any intermediate step implies that the whole transaction
#' will be rolled back, so that the state of the database before the transaction
#' was initiated can be preserved. See <https://en.wikipedia.org/wiki/Database_transaction>
#' for more details.
#'
#' @inherit renv-params
#'
#' @param library The library paths to be used during restore. See **Library**
#' for details.
#' @param library The library paths to be used during restore.
#'
#' @param packages A subset of packages recorded in the lockfile to restore.
#' When `NULL` (the default), all packages available in the lockfile will be
#' restored. Any required recursive dependencies of the requested packages
#' will be restored as well.
#'
#' @param transactional Whether or not to use a 'transactional' restore.
#' See **Transactional Restore** for more details. When `NULL` (the default),
#' the value of the `install.transactional` [`config`] option will be used.
#'
#' @param exclude A subset of packages to be excluded during restore. This can
#' be useful for when you'd like to restore all but a subset of packages from
#' a lockfile. Note that if you attempt to exclude a package which is required
Expand All @@ -34,16 +55,17 @@ the$restore_state <- NULL
#' @export
#'
#' @example examples/examples-init.R
restore <- function(project = NULL,
restore <- function(project = NULL,
...,
library = NULL,
lockfile = NULL,
packages = NULL,
exclude = NULL,
rebuild = FALSE,
repos = NULL,
clean = FALSE,
prompt = interactive())
library = NULL,
lockfile = NULL,
packages = NULL,
exclude = NULL,
rebuild = FALSE,
repos = NULL,
clean = FALSE,
transactional = NULL,
prompt = interactive())
{
renv_consent_check()
renv_scope_error_handler()
Expand All @@ -62,6 +84,10 @@ restore <- function(project = NULL,
# set up .renvignore defensively
renv_load_cache_renvignore(project = project)

# set up transactional param
transactional <- transactional %||% config$install.transactional()
renv_scope_options(renv.config.install.transactional = transactional)

# check and ask user if they need to activate first
renv_activate_prompt("restore", library, prompt, project)

Expand Down
31 changes: 28 additions & 3 deletions man/restore.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 79e3a48

Please # to comment.