From 1096076120cbcf555fbd56b32d0b65559b3845a4 Mon Sep 17 00:00:00 2001 From: Brian Maitner Date: Mon, 19 Oct 2026 13:56:16 -0400 Subject: [PATCH 1/3] Let R-hub install rWCVPdata from its drat repository Every R-hub platform failed while installing dependencies: "Can't find package called rWCVPdata". R-hub installs with pak, which doesn't read DESCRIPTION's Additional_repositories. A step before setup-deps in both jobs now adds the drat repository to the R user profile, loading utils first so the platform's own repositories are kept. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/rhub.yaml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/rhub.yaml b/.github/workflows/rhub.yaml index 74ec7b0..5aebdb0 100644 --- a/.github/workflows/rhub.yaml +++ b/.github/workflows/rhub.yaml @@ -5,6 +5,11 @@ # rhub::rhub_setup() # # It is unlikely that you need to modify this file manually. +# +# NSR modification: the "Add the drat repository" step in both jobs below, so +# pak can install rWCVPdata (Suggests), which isn't on CRAN. pak does not read +# DESCRIPTION's Additional_repositories. Keep that step if this file is +# regenerated with rhub::rhub_setup(). name: R-hub run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" @@ -56,6 +61,20 @@ jobs: with: token: ${{ secrets.RHUB_TOKEN }} job-config: ${{ matrix.config.job-config }} + - name: Add the drat repository for rWCVPdata + run: | + # rWCVPdata (Suggests) isn't on CRAN: add the repository named in + # DESCRIPTION's Additional_repositories to every later R session. + # utils is loaded first because 'repos' isn't set yet while profiles + # run, and utils won't set its defaults once something else has. + f <- Sys.getenv("R_PROFILE_USER") + if (!nzchar(f)) f <- path.expand("~/.Rprofile") + line <- paste('local({ loadNamespace("utils");', + 'options(repos = c(getOption("repos"),', + 'rWCVPdata = "https://matildabrown.github.io/drat")) })') + write(line, file = f, append = TRUE) + message("Added to ", f, ": ", line) + shell: Rscript {0} - uses: r-hub/actions/setup-deps@v1 with: token: ${{ secrets.RHUB_TOKEN }} @@ -85,6 +104,20 @@ jobs: with: token: ${{ secrets.RHUB_TOKEN }} job-config: ${{ matrix.config.job-config }} + - name: Add the drat repository for rWCVPdata + run: | + # rWCVPdata (Suggests) isn't on CRAN: add the repository named in + # DESCRIPTION's Additional_repositories to every later R session. + # utils is loaded first because 'repos' isn't set yet while profiles + # run, and utils won't set its defaults once something else has. + f <- Sys.getenv("R_PROFILE_USER") + if (!nzchar(f)) f <- path.expand("~/.Rprofile") + line <- paste('local({ loadNamespace("utils");', + 'options(repos = c(getOption("repos"),', + 'rWCVPdata = "https://matildabrown.github.io/drat")) })') + write(line, file = f, append = TRUE) + message("Added to ", f, ": ", line) + shell: Rscript {0} - uses: r-hub/actions/setup-deps@v1 with: job-config: ${{ matrix.config.job-config }} From 09831db1c634316766842bd9def37577787995d9 Mon Sep 17 00:00:00 2001 From: Brian Maitner Date: Mon, 19 Oct 2026 14:43:28 -0400 Subject: [PATCH 2/3] Drop BIEN from Suggests BIEN was suggested only for the \dontrun example of the deprecated, unexported NSR_from_coordinates(). It imports RPostgreSQL, which failed to compile on R-hub's Fedora platforms (atlas, nosuggests) for lack of the PostgreSQL headers, stopping both before R CMD check ran. The example now builds its input as a data frame. Co-Authored-By: Claude Opus 5.5 --- DESCRIPTION | 1 - R/NSR_from_coordinates.R | 48 +++++++------------------------------ man/NSR_from_coordinates.Rd | 48 +++++++------------------------------ 3 files changed, 18 insertions(+), 79 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0e5ddea..46ea85a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,7 +28,6 @@ Suggests: terra, testthat, devtools, - BIEN, TNRS, vcr (>= 0.6.0), withr diff --git a/R/NSR_from_coordinates.R b/R/NSR_from_coordinates.R index d5af1b7..eca57aa 100644 --- a/R/NSR_from_coordinates.R +++ b/R/NSR_from_coordinates.R @@ -18,48 +18,18 @@ #' @import httr #' @keywords internal #' @examples \dontrun{ -#'library(BIEN) +#'# Species and coordinates, with an id for each record +#'occs <- data.frame(species = c("Acer rubrum", "Acer rubrum", "Acer platanoides"), +#' latitude = c(45.50, 51.51, 45.50), +#' longitude = c(-73.57, -0.13, -73.57), +#' id = c("1", "2", "3")) #' -#'# Get some data +#'results <- NSR:::NSR_from_coordinates(occurrence_dataframe = occs) #' -#'ar_occs <- BIEN_occurrence_species(species = "Acer rubrum", -#' natives.only = FALSE, -#' political.boundaries = TRUE, -#' limit=100) +#'# Join the results back to the input +#'merge(occs, results, by.x = "id", by.y = "input_id") +#'} #' -#' -#'# Rename columns so that we can differentiate between coordinates declared -#'# and coordinates inferred -#' -#'colnames(ar_occs)[which(colnames(ar_occs)=="country")] <- "country_declared" -#'colnames(ar_occs)[which(colnames(ar_occs)=="state_province")] <- "state_declared" -#'colnames(ar_occs)[which(colnames(ar_occs)=="county")] <- "county_declared" -#' -#'# Select needed fields and add an ID column -#' -#'ar_occs_subset <- ar_occs[c("scrubbed_species_binomial","latitude","longitude")] -#' -#'# Toss duplicates (speeds up processing) -#' -#'ar_occs_subset <- unique(ar_occs_subset) -#' -#'# Add an id column -#' -#'ar_occs_subset$id <- as.character(1:nrow(ar_occs_subset)) -#' -#'# Get results -#' -#'results_ar <- NSR:::NSR_from_coordinates(occurrence_dataframe = ar_occs_subset) -#' -#'# Join results back to original data -#' -#'results_ar <- ar_occs_subset |> -#' merge(y = results_ar,by.x = c("id"), -#' by.y = c("input_id")) -#' -#'ar_occs <- ar_occs |> merge(results_ar, -#' by = c("latitude","longitude","scrubbed_species_binomial")) -#' } NSR_from_coordinates <- function(occurrence_dataframe, ...){ diff --git a/man/NSR_from_coordinates.Rd b/man/NSR_from_coordinates.Rd index 9774d51..2bbe9c4 100644 --- a/man/NSR_from_coordinates.Rd +++ b/man/NSR_from_coordinates.Rd @@ -31,47 +31,17 @@ The coordinates service is separate from the main NSR API. Its address can be } \examples{ \dontrun{ -library(BIEN) +# Species and coordinates, with an id for each record +occs <- data.frame(species = c("Acer rubrum", "Acer rubrum", "Acer platanoides"), + latitude = c(45.50, 51.51, 45.50), + longitude = c(-73.57, -0.13, -73.57), + id = c("1", "2", "3")) -# Get some data +results <- NSR:::NSR_from_coordinates(occurrence_dataframe = occs) -ar_occs <- BIEN_occurrence_species(species = "Acer rubrum", - natives.only = FALSE, - political.boundaries = TRUE, - limit=100) - - -# Rename columns so that we can differentiate between coordinates declared -# and coordinates inferred - -colnames(ar_occs)[which(colnames(ar_occs)=="country")] <- "country_declared" -colnames(ar_occs)[which(colnames(ar_occs)=="state_province")] <- "state_declared" -colnames(ar_occs)[which(colnames(ar_occs)=="county")] <- "county_declared" - -# Select needed fields and add an ID column - -ar_occs_subset <- ar_occs[c("scrubbed_species_binomial","latitude","longitude")] - -# Toss duplicates (speeds up processing) - -ar_occs_subset <- unique(ar_occs_subset) - -# Add an id column - -ar_occs_subset$id <- as.character(1:nrow(ar_occs_subset)) - -# Get results - -results_ar <- NSR:::NSR_from_coordinates(occurrence_dataframe = ar_occs_subset) - -# Join results back to original data - -results_ar <- ar_occs_subset |> - merge(y = results_ar,by.x = c("id"), - by.y = c("input_id")) - -ar_occs <- ar_occs |> merge(results_ar, - by = c("latitude","longitude","scrubbed_species_binomial")) +# Join the results back to the input +merge(occs, results, by.x = "id", by.y = "input_id") } + } \keyword{internal} From a481b3ce9c77d06d59b7c654427db0516743f0f1 Mon Sep 17 00:00:00 2001 From: Brian Maitner Date: Mon, 19 Oct 2026 16:03:00 -0400 Subject: [PATCH 3/3] Pass R CMD check without suggested packages R-hub's nosuggests platform, like CRAN's no-Suggests checks, runs with only Depends, Imports, VignetteBuilder and testthat available, and failed twice: - The tests stopped in setup-nsr.R, which loaded vcr unconditionally. vcr is now set up only when installed, and each test replaying a recorded API response skips itself without it. - The vignette couldn't be rebuilt: its knitr::rmarkdown engine needs rmarkdown, which was only in Suggests. rmarkdown is now also listed in VignetteBuilder, so it's available in these checks. R CMD check --as-cran with _R_CHECK_DEPENDS_ONLY_=true now passes locally. Co-Authored-By: Claude Opus 5.5 --- DESCRIPTION | 2 +- tests/testthat/setup-nsr.R | 14 +++++++++----- tests/testthat/test-NSR.R | 2 ++ tests/testthat/test-NSR_citations.R | 2 ++ tests/testthat/test-NSR_data_dictionary.R | 4 ++++ tests/testthat/test-NSR_political_divisions.R | 4 ++++ tests/testthat/test-NSR_simple.R | 4 ++++ tests/testthat/test-NSR_sources.R | 2 ++ tests/testthat/test-NSR_version.R | 2 ++ 9 files changed, 30 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 46ea85a..dbdb37e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -32,5 +32,5 @@ Suggests: vcr (>= 0.6.0), withr Additional_repositories: https://matildabrown.github.io/drat -VignetteBuilder: knitr +VignetteBuilder: knitr, rmarkdown RoxygenNote: 7.3.3 diff --git a/tests/testthat/setup-nsr.R b/tests/testthat/setup-nsr.R index 189d76e..f441c3b 100644 --- a/tests/testthat/setup-nsr.R +++ b/tests/testthat/setup-nsr.R @@ -9,10 +9,14 @@ url <- "https://nsrapi.xyz/nsr_wsb.php" # production # url <- "www.google.com" # url <- "www.hisstank.com" -library("vcr") # *Required* as vcr is set up on loading +# vcr is in Suggests: without it (as in CRAN's no-Suggests checks) the tests that replay +# recorded API responses skip themselves +if (requireNamespace("vcr", quietly = TRUE)) { + library("vcr") # *Required* as vcr is set up on loading -invisible(vcr::vcr_configure( - dir = vcr::vcr_test_path("fixtures") -)) + invisible(vcr::vcr_configure( + dir = vcr::vcr_test_path("fixtures") + )) -vcr::check_cassette_names() + vcr::check_cassette_names() +} diff --git a/tests/testthat/test-NSR.R b/tests/testthat/test-NSR.R index d42ed9e..fe4ecf1 100644 --- a/tests/testthat/test-NSR.R +++ b/tests/testthat/test-NSR.R @@ -4,6 +4,8 @@ context("nsr main") test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_example", { results <- NSR(occurrence_dataframe = nsr_testfile, diff --git a/tests/testthat/test-NSR_citations.R b/tests/testthat/test-NSR_citations.R index eeb3e7f..65d505a 100644 --- a/tests/testthat/test-NSR_citations.R +++ b/tests/testthat/test-NSR_citations.R @@ -5,6 +5,8 @@ test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_citations", { citation_info <- NSR_citations( url = url, diff --git a/tests/testthat/test-NSR_data_dictionary.R b/tests/testthat/test-NSR_data_dictionary.R index 67fce11..cee12ab 100644 --- a/tests/testthat/test-NSR_data_dictionary.R +++ b/tests/testthat/test-NSR_data_dictionary.R @@ -5,6 +5,8 @@ test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_dd", { NSR_fields <- NSR_data_dictionary(url = url, @@ -22,6 +24,8 @@ test_that("example2 works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_dd_status", { NSR_status <- NSR_data_dictionary(native_status = TRUE, diff --git a/tests/testthat/test-NSR_political_divisions.R b/tests/testthat/test-NSR_political_divisions.R index a81b111..9f99658 100644 --- a/tests/testthat/test-NSR_political_divisions.R +++ b/tests/testthat/test-NSR_political_divisions.R @@ -3,6 +3,8 @@ context("nsr pol divs") test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_poldivs", { nsr_poldivs <- NSR_political_divisions(by_country = TRUE) @@ -22,6 +24,8 @@ test_that("example works", { test_that("example 2 works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_checklist", { nsr_checklists <- NSR_political_divisions(by_country = FALSE) diff --git a/tests/testthat/test-NSR_simple.R b/tests/testthat/test-NSR_simple.R index 9095b88..8527bb7 100644 --- a/tests/testthat/test-NSR_simple.R +++ b/tests/testthat/test-NSR_simple.R @@ -4,6 +4,8 @@ context("nsr simple") test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_simple_example", { results <- NSR_simple(species = "Acer rubrum", @@ -25,6 +27,8 @@ test_that("example works", { test_that("second example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_simple_example2", { results2 <- NSR_simple(species = c("Acer rubrum", "Aspen tremuloides") , diff --git a/tests/testthat/test-NSR_sources.R b/tests/testthat/test-NSR_sources.R index b5110cb..8ea7433 100644 --- a/tests/testthat/test-NSR_sources.R +++ b/tests/testthat/test-NSR_sources.R @@ -5,6 +5,8 @@ test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_sources", { sources <- NSR_sources( url = url, diff --git a/tests/testthat/test-NSR_version.R b/tests/testthat/test-NSR_version.R index 1416107..f6cc2ef 100644 --- a/tests/testthat/test-NSR_version.R +++ b/tests/testthat/test-NSR_version.R @@ -4,6 +4,8 @@ context("nsr version") test_that("example works", { # skip_if_offline(host = "r-project.org") + skip_if_not_installed("vcr") + vcr::use_cassette("nsr_version", { NSR_version_metadata <- NSR_version( url = url,