diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index a1e8e305e..c7fe02479 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -54,7 +54,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::rcmdcheck + extra-packages: any::rcmdcheck, magick=?ignore-before-r=4.0.0 needs: check - name: Configure Git User @@ -66,5 +66,6 @@ jobs: - uses: r-lib/actions/check-r-package@v2 env: _R_CALLS_INVALID_NUMERIC_VERSION_: true + _R_CHECK_FORCE_SUGGESTS_: false with: upload-snapshots: true diff --git a/R/badge.R b/R/badge.R index cba764169..23868bc3c 100644 --- a/R/badge.R +++ b/R/badge.R @@ -45,7 +45,7 @@ use_badge <- function(badge_name, href, src) { if (is.null(path)) { ui_bullets(c( "!" = "Can't find a README for the current project.", - "i" = "See {.fun usethis::use_readme_rmd} for help creating this file.", + "i" = "See {.help usethis::use_readme_rmd} for help creating this file.", "i" = "Badge link will only be printed to screen." )) path <- "README" diff --git a/R/cpp11.R b/R/cpp11.R index 9162b917c..0649aea10 100644 --- a/R/cpp11.R +++ b/R/cpp11.R @@ -9,8 +9,8 @@ #' #' @export use_cpp11 <- function() { - check_installed("cpp11") check_is_package("use_cpp11()") + check_installed("cpp11") check_uses_roxygen("use_cpp11()") use_src() diff --git a/R/data.R b/R/data.R index 75069e708..cc407d745 100644 --- a/R/data.R +++ b/R/data.R @@ -147,6 +147,6 @@ use_data_raw <- function(name = "DATASET", open = rlang::is_interactive()) { ui_bullets(c( "_" = "Finish writing the data preparation script in {.path {pth(r_path)}}.", - "_" = "Use {.code usethis::use_data()} to add prepared data to package." + "_" = "Use {.fun usethis::use_data} to add prepared data to package." )) } diff --git a/R/directory.R b/R/directory.R index 3ec9d5046..d65aa7c7c 100644 --- a/R/directory.R +++ b/R/directory.R @@ -58,7 +58,7 @@ directory_has_files <- function(x) { check_directory_is_empty <- function(x) { if (directory_has_files(x)) { - ui_abort("{.path {pth(path)}} exists and is not an empty directory.") + ui_abort("{.path {pth(x)}} exists and is not an empty directory.") } invisible(x) } diff --git a/R/documentation.R b/R/documentation.R index f66f25315..8052141f1 100644 --- a/R/documentation.R +++ b/R/documentation.R @@ -15,11 +15,15 @@ #' @export use_package_doc <- function(open = rlang::is_interactive()) { check_is_package("use_package_doc()") + use_directory("R") use_template( "packagename-package.R", package_doc_path(), open = open ) + ui_bullets(c( + "_" = "Run {.run devtools::document()} to update package-level documentation." + )) } package_doc_path <- function() { diff --git a/R/github-actions.R b/R/github-actions.R index c60a78ad0..e2c2d5f88 100644 --- a/R/github-actions.R +++ b/R/github-actions.R @@ -250,7 +250,7 @@ check_uses_github_actions <- function() { ui_abort(c( "Cannot detect that package {.pkg {project_name()}} already uses GitHub Actions.", - "Do you need to run {.fun use_github_action}?" + "Do you need to run {.run [use_github_action()](usethis::use_github_action())}?" )) } diff --git a/R/github_token.R b/R/github_token.R index f6c68bc0d..4cb02e7a4 100644 --- a/R/github_token.R +++ b/R/github_token.R @@ -199,7 +199,7 @@ pat_sitrep <- function(host = "https://github.com", git_user_check(user) if (!is.null(user$email) && !any(grepl(user$email, addresses))) { ui_bullets(c( - "x" = "Git user's email (.val {user$email}}) doesn't appear to be + "x" = "Git user's email ({.val {user$email}}) doesn't appear to be registered with GitHub host." )) } @@ -233,7 +233,7 @@ scold_for_renviron <- function() { old, invalid PAT defined in {.path {pth(renviron_path)}}.", "i" = "For most use cases, it is better to NOT define the PAT in {.file .Renviron}.", - "_" = "Call {.fun edit_r_environ} to edit that file.", + "_" = "Call {.run usethis::edit_r_environ()} to edit that file.", "_" = "Then call {.run gitcreds::gitcreds_set()} to put the PAT into the Git credential store." )) diff --git a/R/logo.R b/R/logo.R index e5d90584e..05fc59b34 100644 --- a/R/logo.R +++ b/R/logo.R @@ -48,7 +48,15 @@ use_logo <- function(img, geometry = "240x278", retina = TRUE) { height <- round(height / 2) } - ui_bullets(c("_" = "Add logo to your README with the following html:")) + # Have a clickable hyperlink to jump to README if exists. + readme_path <- find_readme() + if (is.null(readme_path)) { + readme_show <- "your README" + } else { + readme_show <- cli::format_inline("{.path {pth(readme_path)}}") + } + + ui_bullets(c("_" = "Add logo to {readme_show} with the following html:")) pd_link <- pkgdown_url(pedantic = TRUE) if (is.null(pd_link)) { ui_code_snippet( diff --git a/R/package.R b/R/package.R index 3c8ac4289..989efe0a8 100644 --- a/R/package.R +++ b/R/package.R @@ -180,7 +180,7 @@ suggests_usage_hint <- function(package) { ui_bullets(c("_" = "Then directly refer to functions with {.code {code}}.")) } else { code <- glue('requireNamespace("{package}", quietly = TRUE)') - ui_bullets(c("_" = "Use {.code {code}} to test if package is installed.")) + ui_bullets(c("_" = "Use {.code {code}} to test if {.pkg {package}} is installed.")) code <- glue("{package}::fun()") ui_bullets(c("_" = "Then directly refer to functions with {.code {code}}.")) } diff --git a/R/pr.R b/R/pr.R index abb496502..8e2e2933b 100644 --- a/R/pr.R +++ b/R/pr.R @@ -224,7 +224,7 @@ pr_init <- function(branch) { config_key <- glue("branch.{branch}.created-by") gert::git_config_set(config_key, value = "usethis::pr_init", repo = repo) - ui_bullets(c("_" = "Use {.fun pr_push} to create a PR.")) + ui_bullets(c("_" = "Use {.run usethis::pr_push()} to create a PR.")) invisible() } @@ -251,10 +251,10 @@ pr_resume <- function(branch = NULL) { check_string(branch) if (!gert::git_branch_exists(branch, local = TRUE, repo = repo)) { - code <- glue('pr_init("{branch}")') + code <- glue('usethis::pr_init("{branch}")') ui_abort(c( "x" = "No branch named {.val {branch}} exists.", - "_" = "Call {.code {code}} to create a new PR branch." + "_" = "Call {.run {code}} to create a new PR branch." )) } @@ -264,7 +264,7 @@ pr_resume <- function(branch = NULL) { gert::git_branch_checkout(branch, repo = repo) git_pull() - ui_bullets(c("_" = "Use {.fun usethis::pr_push} to create or update PR.")) + ui_bullets(c("_" = "Use {.run usethis::pr_push()} to create or update PR.")) invisible() } @@ -302,7 +302,7 @@ pr_fetch <- function(number = NULL, target = c("source", "primary")) { if (is.na(pr$pr_repo_owner)) { ui_abort(" - The repo or branch where PR #{pr$pr_number} originates seems to have been + The repo or branch where {.href [PR #{pr$pr_number}]({pr$pr_html_url})} originates seems to have been deleted.") } @@ -867,16 +867,17 @@ choose_branch <- function(exclude = character()) { ) prompt <- glue("{prompt}\n{fine_print}") } - dat$pretty_user <- glue_data(dat, "@{pr_user}") dat$pretty_name <- format(dat$name, justify = "right") dat_pretty <- purrr::pmap_chr( - dat[c("pretty_name", "pr_number", "pretty_user", "pr_title")], - function(pretty_name, pr_number, pretty_user, pr_title) { + dat[c("pretty_name", "pr_number", "pr_html_url", "pr_user", "pr_title")], + function(pretty_name, pr_number, pr_html_url, pr_user, pr_title) { if (is.na(pr_number)) { pretty_name } else { + href_number <- ui_pre_glue("{.href [PR #<>](<>)}") + at_user <- glue("@{pr_user}") template <- ui_pre_glue( - "{pretty_name} {cli::symbol$arrow_right} #{pr_number} ({.field <>}): {pr_title}" + "{pretty_name} {cli::symbol$arrow_right} <> ({.field <>}): {.val <>}" ) cli::format_inline(template) } @@ -916,18 +917,18 @@ choose_pr <- function(tr = NULL, pr_dat = NULL) { some_closed <- any(pr_dat$pr_state == "closed") pr_pretty <- purrr::pmap_chr( - pr_dat[c("pr_number", "pr_user", "pr_state", "pr_title")], - function(pr_number, pr_user, pr_state, pr_title) { - hash_number <- glue("#{pr_number}") + pr_dat[c("pr_number", "pr_html_url", "pr_user", "pr_state", "pr_title")], + function(pr_number, pr_html_url, pr_user, pr_state, pr_title) { + href_number <- ui_pre_glue("{.href [PR #<>](<>)}") at_user <- glue("@{pr_user}") if (some_closed) { template <- ui_pre_glue( - "{hash_number} ({.field <>}, {pr_state}): {.val <>}" + "<> ({.field <>}, {pr_state}): {.val <>}" ) cli::format_inline(template) } else { template <- ui_pre_glue( - "{hash_number} ({.field <>}): {.val <>}" + "<> ({.field <>}): {.val <>}" ) cli::format_inline(template) } @@ -1001,8 +1002,9 @@ check_pr_branch <- function(default_branch = git_default_branch()) { "i" = "The {.code pr_*()} functions facilitate pull requests.", "i" = "The current branch ({.val {gb}}) is this repo's default branch, but pull requests should NOT come from the default branch.", - "i" = "Do you need to call {.fun pr_init} (new PR)? Or {.fun pr_resume} or - {.fun pr_fetch} (existing PR)?" + "i" = "Do you need to call {.fun usethis::pr_init} (new PR)? + Or {.fun usethis::pr_resume} or + {.fun usethis::pr_fetch} (existing PR)?" ) ) } diff --git a/R/proj.R b/R/proj.R index 261373efe..0eca24320 100644 --- a/R/proj.R +++ b/R/proj.R @@ -214,8 +214,9 @@ check_is_package <- function(whos_asking = NULL) { message <- "Project {.val {project_name()}} is not an R package." if (!is.null(whos_asking)) { + whos_asking_fn <- sub("()", "", whos_asking, fixed = TRUE) message <- c( - "i" = "{.code {whos_asking}} is designed to work with packages.", + "i" = "{.topic [{whos_asking}](usethis::{whos_asking_fn})} is designed to work with packages.", "x" = message ) } diff --git a/R/roxygen.R b/R/roxygen.R index de1727b12..7822f4f90 100644 --- a/R/roxygen.R +++ b/R/roxygen.R @@ -42,7 +42,7 @@ use_roxygen_md <- function(overwrite = FALSE) { the conversion process." )) } - ui_bullets(c("v" = "Run {.run devtools::document()} when you're done.")) + ui_bullets(c("_" = "Run {.run devtools::document()} when you're done.")) return(invisible()) } diff --git a/R/tibble.R b/R/tibble.R index abb00b5fb..280df9259 100644 --- a/R/tibble.R +++ b/R/tibble.R @@ -13,7 +13,7 @@ #' * Prepare the roxygen directive necessary to import at least one function #' from tibble: #' - If possible, the directive is inserted into existing package-level -#' documentation, i.e. the roxygen snippet created by [use_package_doc()] +#' documentation, i.e. the roxygen snippet created by [use_package_doc()] #' - Otherwise, we issue advice on where the user should add the directive #' #' This is necessary when your package returns a stored data object that has diff --git a/R/tidyverse.R b/R/tidyverse.R index 4daa46b88..0e101e413 100644 --- a/R/tidyverse.R +++ b/R/tidyverse.R @@ -85,15 +85,15 @@ create_tidy_package <- function(path, copyright_holder = NULL) { use_cran_comments(open = FALSE) - ui_bullets(c( - "i" = "In the new package, remember to do:", - "_" = "{.run usethis::use_git()}", - "_" = "{.run usethis::use_github()}", - "_" = "{.run usethis::use_tidy_github()}", - "_" = "{.run usethis::use_tidy_github_actions()}", - "_" = "{.run usethis::use_tidy_github_labels()}", - "_" = "{.run usethis::use_pkgdown_github_pages()}" - )) + ui_bullets(c("i" = "In the new package, remember to do:")) + ui_code_snippet(" + usethis::use_git() + usethis::use_github() + usethis::use_tidy_github() + usethis::use_tidy_github_actions() + usethis::use_tidy_github_labels() + usethis::use_pkgdown_github_pages() + ") proj_activate(path) } diff --git a/README.md b/README.md index de29e6036..a68a2b255 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ library(usethis) # Create a new package ------------------------------------------------- path <- file.path(tempdir(), "mypkg") create_package(path) -#> ✔ Creating '/tmp/Rtmp7yJh5e/mypkg/'. -#> ✔ Setting active project to "/private/tmp/Rtmp7yJh5e/mypkg". +#> ✔ Creating '/tmp/RtmpMuqeSm/mypkg/'. +#> ✔ Setting active project to "/private/tmp/RtmpMuqeSm/mypkg". #> ✔ Creating 'R/'. #> ✔ Writing 'DESCRIPTION'. #> Package: mypkg @@ -80,8 +80,8 @@ create_package(path) #> ✔ Setting active project to "". # only needed since this session isn't interactive proj_activate(path) -#> ✔ Setting active project to "/private/tmp/Rtmp7yJh5e/mypkg". -#> ✔ Changing working directory to '/tmp/Rtmp7yJh5e/mypkg/' +#> ✔ Setting active project to "/private/tmp/RtmpMuqeSm/mypkg". +#> ✔ Changing working directory to '/tmp/RtmpMuqeSm/mypkg/' # Modify the description ---------------------------------------------- use_mit_license("My Name") @@ -92,7 +92,7 @@ use_mit_license("My Name") use_package("ggplot2", "Suggests") #> ✔ Adding ggplot2 to 'Suggests' field in DESCRIPTION. -#> ☐ Use `requireNamespace("ggplot2", quietly = TRUE)` to test if package is +#> ☐ Use `requireNamespace("ggplot2", quietly = TRUE)` to test if ggplot2 is #> installed. #> ☐ Then directly refer to functions with `ggplot2::fun()`. diff --git a/man/use_tibble.Rd b/man/use_tibble.Rd index ebd499e6a..3d1388e36 100644 --- a/man/use_tibble.Rd +++ b/man/use_tibble.Rd @@ -20,7 +20,7 @@ object with class \code{tbl_df}. Specifically: from tibble: \itemize{ \item If possible, the directive is inserted into existing package-level -documentation, i.e. the roxygen snippet created by \code{\link[=use_package_doc]{use_package_doc()}} +documentation, i.e. the roxygen snippet created by \code{\link[=use_package_doc]{use_package_doc()}} \item Otherwise, we issue advice on where the user should add the directive } } diff --git a/tests/testthat/_snaps/logo.md b/tests/testthat/_snaps/logo.md new file mode 100644 index 000000000..39b3791e5 --- /dev/null +++ b/tests/testthat/_snaps/logo.md @@ -0,0 +1,10 @@ +# use_logo() shows a clickable path with README + + Code + use_logo("logo.png") + Message + v Creating 'man/figures/'. + v Resized 'logo.png' to 240x278. + [ ] Add logo to 'README.md' with the following html: + # {TESTPKG} + diff --git a/tests/testthat/_snaps/package.md b/tests/testthat/_snaps/package.md index 96501fa5e..d6de8b628 100644 --- a/tests/testthat/_snaps/package.md +++ b/tests/testthat/_snaps/package.md @@ -47,7 +47,7 @@ use_package("withr", "Suggests") Message v Adding withr to 'Suggests' field in DESCRIPTION. - [ ] Use `requireNamespace("withr", quietly = TRUE)` to test if package is + [ ] Use `requireNamespace("withr", quietly = TRUE)` to test if withr is installed. [ ] Then directly refer to functions with `withr::fun()`. diff --git a/tests/testthat/_snaps/proj.md b/tests/testthat/_snaps/proj.md index a54abb4d3..2d90f6aa1 100644 --- a/tests/testthat/_snaps/proj.md +++ b/tests/testthat/_snaps/proj.md @@ -1,3 +1,12 @@ +# check_is_package() can reveal who's asking + + Code + check_is_package("foo()") + Condition + Error in `check_is_package()`: + i foo() (`?usethis::foo`) is designed to work with packages. + x Project "{TESTPROJ}" is not an R package. + # proj_path() errors with absolute paths Code diff --git a/tests/testthat/_snaps/roxygen.md b/tests/testthat/_snaps/roxygen.md index 548c6a0fb..90b0198a4 100644 --- a/tests/testthat/_snaps/roxygen.md +++ b/tests/testthat/_snaps/roxygen.md @@ -4,6 +4,7 @@ use_package_doc() Message v Writing 'R/{TESTPKG}-package.R'. + [ ] Run `devtools::document()` to update package-level documentation. --- diff --git a/tests/testthat/_snaps/tidyverse.md b/tests/testthat/_snaps/tidyverse.md index dcb9680d6..68d674670 100644 --- a/tests/testthat/_snaps/tidyverse.md +++ b/tests/testthat/_snaps/tidyverse.md @@ -10,8 +10,7 @@ v Adding withr to 'Imports' field in DESCRIPTION. v Adding "@import rlang" to 'R/{TESTPKG}-package.R'. v Adding "@importFrom glue glue" to 'R/{TESTPKG}-package.R'. - v Adding "@importFrom lifecycle deprecated" to - 'R/{TESTPKG}-package.R'. + v Adding "@importFrom lifecycle deprecated" to 'R/{TESTPKG}-package.R'. v Writing 'NAMESPACE'. v Writing 'R/import-standalone-purrr.R'. diff --git a/tests/testthat/_snaps/upkeep.md b/tests/testthat/_snaps/upkeep.md index f7aad90e3..af2df5d58 100644 --- a/tests/testthat/_snaps/upkeep.md +++ b/tests/testthat/_snaps/upkeep.md @@ -52,7 +52,7 @@ ### To finish * [ ] `usethis::use_mit_license()` - * [ ] `usethis::use_package("R", "Depends", "3.6")` + * [ ] `usethis::use_package("R", "Depends", "4.0")` * [ ] `usethis::use_tidy_description()` * [ ] `usethis::use_tidy_github_actions()` * [ ] `devtools::build_readme()` diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index ff3f76c6b..0469caa17 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -82,6 +82,10 @@ scrub_testpkg <- function(message) { gsub("testpkg[a-zA-Z0-9]+", "{TESTPKG}", message, perl = TRUE) } +scrub_testproj <- function(message) { + gsub("testproj[a-zA-Z0-9]+", "{TESTPROJ}", message, perl = TRUE) +} + skip_if_not_ci <- function() { ci_providers <- c("GITHUB_ACTIONS", "TRAVIS", "APPVEYOR") ci <- any(toupper(Sys.getenv(ci_providers)) == "TRUE") diff --git a/tests/testthat/test-github-actions.R b/tests/testthat/test-github-actions.R index 808f3a173..a42de3f4a 100644 --- a/tests/testthat/test-github-actions.R +++ b/tests/testthat/test-github-actions.R @@ -78,7 +78,7 @@ test_that("uses_github_action() reports usage of GitHub Actions", { test_that("check_uses_github_actions() can throw error", { create_local_package() - withr::local_options(list(crayon.enabled = FALSE)) + withr::local_options(list(crayon.enabled = FALSE, cli.width = Inf)) expect_snapshot( check_uses_github_actions(), error = TRUE, diff --git a/tests/testthat/test-logo.R b/tests/testthat/test-logo.R index 4051e17a7..a84475ac3 100644 --- a/tests/testthat/test-logo.R +++ b/tests/testthat/test-logo.R @@ -1,4 +1,4 @@ -test_that("use_logo() doesn't error", { +test_that("use_logo() doesn't error with no README", { skip_if_not_installed("magick") skip_on_os("solaris") @@ -6,3 +6,14 @@ test_that("use_logo() doesn't error", { img <- magick::image_write(magick::image_read("logo:"), "logo.png") expect_no_error(use_logo("logo.png")) }) + +test_that("use_logo() shows a clickable path with README", { + skip_if_not_installed("magick") + skip_on_os("solaris") + + create_local_package() + use_readme_md() + img <- magick::image_write(magick::image_read("logo:"), "logo.png") + withr::local_options(usethis.quiet = FALSE) + expect_snapshot(use_logo("logo.png"), transform = scrub_testpkg) +}) diff --git a/tests/testthat/test-proj.R b/tests/testthat/test-proj.R index 1c9be852a..c2bf4a20c 100644 --- a/tests/testthat/test-proj.R +++ b/tests/testthat/test-proj.R @@ -36,7 +36,11 @@ test_that("check_is_package() errors for non-package", { test_that("check_is_package() can reveal who's asking", { create_local_project() - expect_usethis_error(check_is_package("foo"), "foo") + expect_snapshot( + error = TRUE, + check_is_package("foo()"), + transform = scrub_testproj + ) }) test_that("proj_path() appends to the project path", { diff --git a/tests/testthat/test-tidyverse.R b/tests/testthat/test-tidyverse.R index 45246cd97..057480121 100644 --- a/tests/testthat/test-tidyverse.R +++ b/tests/testthat/test-tidyverse.R @@ -17,7 +17,7 @@ test_that("use_tidy_dependencies() isn't overly informative", { create_local_package() use_package_doc() - withr::local_options(usethis.quiet = FALSE) + withr::local_options(usethis.quiet = FALSE, cli.width = Inf) expect_snapshot( use_tidy_dependencies(),