diff --git a/DESCRIPTION b/DESCRIPTION index 84ba1a51f..bcf0e08be 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,8 +21,10 @@ Imports: desc (>= 1.4.1), ellipsis (>= 0.3.2), fs (>= 1.5.2), + httr2 (>= 1.1.2), lifecycle (>= 1.0.1), memoise (>= 2.0.1), + mime (>= 0.13), miniUI (>= 0.1.1.1), pkgbuild (>= 1.3.1), pkgdown (>= 2.0.6), diff --git a/NAMESPACE b/NAMESPACE index b9b6527f3..39aaf28ed 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -83,8 +83,17 @@ import(fs) importFrom(cli,cat_bullet) importFrom(cli,cat_rule) importFrom(ellipsis,check_dots_used) +importFrom(fs,file_delete) +importFrom(fs,file_temp) +importFrom(httr2,req_body_multipart) +importFrom(httr2,req_perform) +importFrom(httr2,request) +importFrom(httr2,resp_body_raw) +importFrom(httr2,resp_body_string) +importFrom(httr2,resp_check_status) importFrom(lifecycle,deprecated) importFrom(memoise,memoise) +importFrom(mime,guess_type) importFrom(pkgbuild,clean_dll) importFrom(pkgbuild,find_rtools) importFrom(pkgbuild,has_devel) @@ -107,6 +116,8 @@ importFrom(remotes,install_svn) importFrom(remotes,install_url) importFrom(remotes,install_version) importFrom(remotes,update_packages) +importFrom(rlang,check_installed) +importFrom(rlang,warn) importFrom(sessioninfo,package_info) importFrom(sessioninfo,session_info) importFrom(stats,update) diff --git a/R/check-mac.R b/R/check-mac.R index 3346775d2..7ac6c9f22 100644 --- a/R/check-mac.R +++ b/R/check-mac.R @@ -8,6 +8,7 @@ #' @inheritParams check_win #' @param dep_pkgs Additional custom dependencies to install prior to checking #' the package. +#' @importFrom httr2 request req_body_multipart req_perform resp_check_status resp_body_string #' @family build functions #' @return The url with the check results (invisibly) #' @export @@ -40,26 +41,25 @@ check_mac_release <- function(pkg = ".", dep_pkgs = character(), args = NULL, ma url <- "https://mac.r-project.org/macbuilder/v1/submit" - rlang::check_installed("httr") - body <- list(pkgfile = httr::upload_file(built_path)) + rlang::check_installed("httr2") + body <- list(pkgfile = upload_file(built_path)) + # upload_file function implemented in utils.R + if (length(dep_built_paths) > 0) { - uploads <- lapply(dep_built_paths, httr::upload_file) + uploads <- lapply(dep_built_paths, upload_file) names(uploads) <- rep("depfiles", length(uploads)) body <- append(body, uploads) } - res <- httr::POST(url, - body = body, - headers = list( - "Content-Type" = "multipart/form-data" - ), - encode = "multipart" - ) + req <- httr2::request(url) + req <- httr2::req_body_multipart(req, !!!body) + res <- httr2::req_perform(req) - httr::stop_for_status(res, task = "Uploading package") + httr2::resp_check_status(res, info = "Uploading package") - response_url <- httr::content(res)$url + res_body <- httr2::resp_body_string(res) + response_url <- regmatches(res_body, regexpr("https://mac\\.R-project\\.org/macbuilder/results/[0-9a-zA-Z\\-]+/", res_body)) if (!quiet) { time <- strftime(Sys.time() + 10 * 60, "%I:%M %p") @@ -72,3 +72,5 @@ check_mac_release <- function(pkg = ".", dep_pkgs = character(), args = NULL, ma invisible(response_url) } + + diff --git a/R/check.R b/R/check.R index 11489ffb1..3512dae41 100644 --- a/R/check.R +++ b/R/check.R @@ -27,7 +27,7 @@ #' CRAN, and hence can take a reasonable amount of time. #' #' * Debugging flags for the compiler, set by -#' [`compiler_flags(FALSE)`][compiler_flags()]. +#' [`compiler_flags(FALSE)`][pkgbuild::compiler_flags()]. #' #' * If `aspell` is found, `_R_CHECK_CRAN_INCOMING_USE_ASPELL_` #' is set to `TRUE`. If no spell checker is installed, a warning is issued. diff --git a/R/release.R b/R/release.R index 352c5886b..a03bb13b0 100644 --- a/R/release.R +++ b/R/release.R @@ -277,23 +277,27 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { # Initial upload --------- cli::cli_inform(c(i = "Uploading package & comments")) - rlang::check_installed("httr") + rlang::check_installed("httr2") body <- list( pkg_id = "", name = maint$name, email = maint$email, - uploaded_file = httr::upload_file(built_path, "application/x-gzip"), + uploaded_file = upload_file(built_path, "application/x-gzip"), comment = comments, upload = "Upload package" ) - r <- httr::POST(cran_submission_url, body = body) + + req <- httr2::request(cran_submission_url) + req <- httr2::req_body_multipart(req, !!!body) + r <- httr2::req_perform(req) # If a 404 likely CRAN is closed for maintenance, try to get the message - if (httr::status_code(r) == 404) { + if (httr2::resp_status(r) == 404) { msg <- "" - try({ - r2 <- httr::GET(sub("index2", "index", cran_submission_url)) - msg <- extract_cran_msg(httr::content(r2, "text")) + try({ + req2 <- httr2::request(sub("index2", "index", cran_submission_url)) + r2 <- httr2::req_perform(req2) + msg <- extract_cran_msg(httr2::resp_body_string(r2)) }) cli::cli_abort( c( @@ -304,8 +308,8 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { ) } - httr::stop_for_status(r) - new_url <- httr::parse_url(r$url) + httr2::resp_check_status(r) +new_url <- httr2::url_parse(r$url) # Confirmation ----------- cli::cli_inform(c(i = "Confirming submission")) @@ -316,9 +320,14 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { policy_check = "1/", submit = "Submit package" ) - r <- httr::POST(cran_submission_url, body = body) - httr::stop_for_status(r) - new_url <- httr::parse_url(r$url) + + req <- httr2::request(cran_submission_url) + req <- httr2::req_body_multipart(req, !!!body) + r <- httr2::req_perform(req) + + httr2::resp_check_status(r) + + new_url <- httr2::url_parse(r$url) if (new_url$query$submit == "1") { cli::cli_inform(c( "v" = "Package submission successful", diff --git a/R/remotes.R b/R/remotes.R index c783301dc..60581783b 100644 --- a/R/remotes.R +++ b/R/remotes.R @@ -25,7 +25,7 @@ with_pkgbuild_build_tools <- function(fun) { #' #' These functions are re-exported from the remotes package. They differ only -#' that the ones in devtools use the [ellipsis] package to ensure all dotted +#' that the ones in devtools use the [ellipsis::check_dots_used] feature to ensure all dotted #' arguments are used. #' #' Follow the links below to see the documentation. diff --git a/R/run-source.R b/R/run-source.R index 3c8ac9ae4..75753b6ae 100644 --- a/R/run-source.R +++ b/R/run-source.R @@ -13,6 +13,10 @@ #' @param url url #' @param ... other options passed to [source()] #' @param sha1 The (prefix of the) SHA-1 hash of the file at the remote URL. +#' @importFrom fs file_temp file_delete +#' @importFrom rlang check_installed warn +#' @importFrom httr2 request req_perform resp_check_status resp_body_raw +#' @importFrom ellipsis check_dots_used #' @export #' @seealso [source_gist()] #' @examples @@ -31,18 +35,20 @@ source_url <- function(url, ..., sha1 = NULL) { stopifnot(is.character(url), length(url) == 1) rlang::check_installed("digest") - rlang::check_installed("httr") + rlang::check_installed("httr2") - temp_file <- file_temp() - on.exit(file_delete(temp_file), add = TRUE) + temp_file <- fs::file_temp() + on.exit(fs::file_delete(temp_file), add = TRUE) - request <- httr::GET(url) - httr::stop_for_status(request) - writeBin(httr::content(request, type = "raw"), temp_file) + resp <- httr2::req_perform(httr2::request(url)) + + httr2::resp_check_status(resp) + + writeBin(httr2::resp_body_raw(resp), temp_file) check_sha1(temp_file, sha1) - check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn)) + ellipsis::check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn)) source(temp_file, ...) } diff --git a/R/utils.R b/R/utils.R index d9f01e914..a8ffa8408 100644 --- a/R/utils.R +++ b/R/utils.R @@ -45,3 +45,12 @@ is_testing <- function() { is_rstudio_running <- function() { !is_testing() && rstudioapi::isAvailable() } + +#' @importFrom mime guess_type +upload_file <- function(path, type = NULL) { + stopifnot(is.character(path), length(path) == 1, file.exists(path)) + if (is.null(type)) { + type <- mime::guess_type(path) + } + curl::form_file(path, type) +} \ No newline at end of file diff --git a/man/check.Rd b/man/check.Rd index 949d7d869..1acf0c256 100644 --- a/man/check.Rd +++ b/man/check.Rd @@ -134,7 +134,7 @@ with how check works on CRAN. This includes: var, which lets you know that your tests are running somewhere other than CRAN, and hence can take a reasonable amount of time. \item Debugging flags for the compiler, set by -\code{\link[=compiler_flags]{compiler_flags(FALSE)}}. +\code{\link[pkgbuild:compiler_flags]{compiler_flags(FALSE)}}. \item If \code{aspell} is found, \verb{_R_CHECK_CRAN_INCOMING_USE_ASPELL_} is set to \code{TRUE}. If no spell checker is installed, a warning is issued. \item Environment variables, controlled by arguments \code{incoming}, \code{remote} and diff --git a/man/load_all.Rd b/man/load_all.Rd index 8221cfd77..fd368b447 100644 --- a/man/load_all.Rd +++ b/man/load_all.Rd @@ -17,11 +17,9 @@ load_all( \arguments{ \item{path}{Path to a package, or within a package.} -\item{reset}{clear package environment and reset file cache before loading -any pieces of the package. This largely equivalent to running -\code{\link[pkgload:unload]{unload()}}, however the old namespaces are not completely removed and no -\code{.onUnload()} hooks are called. Use \code{reset = FALSE} may be faster for -large code bases, but is a significantly less accurate approximation.} +\item{reset}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This is no longer supported +because preserving the namespace requires unlocking its environment, which +is no longer possible in recent versions of R.} \item{recompile}{DEPRECATED. force a recompile of DLL from source code, if present. This is equivalent to running \code{\link[pkgbuild:clean_dll]{pkgbuild::clean_dll()}} before @@ -67,6 +65,8 @@ helpers are run during package loading. \code{is_loading()} returns \code{TRUE} when it is called while \code{load_all()} is running. This may be useful e.g. in \code{.onLoad} hooks. +A package loaded with \code{load_all()} can be identified with with +\code{\link[pkgload:is_dev_package]{is_dev_package()}}. } \section{Differences to regular loading}{ @@ -102,9 +102,6 @@ load_all("./") # Running again loads changed files load_all("./") -# With reset=TRUE, unload and reload the package for a clean start -load_all("./", TRUE) - # With export_all=FALSE, only objects listed as exports in NAMESPACE # are exported load_all("./", export_all = FALSE) diff --git a/man/reexports.Rd b/man/reexports.Rd index 413971ab1..e001a381d 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -16,6 +16,11 @@ \alias{session_info} \alias{package_info} \title{Objects exported from other packages} +\usage{ +github_pull(pull) + +github_release() +} \keyword{internal} \description{ These objects are imported from other packages. Follow the links @@ -26,8 +31,6 @@ below to see their documentation. \item{pkgload}{\code{\link[pkgload]{check_dep_version}}, \code{\link[pkgload]{parse_deps}}, \code{\link[pkgload]{unload}}} - \item{remotes}{\code{\link[remotes:github_refs]{github_pull}}, \code{\link[remotes:github_refs]{github_release}}} - \item{sessioninfo}{\code{\link[sessioninfo]{package_info}}, \code{\link[sessioninfo]{session_info}}} }} diff --git a/man/remote-reexports.Rd b/man/remote-reexports.Rd index 18f315d06..3b1ac7ecc 100644 --- a/man/remote-reexports.Rd +++ b/man/remote-reexports.Rd @@ -218,7 +218,7 @@ dev_package_deps( } \description{ These functions are re-exported from the remotes package. They differ only -that the ones in devtools use the \link{ellipsis} package to ensure all dotted +that the ones in devtools use the \link[ellipsis:check_dots_used]{ellipsis::check_dots_used} feature to ensure all dotted arguments are used. } \details{