1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
#' Install a local development package.
#'
#' Uses `R CMD INSTALL` to install the package. Will also try to install
#' dependencies of the package from CRAN, if they're not already installed.
#'
#' If `quick = TRUE`, installation takes place using the current package
#' directory. If you have compiled code, this means that artefacts of
#' compilation will be created in the `src/` directory. If you want to avoid
#' this, you can use `build = TRUE` to first build a package bundle and then
#' install it from a temporary directory. This is slower, but keeps the source
#' directory pristine.
#'
#' If the package is loaded, it will be reloaded after installation. This is
#' not always completely possible, see [reload()] for caveats.
#'
#' To install a package in a non-default library, use [withr::with_libpaths()].
#'
#' @template devtools
#' @inheritParams remotes::install_local
#' @param reload if `TRUE` (the default), will automatically reload the
#' package after installing.
#' @param quick if `TRUE` skips docs, multiple-architectures,
#' demos, and vignettes, to make installation as fast as possible.
#' @param build if `TRUE` [pkgbuild::build()]s the package first:
#' this ensures that the installation is completely clean, and prevents any
#' binary artefacts (like \file{.o}, `.so`) from appearing in your local
#' package directory, but is considerably slower, because every compile has
#' to start from scratch.
#'
#' One downside of installing from a built tarball is that the package is
#' installed from a temporary location. This means that any source references,
#' at R level or C/C++ level, will point to dangling locations. The debuggers
#' will not be able to find the sources for step-debugging. If you're
#' installing the package for development, consider setting `build` to
#' `FALSE`.
#' @param args An optional character vector of additional command line
#' arguments to be passed to `R CMD INSTALL`. This defaults to the
#' value of the option `"devtools.install.args"`.
#' @param build_vignettes if `TRUE`, will build vignettes. Normally it is
#' `build` that's responsible for creating vignettes; this argument makes
#' sure vignettes are built even if a build never happens (i.e. because
#' `build = FALSE`).
#' @param keep_source If `TRUE` will keep the srcrefs from an installed
#' package. This is useful for debugging (especially inside of RStudio).
#' It defaults to the option `"keep.source.pkgs"`.
#' @param ... additional arguments passed to [remotes::install_deps()]
#' when installing dependencies.
#' @family package installation
#' @seealso [update_packages()] to update installed packages from the
#' source location and [with_debug()] to install packages with
#' debugging flags set.
#' @export
install <-
function(pkg = ".", reload = TRUE, quick = FALSE, build = !quick,
args = getOption("devtools.install.args"), quiet = FALSE,
dependencies = NA, upgrade = "default",
build_vignettes = FALSE,
keep_source = getOption("keep.source.pkgs"),
force = FALSE,
...) {
pkg <- as.package(pkg)
# Forcing all of the promises for the current namespace now will avoid lazy-load
# errors when the new package is installed overtop the old one.
# https://stat.ethz.ch/pipermail/r-devel/2015-December/072150.html
if (reload && is_loaded(pkg)) {
eapply(pkgload::ns_env(pkg$package), force, all.names = TRUE)
}
if (isTRUE(build_vignettes)) {
# we likely need all Suggested dependencies if building vignettes
dependencies <- TRUE
build_opts <- c("--no-resave-data", "--no-manual")
} else {
build_opts <- c("--no-resave-data", "--no-manual", "--no-build-vignettes")
}
opts <- c(
if (keep_source) "--with-keep.source",
"--install-tests"
)
if (quick) {
opts <- c(opts, "--no-docs", "--no-multiarch", "--no-demo")
}
opts <- c(opts, args)
check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn))
remotes::install_deps(pkg$path,
build = build, build_opts = build_opts,
INSTALL_opts = opts, dependencies = dependencies, quiet = quiet,
force = force, upgrade = upgrade, ...
)
if (build) {
install_path <- pkgbuild::build(pkg$path, dest_path = tempdir(), args = build_opts, quiet = quiet)
on.exit(file_delete(install_path), add = TRUE)
} else {
install_path <- pkg$path
}
was_loaded <- is_loaded(pkg)
was_attached <- is_attached(pkg)
if (reload && was_loaded) {
pkgload::unregister(pkg$package)
}
pkgbuild::with_build_tools(required = FALSE,
callr::rcmd("INSTALL", c(install_path, opts), echo = !quiet, show = !quiet, spinner = FALSE, stderr = "2>&1", fail_on_status = TRUE)
)
if (reload && was_loaded) {
if (was_attached) {
require(pkg$package, quietly = TRUE, character.only = TRUE)
} else {
requireNamespace(pkg$package, quietly = TRUE)
}
}
invisible(TRUE)
}
#' Install package dependencies if needed.
#'
#' `install_deps()` will install the
#' user dependencies needed to run the package, `install_dev_deps()` will also
#' install the development dependencies needed to test and build the package.
#' @inheritParams install
#' @inherit remotes::install_deps
#' @export
install_deps <- function(pkg = ".",
dependencies = NA,
repos = getOption("repos"),
type = getOption("pkgType"),
upgrade = c("default", "ask", "always", "never"),
quiet = FALSE,
build = TRUE,
build_opts = c("--no-resave-data", "--no-manual", " --no-build-vignettes"),
...) {
pkg <- as.package(pkg)
check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn))
remotes::install_deps(
pkg$path,
dependencies = dependencies,
repos = repos,
type = type,
upgrade = upgrade,
quiet = quiet,
build = build,
build_opts = build_opts,
...
)
}
#' @rdname install_deps
#' @export
install_dev_deps <- function(pkg = ".",
dependencies = TRUE,
repos = getOption("repos"),
type = getOption("pkgType"),
upgrade = c("default", "ask", "always", "never"),
quiet = FALSE,
build = TRUE,
build_opts = c("--no-resave-data", "--no-manual", " --no-build-vignettes"),
...) {
remotes::update_packages("roxygen2")
pkg <- as.package(pkg)
check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn))
remotes::install_deps(
pkg$path,
dependencies = dependencies,
repos = repos,
type = type,
upgrade = upgrade,
quiet = quiet,
build = build,
build_opts = build_opts,
...
)
}
local_install <- function(pkg = ".", quiet = TRUE, env = parent.frame()) {
pkg <- as.package(pkg)
cli::cli_inform(c(i = "Installing {.pkg {pkg$package}} in temporary library"))
withr::local_temp_libpaths(.local_envir = env)
install(pkg, upgrade = "never", reload = FALSE, quick = TRUE, quiet = quiet)
}
|