File: install.R

package info (click to toggle)
r-cran-devtools 2.4.6-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,340 kB
  • sloc: sh: 15; makefile: 5
file content (194 lines) | stat: -rw-r--r-- 7,604 bytes parent folder | download
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)
}