diff --git a/NEWS.md b/NEWS.md index 9c2d1d782..c9bf0c24c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ * New `check_mac_devel()` function to check a package using the macOS builder at https://mac.r-project.org/macbuilder/submit.html (@nfrerebeau, #2507) * `is_loading()` is now re-exported from pkgload (#2556). * `load_all()` now errors if called recursively, i.e. if you accidentally include a `load_all()` call in one of your R source files (#2617). +* `show_news()` now looks for NEWS files in the same locations as `utils::news()`: `inst/NEWS.Rd`, `NEWS.md`, `NEWS`, and `inst/NEWS` (@arcresu, #2499). # devtools 2.4.6 diff --git a/R/show-news.R b/R/show-news.R index 3af181eab..15cbc6411 100644 --- a/R/show-news.R +++ b/R/show-news.R @@ -7,18 +7,25 @@ #' @export show_news <- function(pkg = ".", latest = TRUE, ...) { pkg <- as.package(pkg) - news_path <- path(pkg$path, "NEWS") + news_path <- find_news(pkg$path) - if (!file_exists(news_path)) { - cli::cli_abort("No NEWS found") - } + withCallingHandlers( + { + news_db <- switch( + path_ext(news_path), + Rd = ("tools" %:::% ".build_news_db_from_package_NEWS_Rd")(news_path), + md = ("tools" %:::% ".build_news_db_from_package_NEWS_md")(news_path), + ("tools" %:::% ".news_reader_default")(news_path) + ) + }, + error = function(e) { + cli::cli_abort("Failed to parse NEWS file.", parent = e) + } + ) check_dots_used(action = getOption("devtools.ellipsis_action", rlang::warn)) - out <- utils::news( - ..., - db = ("tools" %:::% ".news_reader_default")(news_path) - ) + out <- utils::news(..., db = news_db) if (latest) { ver <- numeric_version(out$Version) recent <- ver == max(ver) @@ -27,3 +34,19 @@ show_news <- function(pkg = ".", latest = TRUE, ...) { out } } + +find_news <- function(path) { + news_paths <- c( + file.path(path, "inst", "NEWS.Rd"), + file.path(path, "NEWS.md"), + file.path(path, "NEWS"), + file.path(path, "inst", "NEWS") + ) + news_path <- news_paths[file_exists(news_paths)] + + if (length(news_path) == 0) { + cli::cli_abort("Failed to find NEWS file.") + } + + path_abs(news_path[[1]]) +} diff --git a/tests/testthat/_snaps/show-news.md b/tests/testthat/_snaps/show-news.md new file mode 100644 index 000000000..acc660f98 --- /dev/null +++ b/tests/testthat/_snaps/show-news.md @@ -0,0 +1,18 @@ +# fails when NEWS is missing or improperly formatted + + Code + show_news(pkg) + Condition + Error in `find_news()`: + ! Failed to find NEWS file. + +--- + + Code + show_news(pkg) + Condition + Error in `show_news()`: + ! Failed to parse NEWS file. + Caused by error: + ! NEWS.Rd: Sections \title, and \name must exist and be unique in Rd files + diff --git a/tests/testthat/test-show-news.R b/tests/testthat/test-show-news.R new file mode 100644 index 000000000..3691da53f --- /dev/null +++ b/tests/testthat/test-show-news.R @@ -0,0 +1,29 @@ +test_that("find_news() finds NEWS in all expected locations", { + pkg <- local_package_create() + + dir_create(pkg, "inst") + file_create(pkg, "inst", "NEWS") + expect_equal(path_rel(find_news(pkg), pkg), path("inst/NEWS")) + + file_create(pkg, "NEWS") + expect_equal(path_rel(find_news(pkg), pkg), path("NEWS")) + + file_create(pkg, "NEWS.md") + expect_equal(path_rel(find_news(pkg), pkg), path("NEWS.md")) + + file_create(pkg, "inst", "NEWS.Rd") + expect_equal(path_rel(find_news(pkg), pkg), path("inst/NEWS.Rd")) +}) + +test_that("fails when NEWS is missing or improperly formatted", { + skip_on_cran() + skip_unless_r(">= 4.2.0") # different error message + + pkg <- local_package_create() + expect_snapshot(show_news(pkg), error = TRUE) + + dir_create(pkg, "inst") + file_create(pkg, "inst", "NEWS.Rd") + + expect_snapshot(show_news(pkg), error = TRUE) +})