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