From 41f39767e9d30dd57fce08a9dda314832ff101de Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Tue, 16 Nov 2021 09:55:54 -0500 Subject: [PATCH 1/2] Add check_mac_release function to submit to the mac builder Fixes #2375 --- DESCRIPTION | 2 +- NAMESPACE | 1 + NEWS.md | 4 ++- R/check-mac.R | 71 ++++++++++++++++++++++++++++++++++++++++ man/check.Rd | 16 +++++---- man/check_mac_release.Rd | 48 +++++++++++++++++++++++++++ man/check_rhub.Rd | 1 + man/check_win.Rd | 1 + 8 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 R/check-mac.R create mode 100644 man/check_mac_release.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 41563d144..0ca80d494 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -67,4 +67,4 @@ VignetteBuilder: Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.1.1 +RoxygenNote: 7.1.2 diff --git a/NAMESPACE b/NAMESPACE index 6676ec0a7..2fb640b16 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,6 +13,7 @@ export(build_vignettes) export(check) export(check_built) export(check_dep_version) +export(check_mac_release) export(check_man) export(check_rhub) export(check_win_devel) diff --git a/NEWS.md b/NEWS.md index 641e7f7b4..dbf97495e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,8 @@ # devtools (development version) -`release()` and `submit_cran()` now record submission details using the Debian Control File format, for better machine-readability. This file has a new name, CRAN-SUBMISSION (instead of CRAN-RELEASE) and now includes package version, in addition to the full SHA and a timestamp. +* New `check_mac_release()` function to check a package using the macOS builder at https://mac.r-project.org/macbuilder/submit.html (#2375) + +* `release()` and `submit_cran()` now record submission details using the Debian Control File format, for better machine-readability. This file has a new name, CRAN-SUBMISSION (instead of CRAN-RELEASE) and now includes package version, in addition to the full SHA and a timestamp. # devtools 2.4.2 diff --git a/R/check-mac.R b/R/check-mac.R new file mode 100644 index 000000000..16829f36b --- /dev/null +++ b/R/check-mac.R @@ -0,0 +1,71 @@ +#' Check macOS package +#' +#' This function works by bundling source package, and then uploading to +#' . Once building is +#' complete you'll receive a link to the built package in the email address +#' listed in the maintainer field. +#' +#' @template devtools +#' @inheritParams pkgbuild::build +#' @param email An alternative email to use, default `NULL` uses the package +#' Maintainer's email. +#' @param quiet If `TRUE`, suppresses output. +#' @param ... Additional arguments passed to [pkgbuild::build()]. +#' @family build functions +#' @return The url with the check results (invisibly) +#' @export +check_mac_release <- function(pkg = ".", args = NULL, manual = TRUE, email = NULL, quiet = FALSE, ...) { + check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn)) + + pkg <- as.package(pkg) + + if (!is.null(email)) { + desc_file <- path(pkg$path, "DESCRIPTION") + backup <- file_temp() + file_copy(desc_file, backup) + on.exit(file_move(backup, desc_file), add = TRUE) + + change_maintainer_email(desc_file, email) + + pkg <- as.package(pkg$path) + } + + if (!quiet) { + cli::cli_alert_info( + "Building macOS version of {.pkg {pkg$package}} ({pkg$version})", + "with https://mac.r-project.org/macbuilder/submit.html." + ) + } + + built_path <- pkgbuild::build(pkg$path, tempdir(), + args = args, + manual = manual, quiet = quiet, ... + ) + on.exit(file_delete(built_path), add = TRUE) + + url <- "https://mac.r-project.org/macbuilder/v1/submit" + + res <- httr::POST(url, + body = list( + pkgfile = httr::upload_file(built_path) + ), + headers = list( + "Content-Type" = "multipart/form-data" + ), + encode = "multipart" + ) + + httr::stop_for_status(res) + + response_url <- httr::content(res)$url + + if (!quiet) { + time <- strftime(Sys.time() + 30 * 60, "%I:%M %p") + + cli::cli_alert_success( + "[{Sys.Date()}] Check {.url {response_url}} for a link to results in 15-30 mins (~{time})." + ) + } + + invisible(response_url) +} diff --git a/man/check.Rd b/man/check.Rd index 427d583b3..b2ca1e312 100644 --- a/man/check.Rd +++ b/man/check.Rd @@ -74,10 +74,13 @@ packages aren't found.} R 3.6 and earlier; in R 4.0.0 code in \verb{\\dontest\{\}} is always run as part of CRAN submission.} -\item{args}{Character vector of arguments to pass to -\code{R CMD check}. (Note that instead of the \code{--output} option you -should use the \code{check_dir} argument, because \code{--output} cannot -deal with spaces and other special characters on Windows.} +\item{args}{Character vector of arguments to pass to \verb{R CMD check}. Pass each +argument as a single element of this character vector (do not use spaces to +delimit arguments like you would in the shell). For example, to skip +running of examples and tests, use \code{args = c("--no-examples", "--no-tests")} and not \code{args = "--no-examples --no-tests"}. (Note that +instead of the \code{--output} option you should use the \code{check_dir} argument, +because \code{--output} cannot deal with spaces and other special characters on +Windows.)} \item{env_vars}{Environment variables set during \verb{R CMD check}} @@ -92,13 +95,14 @@ check directory.} \item{vignettes}{If \code{FALSE}, do not build or check vignettes, equivalent to using \verb{args = '--ignore-vignettes' and }build_args = '--no-build-vignettes'.} -\item{error_on}{Whether to throw an error on \code{R CMD check} failures. +\item{error_on}{Whether to throw an error on \verb{R CMD check} failures. Note that the check is always completed (unless a timeout happens), and the error is only thrown after completion. If \code{"never"}, then no errors are thrown. If \code{"error"}, then only \code{ERROR} failures generate errors. If \code{"warning"}, then \code{WARNING} failures generate errors as well. If \code{"note"}, then any check failure generated an -error.} +error. Its default can be modified with the \code{RCMDCHECK_ERROR_ON} +environment variable. If that is not set, then \code{"never"} is used.} \item{path}{Path to built package.} } diff --git a/man/check_mac_release.Rd b/man/check_mac_release.Rd new file mode 100644 index 000000000..a319569c1 --- /dev/null +++ b/man/check_mac_release.Rd @@ -0,0 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check-mac.R +\name{check_mac_release} +\alias{check_mac_release} +\title{Check macOS package} +\usage{ +check_mac_release( + pkg = ".", + args = NULL, + manual = TRUE, + email = NULL, + quiet = FALSE, + ... +) +} +\arguments{ +\item{pkg}{The package to use, can be a file path to the package or a +package object. See \code{\link[=as.package]{as.package()}} for more information.} + +\item{args}{An optional character vector of additional command +line arguments to be passed to \verb{R CMD build} if \code{binary = FALSE}, +or \verb{R CMD install} if \code{binary = TRUE}.} + +\item{manual}{For source packages: if \code{FALSE}, don't build PDF +vignettes (\code{--no-build-vignettes}) or manual (\code{--no-manual}).} + +\item{email}{An alternative email to use, default \code{NULL} uses the package +Maintainer's email.} + +\item{quiet}{If \code{TRUE}, suppresses output.} + +\item{...}{Additional arguments passed to \code{\link[pkgbuild:build]{pkgbuild::build()}}.} +} +\value{ +The url with the check results (invisibly) +} +\description{ +This function works by bundling source package, and then uploading to +\url{https://mac.r-project.org/macbuilder/submit.html}. Once building is +complete you'll receive a link to the built package in the email address +listed in the maintainer field. +} +\seealso{ +Other build functions: +\code{\link{check_rhub}()}, +\code{\link{check_win}()} +} +\concept{build functions} diff --git a/man/check_rhub.Rd b/man/check_rhub.Rd index e5324a138..8eb445901 100644 --- a/man/check_rhub.Rd +++ b/man/check_rhub.Rd @@ -53,6 +53,7 @@ results. See more at \code{\link[rhub:validate_email]{rhub::validate_email()}}. \seealso{ Other build functions: +\code{\link{check_mac_release}()}, \code{\link{check_win}()} } \concept{build functions} diff --git a/man/check_win.Rd b/man/check_win.Rd index fe4e9e005..b5319517a 100644 --- a/man/check_win.Rd +++ b/man/check_win.Rd @@ -71,6 +71,7 @@ is also useful to check that your package is ok on windows. \seealso{ Other build functions: +\code{\link{check_mac_release}()}, \code{\link{check_rhub}()} } \concept{build functions} From 94c4ad9bbd4d3597948512beed616219ac547e46 Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Wed, 17 Nov 2021 16:00:13 -0500 Subject: [PATCH 2/2] Updates after review - Removed the email argument - added support for custom dependencies - added `task` argument to `stop_for_status()` --- R/check-mac.R | 50 +++++++++++++++++++++------------------- man/check_mac_release.Rd | 12 ++++------ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/R/check-mac.R b/R/check-mac.R index 16829f36b..3af065329 100644 --- a/R/check-mac.R +++ b/R/check-mac.R @@ -1,35 +1,22 @@ #' Check macOS package #' #' This function works by bundling source package, and then uploading to -#' . Once building is -#' complete you'll receive a link to the built package in the email address -#' listed in the maintainer field. +#' . This function returns a +#' link to the page with the check results. #' #' @template devtools #' @inheritParams pkgbuild::build -#' @param email An alternative email to use, default `NULL` uses the package -#' Maintainer's email. +#' @param dep_pkgs Additional custom dependencies to install prior to checking the package. #' @param quiet If `TRUE`, suppresses output. #' @param ... Additional arguments passed to [pkgbuild::build()]. #' @family build functions #' @return The url with the check results (invisibly) #' @export -check_mac_release <- function(pkg = ".", args = NULL, manual = TRUE, email = NULL, quiet = FALSE, ...) { +check_mac_release <- function(pkg = ".", dep_pkgs = ".", args = NULL, manual = TRUE, quiet = FALSE, ...) { check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn)) pkg <- as.package(pkg) - if (!is.null(email)) { - desc_file <- path(pkg$path, "DESCRIPTION") - backup <- file_temp() - file_copy(desc_file, backup) - on.exit(file_move(backup, desc_file), add = TRUE) - - change_maintainer_email(desc_file, email) - - pkg <- as.package(pkg$path) - } - if (!quiet) { cli::cli_alert_info( "Building macOS version of {.pkg {pkg$package}} ({pkg$version})", @@ -41,29 +28,44 @@ check_mac_release <- function(pkg = ".", args = NULL, manual = TRUE, email = NUL args = args, manual = manual, quiet = quiet, ... ) - on.exit(file_delete(built_path), add = TRUE) + + dep_built_paths <- character() + for (i in seq_along(dep_pkgs)) { + dep_pkg <- as.package(dep_pkgs[[i]])$path + dep_built_paths[[i]] <- pkgbuild::build(dep_pkg, tempdir(), + args = args, + manual = manual, quiet = quiet, ... + ) + } + on.exit(file_delete(c(built_path, dep_built_paths)), add = TRUE) url <- "https://mac.r-project.org/macbuilder/v1/submit" + body <- list(pkgfile = httr::upload_file(built_path)) + + if (length(dep_built_paths) > 0) { + uploads <- lapply(dep_built_paths, httr::upload_file) + names(uploads) <- rep("depfiles", length(uploads)) + body <- append(body, uploads) + } + res <- httr::POST(url, - body = list( - pkgfile = httr::upload_file(built_path) - ), + body = body, headers = list( "Content-Type" = "multipart/form-data" ), encode = "multipart" ) - httr::stop_for_status(res) + httr::stop_for_status(res, task = "Uploading package") response_url <- httr::content(res)$url if (!quiet) { - time <- strftime(Sys.time() + 30 * 60, "%I:%M %p") + time <- strftime(Sys.time() + 10 * 60, "%I:%M %p") cli::cli_alert_success( - "[{Sys.Date()}] Check {.url {response_url}} for a link to results in 15-30 mins (~{time})." + "[{Sys.Date()}] Check {.url {response_url}} for the results in 5-10 mins (~{time})." ) } diff --git a/man/check_mac_release.Rd b/man/check_mac_release.Rd index a319569c1..44df5d908 100644 --- a/man/check_mac_release.Rd +++ b/man/check_mac_release.Rd @@ -6,9 +6,9 @@ \usage{ check_mac_release( pkg = ".", + dep_pkgs = ".", args = NULL, manual = TRUE, - email = NULL, quiet = FALSE, ... ) @@ -17,6 +17,8 @@ check_mac_release( \item{pkg}{The package to use, can be a file path to the package or a package object. See \code{\link[=as.package]{as.package()}} for more information.} +\item{dep_pkgs}{Additional custom dependencies to install prior to checking the package.} + \item{args}{An optional character vector of additional command line arguments to be passed to \verb{R CMD build} if \code{binary = FALSE}, or \verb{R CMD install} if \code{binary = TRUE}.} @@ -24,9 +26,6 @@ or \verb{R CMD install} if \code{binary = TRUE}.} \item{manual}{For source packages: if \code{FALSE}, don't build PDF vignettes (\code{--no-build-vignettes}) or manual (\code{--no-manual}).} -\item{email}{An alternative email to use, default \code{NULL} uses the package -Maintainer's email.} - \item{quiet}{If \code{TRUE}, suppresses output.} \item{...}{Additional arguments passed to \code{\link[pkgbuild:build]{pkgbuild::build()}}.} @@ -36,9 +35,8 @@ The url with the check results (invisibly) } \description{ This function works by bundling source package, and then uploading to -\url{https://mac.r-project.org/macbuilder/submit.html}. Once building is -complete you'll receive a link to the built package in the email address -listed in the maintainer field. +\url{https://mac.r-project.org/macbuilder/submit.html}. This function returns a +link to the page with the check results. } \seealso{ Other build functions: