diff --git a/DESCRIPTION b/DESCRIPTION index 13f66fa34..a9df4ee23 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,7 +31,6 @@ Imports: pkgload (>= 1.5.0), profvis (>= 0.4.0), rcmdcheck (>= 1.4.0), - remotes (>= 2.5.0), rlang (>= 1.1.7), roxygen2 (>= 7.3.3), rversions (>= 3.0.0), @@ -51,6 +50,7 @@ Suggests: httr (>= 1.4.3), knitr (>= 1.39), lintr (>= 3.0.0), + remotes (>= 2.5.0), rmarkdown (>= 2.14), rstudioapi (>= 0.13), spelling (>= 2.2) diff --git a/NEWS.md b/NEWS.md index 16cb6e9e7..f93a8941b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,11 +1,13 @@ # devtools (development version) +* remotes has moved from Imports to Suggests (#2663). * `bash()`, `create()`, `missing_s3()`, `reload()`, `show_news()`, and `wd()` are now deprecated. These functions are all historical parts of our workflow that we no longer use or recommend. `create()` is superseded by `usethis::create_package()`. * `build_manual()` reports more details on failure (#2586). * `check_doc_fields()` is a new function that checks for missing `\value` and `\examples` fields in Rd files, which are commonly flagged by CRAN (#2525). * `build_vignettes()` and `clean_vignettes()` are now deprecated. We no longer recommend building vignettes in this way; instead use `pkgdown::build_article()` to render articles locally (#2488). * `build_site()` now just calls `pkgdown::build_site()`, meaning that you will get more (informative) output by default (#2578). * New `check_mac_devel()` function to check a package using the macOS builder at https://mac.r-project.org/macbuilder/submit.html (@nfrerebeau, #2507) +* `dev_sitrep()` now uses pak instead of remotes to check for outdated dependencies (#2663). * `dev_sitrep()` now uses cli for user-facing messages instead of deprecated usethis UI functions. * `dev_sitrep()` now works correctly in Positron (#2618). * `is_loading()` is now re-exported from pkgload (#2556). diff --git a/R/check-devtools.R b/R/check-devtools.R index 29e767b2c..a2b2f9d83 100644 --- a/R/check-devtools.R +++ b/R/check-devtools.R @@ -22,7 +22,7 @@ release_checks <- function(pkg = ".", built_path = NULL) { check_dev_versions <- function(pkg = ".") { pkg <- as.package(pkg) - dep_list <- pkg[tolower(remotes::standardise_dep(TRUE))] + dep_list <- pkg[tolower(c("Depends", "Imports", "LinkingTo", "Suggests"))] deps <- do.call("rbind", unname(compact(lapply(dep_list, parse_deps)))) deps <- deps[!is.na(deps$version), , drop = FALSE] diff --git a/R/install.R b/R/install.R index 99040b5dd..6a26b1fca 100644 --- a/R/install.R +++ b/R/install.R @@ -181,6 +181,7 @@ install_deps <- function( check_dots_used(action = getOption("devtools.ellipsis_action", warn)) + check_installed("remotes") remotes::install_deps( pkg$path, dependencies = dependencies, @@ -212,6 +213,7 @@ install_dev_deps <- function( "install_dev_deps()", "pak::local_install_dev_deps()" ) + check_installed("remotes") remotes::update_packages("roxygen2") pkg <- as.package(pkg) diff --git a/R/remotes.R b/R/remotes.R index ed9d57d48..d57abeb5d 100644 --- a/R/remotes.R +++ b/R/remotes.R @@ -40,6 +40,7 @@ install_bioc <- function(...) { "install_bioc()", I('pak::pak("bioc::pkg")') ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_bioc(...), required = FALSE) } @@ -51,6 +52,7 @@ install_bitbucket <- function(...) { "install_bitbucket()", "remotes::install_bitbucket()" ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_bitbucket(...), required = FALSE) } @@ -58,6 +60,7 @@ install_bitbucket <- function(...) { #' @export install_cran <- function(...) { lifecycle::deprecate_warn("2.5.0", "install_cran()", "pak::pak()") + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_cran(...), required = FALSE) } @@ -65,6 +68,7 @@ install_cran <- function(...) { #' @export install_dev <- function(...) { lifecycle::deprecate_warn("2.5.0", "install_dev()", "remotes::install_dev()") + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_dev(...), required = FALSE) } @@ -72,6 +76,7 @@ install_dev <- function(...) { #' @export install_git <- function(...) { lifecycle::deprecate_warn("2.5.0", "install_git()", I('pak::pak("git::url")')) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_git(...), required = FALSE) } @@ -83,6 +88,7 @@ install_github <- function(...) { "install_github()", I('pak::pak("user/repo")') ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_github(...), required = FALSE) } @@ -94,6 +100,7 @@ install_gitlab <- function(...) { "install_gitlab()", I('pak::pak("gitlab::user/repo")') ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_gitlab(...), required = FALSE) } @@ -105,6 +112,7 @@ install_local <- function(...) { "install_local()", I('pak::pak("local::path")') ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_local(...), required = FALSE) } @@ -112,6 +120,7 @@ install_local <- function(...) { #' @export install_svn <- function(...) { lifecycle::deprecate_warn("2.5.0", "install_svn()", "remotes::install_svn()") + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_svn(...), required = FALSE) } @@ -119,6 +128,7 @@ install_svn <- function(...) { #' @export install_url <- function(...) { lifecycle::deprecate_warn("2.5.0", "install_url()", I('pak::pak("url::url")')) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_url(...), required = FALSE) } @@ -130,6 +140,7 @@ install_version <- function(...) { "install_version()", I('pak::pak("pkg@version")') ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::install_version(...), required = FALSE) } @@ -137,6 +148,7 @@ install_version <- function(...) { #' @export update_packages <- function(...) { lifecycle::deprecate_warn("2.5.0", "update_packages()", "pak::pak()") + check_installed("remotes") pkgbuild::with_build_tools(remotes::update_packages(...), required = FALSE) } @@ -148,6 +160,7 @@ dev_package_deps <- function(...) { "dev_package_deps()", "pak::local_dev_deps()" ) + check_installed("remotes") pkgbuild::with_build_tools(remotes::dev_package_deps(...), required = FALSE) } @@ -155,6 +168,7 @@ dev_package_deps <- function(...) { #' @export github_pull <- function(...) { lifecycle::deprecate_warn("2.5.0", "github_pull()", "remotes::github_pull()") + check_installed("remotes") remotes::github_pull(...) } @@ -166,5 +180,6 @@ github_release <- function(...) { "github_release()", "remotes::github_release()" ) + check_installed("remotes") remotes::github_release(...) } diff --git a/R/sitrep.R b/R/sitrep.R index c37adbaff..997c6948d 100644 --- a/R/sitrep.R +++ b/R/sitrep.R @@ -112,9 +112,9 @@ dev_sitrep <- function(pkg = ".", debug = FALSE) { has_build_tools = has_build_tools, rtools_path = if (has_build_tools) pkgbuild::rtools_path(), devtools_version = utils::packageVersion("devtools"), - devtools_deps = remotes::package_deps("devtools", dependencies = NA), + devtools_deps = outdated_deps(pak::pkg_deps("devtools", dependencies = NA)), pkg_deps = if (!is.null(pkg)) { - remotes::dev_package_deps(pkg$path, dependencies = TRUE) + outdated_deps(pak::local_dev_deps(pkg$path, dependencies = TRUE)) }, rstudio_version = if (is_rstudio_running()) rstudioapi::getVersion(), rstudio_msg = if (!is_positron()) check_for_rstudio_updates() @@ -199,7 +199,7 @@ print.dev_sitrep <- function(x, ...) { cli::cli_bullets(c( "!" = "{.pkg devtools} or its dependencies out of date:", " " = "{.val {x$devtools_deps$package[devtools_deps_old]}}", - " " = "Update them with {.code devtools::update_packages(\"devtools\")}" + " " = "Update them with {.code pak::pak(\"devtools\")}" )) all_ok <- FALSE } @@ -213,7 +213,7 @@ print.dev_sitrep <- function(x, ...) { cli::cli_bullets(c( "!" = "{.field {x$pkg$package}} dependencies out of date:", " " = "{.val {x$pkg_deps$package[pkg_deps_old]}}", - " " = "Update them with {.code devtools::install_dev_deps()}" + " " = "Update them with {.code pak::local_install_dev_deps()}" )) all_ok <- FALSE } @@ -228,6 +228,31 @@ print.dev_sitrep <- function(x, ...) { # Helpers ----------------------------------------------------------------- +outdated_deps <- function(deps) { + installed <- vapply( + deps$package, + function(p) { + tryCatch( + as.character(utils::packageVersion(p)), + error = function(e) NA_character_ + ) + }, + character(1) + ) + diff <- mapply( + function(inst, avail) { + if (is.na(inst)) { + return(-1L) + } + as.integer(utils::compareVersion(inst, avail)) + }, + installed, + deps$version, + USE.NAMES = FALSE + ) + data.frame(package = deps$package, diff = diff) +} + kv_line <- function(key, value, path = FALSE) { if (is.null(value)) { cli::cli_inform(c("*" = "{key}: {.silver }")) diff --git a/R/vignettes.R b/R/vignettes.R index 453f54424..cd5dce38c 100644 --- a/R/vignettes.R +++ b/R/vignettes.R @@ -40,6 +40,7 @@ build_vignettes <- function( return(invisible()) } + check_installed("remotes") deps <- remotes::dev_package_deps(pkg$path, dependencies) update(deps, upgrade = upgrade) diff --git a/README.md b/README.md index 22bdf6a70..e19b980a8 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,7 @@ includes: * [roxygen2](https://github.com/r-lib/roxygen2): Function and package documentation (i.e. `document()`). -* [remotes](https://github.com/r-lib/remotes): Installing packages (i.e. - `install_github()`). +* [pak](https://pak.r-lib.org): Installing packages (i.e. `pak::pak()`). * [pkgbuild](https://github.com/r-lib/pkgbuild): Building binary packages (including checking if build tools are available) (i.e. `build()`). @@ -161,7 +160,7 @@ You may also need to care if you are trying to use some devtools functionality in your own package or deployed application. Generally in these cases it is better to depend on the particular package directly rather than depend on devtools, e.g. use `sessioninfo::session_info()` rather than `devtools::session_info()`, -or `remotes::install_github()` vs `devtools::install_github()`. +or `pak::pak("user/repo")` vs `devtools::install_github("user/repo")`. However for day to day development we recommend you continue to use `library(devtools)` to quickly load all needed development tools, just like diff --git a/tests/testthat/_snaps/sitrep.md b/tests/testthat/_snaps/sitrep.md index 548c26c8e..9ea602c0f 100644 --- a/tests/testthat/_snaps/sitrep.md +++ b/tests/testthat/_snaps/sitrep.md @@ -40,7 +40,7 @@ * version: 2.4.6 ! devtools or its dependencies out of date: "cli" - Update them with `devtools::update_packages("devtools")` + Update them with `pak::pak("devtools")` -- dev package --------------------------------------------- * package: * path: @@ -60,7 +60,7 @@ * path: '/tmp/mypkg' ! mypkg dependencies out of date: "dplyr" and "tidyr" - Update them with `devtools::install_dev_deps()` + Update them with `pak::local_install_dev_deps()` # print shows RStudio update message diff --git a/tests/testthat/test-sitrep.R b/tests/testthat/test-sitrep.R index c2debee42..cbe14f69c 100644 --- a/tests/testthat/test-sitrep.R +++ b/tests/testthat/test-sitrep.R @@ -55,6 +55,25 @@ test_that("print shows RStudio update message", { expect_snapshot(print(x)) }) +test_that("outdated_deps detects outdated packages", { + deps <- data.frame( + package = c("rlang", "cli"), + version = c("0.0.1", "0.0.1") + ) + result <- outdated_deps(deps) + expect_equal(result$package, c("rlang", "cli")) + expect_equal(result$diff, c(1, 1)) +}) + +test_that("outdated_deps reports missing packages as outdated", { + deps <- data.frame( + package = c("rlang", "thereIsNoSuchPackage"), + version = c("0.0.1", "1.0.0") + ) + result <- outdated_deps(deps) + expect_equal(result$diff[[2]], -1L) +}) + test_that("check_for_rstudio_updates", { skip_if_offline() skip_on_cran()