From ef928884820a6c2dfa2ecd892faa78deb3bf019e Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Tue, 28 Aug 2018 15:54:15 -0400 Subject: [PATCH 1/4] Pass all authentication and build arguments to dependencies We now pass all authentication arguments and build arguments to remotes and dependencies. This means you can supply the authentication in in the top level `install_()` call and have that same authentication be used in downstream Remotes. This also should propagate upgrade to dependencies appropriately, so setting `upgrade = FALSE` should disable upgrading for all dependencies, even grandchildren. Fixes #53 Fixes #86 Fixes #87 --- NEWS.md | 3 +++ R/deps.R | 18 +++++++----------- R/install-bitbucket.R | 4 ++-- R/install-github.R | 4 ++-- R/install-gitlab.R | 2 +- R/install-svn.R | 2 +- R/install.R | 13 ++++++++++--- man/install_deps.Rd | 8 +++++++- man/package_deps.Rd | 6 +++--- 9 files changed, 36 insertions(+), 24 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6fccb13a..67ad350c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,9 @@ # Development +* `install_()` functions now pass arguments, including authentication + information and upgrade down to dependencies (#53, #86, #87). + * `install_()` functions now return the name of the package(s) which were installed (#55). diff --git a/R/deps.R b/R/deps.R index 3e27c0e6..402da0d5 100644 --- a/R/deps.R +++ b/R/deps.R @@ -111,7 +111,7 @@ local_package_deps <- function(pkgdir = ".", dependencies = NA) { dev_package_deps <- function(pkgdir = ".", dependencies = NA, repos = getOption("repos"), - type = getOption("pkgType")) { + type = getOption("pkgType"), ...) { pkg <- load_pkg_description(pkgdir) repos <- c(repos, parse_additional_repositories(pkg)) @@ -129,7 +129,7 @@ dev_package_deps <- function(pkgdir = ".", dependencies = NA, combine_deps( package_deps(deps, repos = repos, type = type), - remote_deps(pkg)) + remote_deps(pkg, ...)) } combine_deps <- function(cran_deps, remote_deps) { @@ -280,11 +280,7 @@ update.package_deps <- function(object, ..., quiet = FALSE, upgrade = TRUE) { install_packages <- function(packages, repos = getOption("repos"), type = getOption("pkgType"), ..., - dependencies = FALSE, quiet = NULL, - # These are options to `install()` used when - # installing remotes, but can get passed to us by - # `...` so we just ignore them here - build, build_opts) { + dependencies = FALSE, quiet = NULL) { if (is.null(quiet)) quiet <- !identical(type, "source") @@ -381,7 +377,7 @@ fix_repositories <- function(repos) { repos } -parse_one_remote <- function(x) { +parse_one_remote <- function(x, ...) { pieces <- strsplit(x, "::", fixed = TRUE)[[1]] if (length(pieces) == 1) { @@ -397,7 +393,7 @@ parse_one_remote <- function(x) { fun <- get(paste0(tolower(type), "_remote"), envir = asNamespace("remotes"), mode = "function", inherits = FALSE) - res <- fun(repo) + res <- fun(repo, ...) }, error = function(e) stop("Unknown remote type: ", type, "\n ", conditionMessage(e), call. = FALSE) ) res @@ -412,13 +408,13 @@ split_remotes <- function(x) { } -remote_deps <- function(pkg) { +remote_deps <- function(pkg, ...) { if (!has_dev_remotes(pkg)) { return(NULL) } dev_packages <- split_remotes(pkg[["remotes"]]) - remote <- lapply(dev_packages, parse_one_remote) + remote <- lapply(dev_packages, parse_one_remote, ...) package <- vapply(remote, remote_package_name, character(1), USE.NAMES = FALSE) installed <- vapply(package, local_sha, character(1), USE.NAMES = FALSE) diff --git a/R/install-bitbucket.R b/R/install-bitbucket.R index 9cb883ee..d582e99d 100644 --- a/R/install-bitbucket.R +++ b/R/install-bitbucket.R @@ -38,10 +38,10 @@ install_bitbucket <- function(repo, ref = "master", subdir = NULL, remotes <- lapply(repo, bitbucket_remote, ref = ref, subdir = subdir, auth_user = auth_user, password = password, host = host) - install_remotes(remotes, ...) + install_remotes(remotes, auth_user = auth_user, password = password, host = host, ...) } -bitbucket_remote <- function(repo, ref = NULL, subdir = NULL, +bitbucket_remote <- function(repo, ref = "master", subdir = NULL, auth_user = NULL, password = NULL, sha = NULL, host = NULL) { diff --git a/R/install-github.R b/R/install-github.R index e9718630..cfeab08c 100644 --- a/R/install-github.R +++ b/R/install-github.R @@ -47,10 +47,10 @@ install_github <- function(repo, remotes <- lapply(repo, github_remote, ref = ref, subdir = subdir, auth_token = auth_token, host = host) - install_remotes(remotes, ...) + install_remotes(remotes, auth_token = auth_token, host = host, ...) } -github_remote <- function(repo, ref = NULL, subdir = NULL, +github_remote <- function(repo, ref = "master", subdir = NULL, auth_token = github_pat(), sha = NULL, host = "api.github.com") { diff --git a/R/install-gitlab.R b/R/install-gitlab.R index 7e754e7c..94e9c53d 100644 --- a/R/install-gitlab.R +++ b/R/install-gitlab.R @@ -23,7 +23,7 @@ install_gitlab <- function(repo, remotes <- lapply(repo, gitlab_remote, auth_token = auth_token, host = host) - install_remotes(remotes, ...) + install_remotes(remotes, auth_token = auth_token, host = host, ...) } gitlab_remote <- function(repo, diff --git a/R/install-svn.R b/R/install-svn.R index 16f89ea8..b33bda9f 100644 --- a/R/install-svn.R +++ b/R/install-svn.R @@ -27,7 +27,7 @@ install_svn <- function(url, subdir = NULL, args = character(0), remotes <- lapply(url, svn_remote, svn_subdir = subdir, revision = revision, args = args) - install_remotes(remotes, ...) + install_remotes(remotes, args = args, ...) } svn_remote <- function(url, svn_subdir = NULL, revision = NULL, diff --git a/R/install.R b/R/install.R index 4f7031e7..9e5560fb 100644 --- a/R/install.R +++ b/R/install.R @@ -99,6 +99,8 @@ safe_build_package <- function(pkgdir, build_opts, dest_path, quiet, use_pkgbuil #' @param threads Number of threads to start, passed to #' \code{\link[utils]{install.packages}} as \code{Ncpus}. #' @param ... additional arguments passed to \code{\link[utils]{install.packages}}. +#' @param build If \code{TRUE} build the pacakge before installing. +#' @param build_opts Options to pass to `R CMD build`. #' @export #' @examples #' \dontrun{install_deps(".")} @@ -109,13 +111,16 @@ install_deps <- function(pkgdir = ".", dependencies = NA, type = getOption("pkgType"), ..., upgrade = TRUE, - quiet = FALSE) { + quiet = FALSE, + build = TRUE, + build_opts = c("--no-resave-data", "--no-manual", "--no-build-vignettes")) { packages <- dev_package_deps( pkgdir, repos = repos, dependencies = dependencies, - type = type + type = type, + ... ) dep_deps <- if (isTRUE(dependencies)) NA else dependencies @@ -126,6 +131,8 @@ install_deps <- function(pkgdir = ".", dependencies = NA, ..., Ncpus = threads, quiet = quiet, - upgrade = upgrade + upgrade = upgrade, + build = build, + build_opts = build_opts ) } diff --git a/man/install_deps.Rd b/man/install_deps.Rd index 742f1e9d..f7857362 100644 --- a/man/install_deps.Rd +++ b/man/install_deps.Rd @@ -6,7 +6,9 @@ \usage{ install_deps(pkgdir = ".", dependencies = NA, threads = getOption("Ncpus", 1), repos = getOption("repos"), - type = getOption("pkgType"), ..., upgrade = TRUE, quiet = FALSE) + type = getOption("pkgType"), ..., upgrade = TRUE, quiet = FALSE, + build = TRUE, build_opts = c("--no-resave-data", "--no-manual", + "--no-build-vignettes")) } \arguments{ \item{pkgdir}{path to a package directory, or to a package tarball.} @@ -32,6 +34,10 @@ install_deps(pkgdir = ".", dependencies = NA, \item{upgrade}{If \code{TRUE}, also upgrade any of out date dependencies.} \item{quiet}{If \code{TRUE}, suppress output.} + +\item{build}{If \code{TRUE} build the pacakge before installing.} + +\item{build_opts}{Options to pass to `R CMD build`.} } \description{ Install package dependencies if needed. diff --git a/man/package_deps.Rd b/man/package_deps.Rd index 3b70fb0e..b413292d 100644 --- a/man/package_deps.Rd +++ b/man/package_deps.Rd @@ -13,7 +13,7 @@ package_deps(packages, dependencies = NA, repos = getOption("repos"), local_package_deps(pkgdir = ".", dependencies = NA) dev_package_deps(pkgdir = ".", dependencies = NA, - repos = getOption("repos"), type = getOption("pkgType")) + repos = getOption("repos"), type = getOption("pkgType"), ...) \method{update}{package_deps}(object, ..., quiet = FALSE, upgrade = TRUE) @@ -36,10 +36,10 @@ dev_package_deps(pkgdir = ".", dependencies = NA, \item{pkgdir}{path to a package directory, or to a package tarball.} -\item{object}{A \code{package_deps} object.} - \item{...}{Additional arguments passed to \code{install_packages}.} +\item{object}{A \code{package_deps} object.} + \item{quiet}{If \code{TRUE}, suppress output.} \item{upgrade}{If \code{TRUE}, also upgrade any of out date dependencies.} From d9c60e0f1e43694e1dbae828aa0a6e7af280befd Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Wed, 29 Aug 2018 11:00:08 -0400 Subject: [PATCH 2/4] Ignore args which should not be passed to install.packages --- R/deps.R | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/R/deps.R b/R/deps.R index 402da0d5..d41f0acd 100644 --- a/R/deps.R +++ b/R/deps.R @@ -282,19 +282,37 @@ install_packages <- function(packages, repos = getOption("repos"), type = getOption("pkgType"), ..., dependencies = FALSE, quiet = NULL) { + # We want to pass only args that exist in the downstream functions + args_to_keep <- + unique( + names( + c( + formals(install.packages), + formals(download.file) + ) + ) + ) + + args <- list(...) + args <- args[names(args) %in% args_to_keep] + if (is.null(quiet)) quiet <- !identical(type, "source") message("Installing ", length(packages), " packages: ", paste(packages, collapse = ", ")) - safe_install_packages( - packages, - repos = repos, - type = type, - ..., - dependencies = dependencies, - quiet = quiet + do.call( + safe_install_packages, + c(list( + packages, + repos = repos, + type = type, + dependencies = dependencies, + quiet = quiet + ), + args + ) ) } From 48c9cb03a76f065b0b92893e06d63a4cbd6cc9a5 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Wed, 29 Aug 2018 13:08:11 -0400 Subject: [PATCH 3/4] Update bioc so there is a bioc_remote function Really the same issue as #140 --- R/install-bioc.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/R/install-bioc.R b/R/install-bioc.R index eba08036..e3214a03 100644 --- a/R/install-bioc.R +++ b/R/install-bioc.R @@ -30,20 +30,20 @@ install_bioc <- function(repo, mirror = getOption("BioC_git", download_url("git.bioconductor.org/packages")), git = c("auto", "git2r", "external"), ...) { - bioc_remote <- select_bioc_git_remote(match.arg(git)) - - remotes <- lapply(repo, bioc_remote, mirror = mirror) + remotes <- lapply(repo, bioc_remote, mirror = mirror, git = match.arg(git)) install_remotes(remotes, ...) } -select_bioc_git_remote <- function(git) { +bioc_remote <- function(repo, mirror = getOption("BioC_git", download_url("git.bioconductor.org/packages")), + git = c("auto", "git2r", "external"), ...) { + + git <- match.arg(git) if (git == "auto") { git <- if (pkg_installed("git2r")) "git2r" else "external" } - switch(git, - git2r = bioc_git2r_remote, - external = bioc_xgit_remote) + + list(git2r = bioc_git2r_remote, external = bioc_xgit_remote)[[git]](repo, mirror) } # Parse concise git repo specification: [username:password@][branch/]repo[#commit] From f7ce9a1da5a396d6073bb9d12c4ccb49969abf73 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Wed, 29 Aug 2018 13:09:22 -0400 Subject: [PATCH 4/4] All remotes should ignore additional arguments They now get passed all arguments from the parent call, but some of them are not applicable to the remote constructor --- R/install-bitbucket.R | 2 +- R/install-cran.R | 2 +- R/install-git.R | 2 +- R/install-github.R | 2 +- R/install-gitlab.R | 2 +- R/install-local.R | 2 +- R/install-svn.R | 2 +- R/install-url.R | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/R/install-bitbucket.R b/R/install-bitbucket.R index d582e99d..419b5324 100644 --- a/R/install-bitbucket.R +++ b/R/install-bitbucket.R @@ -43,7 +43,7 @@ install_bitbucket <- function(repo, ref = "master", subdir = NULL, bitbucket_remote <- function(repo, ref = "master", subdir = NULL, auth_user = NULL, password = NULL, sha = NULL, - host = NULL) { + host = NULL, ...) { meta <- parse_git_repo(repo) diff --git a/R/install-cran.R b/R/install-cran.R index 27f0d906..377ca6dc 100644 --- a/R/install-cran.R +++ b/R/install-cran.R @@ -20,7 +20,7 @@ install_cran <- function(pkgs, repos = getOption("repos"), type = getOption("pkg install_remotes(remotes, quiet = quiet, ...) } -cran_remote <- function(pkg, repos, type) { +cran_remote <- function(pkg, repos, type, ...) { remote("cran", name = pkg, diff --git a/R/install-git.R b/R/install-git.R index 7512581b..074c5145 100644 --- a/R/install-git.R +++ b/R/install-git.R @@ -28,7 +28,7 @@ install_git <- function(url, subdir = NULL, branch = NULL, } -git_remote <- function(url, subdir = NULL, branch = NULL, git = c("auto", "git2r", "external")) { +git_remote <- function(url, subdir = NULL, branch = NULL, git = c("auto", "git2r", "external"), ...) { git <- match.arg(git) if (git == "auto") { git <- if (pkg_installed("git2r")) "git2r" else "external" diff --git a/R/install-github.R b/R/install-github.R index cfeab08c..9ea6e2ca 100644 --- a/R/install-github.R +++ b/R/install-github.R @@ -52,7 +52,7 @@ install_github <- function(repo, github_remote <- function(repo, ref = "master", subdir = NULL, auth_token = github_pat(), sha = NULL, - host = "api.github.com") { + host = "api.github.com", ...) { meta <- parse_git_repo(repo) meta <- github_resolve_ref(meta$ref %||% ref, meta, auth_token) diff --git a/R/install-gitlab.R b/R/install-gitlab.R index 94e9c53d..909c18f6 100644 --- a/R/install-gitlab.R +++ b/R/install-gitlab.R @@ -28,7 +28,7 @@ install_gitlab <- function(repo, gitlab_remote <- function(repo, auth_token = gitlab_pat(), sha = NULL, - host = "gitlab.com") { + host = "gitlab.com", ...) { meta <- parse_git_repo(repo) meta$ref <- meta$ref %||% "master" diff --git a/R/install-local.R b/R/install-local.R index 0fad004f..349ab909 100644 --- a/R/install-local.R +++ b/R/install-local.R @@ -21,7 +21,7 @@ install_local <- function(path, subdir = NULL, ...) { install_remotes(remotes, ...) } -local_remote <- function(path, subdir = NULL, branch = NULL, args = character(0)) { +local_remote <- function(path, subdir = NULL, branch = NULL, args = character(0), ...) { remote("local", path = normalizePath(path), subdir = subdir diff --git a/R/install-svn.R b/R/install-svn.R index b33bda9f..9d4e4f88 100644 --- a/R/install-svn.R +++ b/R/install-svn.R @@ -31,7 +31,7 @@ install_svn <- function(url, subdir = NULL, args = character(0), } svn_remote <- function(url, svn_subdir = NULL, revision = NULL, - args = character(0)) { + args = character(0), ...) { remote("svn", url = url, svn_subdir = svn_subdir, diff --git a/R/install-url.R b/R/install-url.R index 90de68ce..2c875bac 100644 --- a/R/install-url.R +++ b/R/install-url.R @@ -20,7 +20,7 @@ install_url <- function(url, subdir = NULL, ...) { install_remotes(remotes, ...) } -url_remote <- function(url, subdir = NULL) { +url_remote <- function(url, subdir = NULL, ...) { remote("url", url = url, subdir = subdir