From a690436cb062a473fad590220a24ce45cb1c08e7 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 10:06:41 -0400 Subject: [PATCH 01/17] Change qa repo link --- R/record_versions.R | 4 ++-- man/get_current_versions.Rd | 2 +- man/record_versions.Rd | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/record_versions.R b/R/record_versions.R index c95bdc67..6ff9f187 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -15,7 +15,7 @@ #' in `repo`. This argument is exposed for testing only. record_versions <- function( manifest = "versions.json", - repo = "https://r-multiverse.r-universe.dev", + repo = "https://multiverse.r-multiverse.org", current = multiverse.internals::get_current_versions(repo = repo) ) { if (!file.exists(manifest)) { @@ -35,7 +35,7 @@ record_versions <- function( #' @return A data frame of packages with their current versions and hashes. #' @inheritParams record_versions get_current_versions <- function( - repo = "https://r-multiverse.r-universe.dev" + repo = "https://multiverse.r-multiverse.org" ) { listing <- file.path( contrib.url(repos = repo, type = "source"), diff --git a/man/get_current_versions.Rd b/man/get_current_versions.Rd index e66f8e4b..2821199b 100644 --- a/man/get_current_versions.Rd +++ b/man/get_current_versions.Rd @@ -4,7 +4,7 @@ \alias{get_current_versions} \title{Get the current versions of packages} \usage{ -get_current_versions(repo = "https://r-multiverse.r-universe.dev") +get_current_versions(repo = "https://multiverse.r-multiverse.org") } \arguments{ \item{repo}{Character string of package repositories to track.} diff --git a/man/record_versions.Rd b/man/record_versions.Rd index 20cd9853..85d7c439 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -6,7 +6,7 @@ \usage{ record_versions( manifest = "versions.json", - repo = "https://r-multiverse.r-universe.dev", + repo = "https://multiverse.r-multiverse.org", current = multiverse.internals::get_current_versions(repo = repo) ) } From c78753103de944ef8161f6bee842007347f48c47 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 11:43:42 -0400 Subject: [PATCH 02/17] Check descriptions --- NAMESPACE | 2 + R/check_descriptions.R | 37 ++++++++++++ R/check_versions.R | 65 ++++++++++++++++++++ R/record_issues.R | 20 +------ R/record_versions.R | 20 ++----- R/utils_check.R | 24 ++++++++ R/utils_logic.R | 15 +++++ man/check_descriptions.Rd | 36 ++++++++++++ man/check_versions.Rd | 75 ++++++++++++++++++++++++ man/record_issues.Rd | 5 +- tests/testthat/test-check_descriptions.R | 40 +++++++++++++ tests/testthat/test-check_versions.R | 58 ++++++++++++++++++ tests/testthat/test-record_issues.R | 72 +---------------------- tests/testthat/test-utils_logic.R | 11 ++++ 14 files changed, 373 insertions(+), 107 deletions(-) create mode 100644 R/check_descriptions.R create mode 100644 R/check_versions.R create mode 100644 R/utils_check.R create mode 100644 R/utils_logic.R create mode 100644 man/check_descriptions.Rd create mode 100644 man/check_versions.Rd create mode 100644 tests/testthat/test-check_descriptions.R create mode 100644 tests/testthat/test-check_versions.R create mode 100644 tests/testthat/test-utils_logic.R diff --git a/NAMESPACE b/NAMESPACE index 6a2bdc10..022ee8e1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,8 @@ export(aggregate_contributions) export(assert_cran_url) export(assert_package) export(assert_release_exists) +export(check_descriptions) +export(check_versions) export(get_current_versions) export(record_issues) export(record_versions) diff --git a/R/check_descriptions.R b/R/check_descriptions.R new file mode 100644 index 00000000..3751b2e8 --- /dev/null +++ b/R/check_descriptions.R @@ -0,0 +1,37 @@ +#' @title Check package `DESCRIPTION` files. +#' @export +#' @description Check the `DESCRIPTION` files of packages for specific +#' issues. +#' @details This function scrapes the `src/contrib/PACKAGES.json` file +#' of the universe to check the data in the `DESCRIPTION` files of packages +#' for compliance. Right now, the only field checked is `Remotes:`. +#' A packages with a `Remotes:` field in the `DESCRIPTION` file may +#' depend on development versions of other packages and so are +#' excluded from the production universe. +#' @return A named list of information about packages which do not comply +#' with `DESCRPTION` checks. Each name is a package name, +#' and each element contains specific information about +#' non-compliance. +#' @param repo Character of length 1, URL of the repository +#' of R package candidates for production. +#' @param index For testing purposes only, +#' an optional pre-computed data frame with the package index. +#' @examples +#' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +check_descriptions <- function( + repo = "https://multiverse.r-multiverse.org", + index = NULL +) { + fields <- "Remotes" + index <- index %|||% get_package_index(repo = repo, fields = fields) + index <- check_descriptions_remotes(index) + index <- index[, c("Package", fields)] + colnames(index) <- tolower(colnames(index)) + check_list(index) +} + +check_descriptions_remotes <- function(index) { + index$Remotes <- index$Remotes %|||% replicate(nrow(index), NULL) + index$Remotes <- lapply(index$Remotes, function(x) x[nzchar(x)]) + index[vapply(index$Remotes, length, integer(1L)) > 0L, ] +} diff --git a/R/check_versions.R b/R/check_versions.R new file mode 100644 index 00000000..3c9eb11b --- /dev/null +++ b/R/check_versions.R @@ -0,0 +1,65 @@ +#' @title Check package versions. +#' @export +#' @description Check package version number history for compliance. +#' @details This function checks the version number history of packages +#' in R-multiverse and reports any packages with issues. The current +#' released version of a given package must be unique, and it must be +#' greater than all the versions of all the previous package releases. +#' @section Checks: +#' Functions like [check_versions()] and [check_descriptions()] check +#' the packages in . Only packages +#' that pass these checks will appear in +#' . +#' @return A named list of information about packages which do not comply +#' with version number history checks. Each name is a package name, +#' and each element contains specific information about version +#' non-compliance: the current version number, the current version hash, +#' and the analogous versions and hashes of the highest-versioned +#' release recorded. +#' @param versions Character of length 1, file path to a JSON manifest +#' tracking the history of released versions of packages. +#' @examples +#' lines <- c( +#' "[", +#' " {", +#' " \"package\": \"package_unmodified\",", +#' " \"version_current\": \"1.0.0\",", +#' " \"hash_current\": \"hash_1.0.0\",", +#' " \"version_highest\": \"1.0.0\",", +#' " \"hash_highest\": \"hash_1.0.0\"", +#' " },", +#' " {", +#' " \"package\": \"version_decremented\",", +#' " \"version_current\": \"0.0.1\",", +#' " \"hash_current\": \"hash_0.0.1\",", +#' " \"version_highest\": \"1.0.0\",", +#' " \"hash_highest\": \"hash_1.0.0\"", +#' " },", +#' " {", +#' " \"package\": \"version_incremented\",", +#' " \"version_current\": \"2.0.0\",", +#' " \"hash_current\": \"hash_2.0.0\",", +#' " \"version_highest\": \"2.0.0\",", +#' " \"hash_highest\": \"hash_2.0.0\"", +#' " },", +#' " {", +#' " \"package\": \"version_unmodified\",", +#' " \"version_current\": \"1.0.0\",", +#' " \"hash_current\": \"hash_1.0.0-modified\",", +#' " \"version_highest\": \"1.0.0\",", +#' " \"hash_highest\": \"hash_1.0.0\"", +#' " }", +#' "]" +#' ) +#' versions <- tempfile() +#' writeLines(lines, versions) +#' out <- check_versions(versions) +#' str(out) +check_versions <- function(versions) { + history <- jsonlite::read_json(path = versions, simplifyVector = TRUE) + aligned <- (history$version_current == history$version_highest) & + (history$hash_current == history$hash_highest) + aligned[is.na(aligned)] <- TRUE + out <- history[!aligned,, drop = FALSE] # nolint + check_list(out) +} diff --git a/R/record_issues.R b/R/record_issues.R index 93f5e5d4..a71aa17a 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -3,17 +3,15 @@ #' @description Record package check and version issues in individual JSON #' files. #' @return `NULL` (invisibly). -#' @param manifest Character of length 1, file path to a JSON manifest -#' tracking release versions of packages. #' @param output Character of length 1, file path to the folder to record #' new package issues. Each call to `record_issues()` overwrites the #' contents of the repo. record_issues <- function( - manifest = "versions.json", + versions = "versions.json", output = "issues" ) { - issues_version <- version_issues(manifest) - issues <- issues_version # Will include check issues too later. + issues_versions <- check_versions(versions) + issues <- issues_versions overwrite_issues(issues, output) invisible() } @@ -26,15 +24,3 @@ overwrite_issues <- function(issues, output) { jsonlite::write_json(row, file.path(output, row$package)) } } - -version_issues <- function(manifest) { - manifest <- jsonlite::read_json(path = manifest, simplifyVector = TRUE) - aligned <- (manifest$version_current == manifest$version_highest) & - (manifest$hash_current == manifest$hash_highest) - aligned[is.na(aligned)] <- TRUE - out <- manifest[!aligned,, drop = FALSE] # nolint - if (nrow(out)) { - out$version_okay <- FALSE - } - out -} diff --git a/R/record_versions.R b/R/record_versions.R index 6ff9f187..b9b5fb62 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -37,21 +37,11 @@ record_versions <- function( get_current_versions <- function( repo = "https://multiverse.r-multiverse.org" ) { - listing <- file.path( - contrib.url(repos = repo, type = "source"), - "PACKAGES.json?fields=RemoteSha" - ) - out <- jsonlite::stream_in( - con = gzcon(url(listing)), - verbose = TRUE, - simplifyVector = TRUE, - simplifyDataFrame = TRUE, - simplifyMatrix = TRUE - ) - out <- out[, c("Package", "Version", "RemoteSha")] - colnames(out) <- c("package", "version_current", "hash_current") - rownames(out) <- NULL - out + index <- get_package_index(repo = repo, fields = "RemoteSha") + index <- index[, c("Package", "Version", "RemoteSha")] + colnames(index) <- c("package", "version_current", "hash_current") + rownames(index) <- NULL + index } read_versions_previous <- function(manifest) { diff --git a/R/utils_check.R b/R/utils_check.R new file mode 100644 index 00000000..6c4351be --- /dev/null +++ b/R/utils_check.R @@ -0,0 +1,24 @@ +check_list <- function(x) { + package <- x$package + x$package <- NULL + out <- lapply(split(x, seq_len(nrow(x))), as.list) + names(out) <- package + out +} + +get_package_index <- function( + repo = "https://multiverse.r-multiverse.org", + fields = character(0L) +) { + listing <- file.path( + contrib.url(repos = repo, type = "source"), + paste0("PACKAGES.json?fields=", paste(fields, collapse = ",")) + ) + jsonlite::stream_in( + con = gzcon(url(listing)), + verbose = FALSE, + simplifyVector = TRUE, + simplifyDataFrame = TRUE, + simplifyMatrix = TRUE + ) +} diff --git a/R/utils_logic.R b/R/utils_logic.R new file mode 100644 index 00000000..b8794e2f --- /dev/null +++ b/R/utils_logic.R @@ -0,0 +1,15 @@ +`%||%` <- function(x, y) { + if (length(x) > 0L) { + x + } else { + y + } +} + +`%|||%` <- function(x, y) { + if (is.null(x)) { + y + } else { + x + } +} diff --git a/man/check_descriptions.Rd b/man/check_descriptions.Rd new file mode 100644 index 00000000..f0b77044 --- /dev/null +++ b/man/check_descriptions.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check_descriptions.R +\name{check_descriptions} +\alias{check_descriptions} +\title{Check package \code{DESCRIPTION} files.} +\usage{ +check_descriptions(repo = "https://multiverse.r-multiverse.org", index = NULL) +} +\arguments{ +\item{repo}{Character of length 1, URL of the repository +of R package candidates for production.} + +\item{index}{For testing purposes only, +an optional pre-computed data frame with the package index.} +} +\value{ +A named list of information about packages which do not comply +with \code{DESCRPTION} checks. Each name is a package name, +and each element contains specific information about +non-compliance. +} +\description{ +Check the \code{DESCRIPTION} files of packages for specific +issues. +} +\details{ +This function scrapes the \code{src/contrib/PACKAGES.json} file +of the universe to check the data in the \code{DESCRIPTION} files of packages +for compliance. Right now, the only field checked is \verb{Remotes:}. +A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may +depend on development versions of other packages and so are +excluded from the production universe. +} +\examples{ + str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +} diff --git a/man/check_versions.Rd b/man/check_versions.Rd new file mode 100644 index 00000000..d0cd25f3 --- /dev/null +++ b/man/check_versions.Rd @@ -0,0 +1,75 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check_versions.R +\name{check_versions} +\alias{check_versions} +\title{Check package versions.} +\usage{ +check_versions(versions) +} +\arguments{ +\item{versions}{Character of length 1, file path to a JSON manifest +tracking the history of released versions of packages.} +} +\value{ +A named list of information about packages which do not comply +with version number history checks. Each name is a package name, +and each element contains specific information about version +non-compliance: the current version number, the current version hash, +and the analogous versions and hashes of the highest-versioned +release recorded. +} +\description{ +Check package version number history for compliance. +} +\details{ +This function checks the version number history of packages +in R-multiverse and reports any packages with issues. The current +released version of a given package must be unique, and it must be +greater than all the versions of all the previous package releases. +} +\section{Checks}{ + +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} check +the packages in \url{https://multiverse.r-multiverse.org}. Only packages +that pass these checks will appear in +\url{https://production.r-multiverse.org}. +} + +\examples{ + lines <- c( + "[", + " {", + " \"package\": \"package_unmodified\",", + " \"version_current\": \"1.0.0\",", + " \"hash_current\": \"hash_1.0.0\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " },", + " {", + " \"package\": \"version_decremented\",", + " \"version_current\": \"0.0.1\",", + " \"hash_current\": \"hash_0.0.1\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " },", + " {", + " \"package\": \"version_incremented\",", + " \"version_current\": \"2.0.0\",", + " \"hash_current\": \"hash_2.0.0\",", + " \"version_highest\": \"2.0.0\",", + " \"hash_highest\": \"hash_2.0.0\"", + " },", + " {", + " \"package\": \"version_unmodified\",", + " \"version_current\": \"1.0.0\",", + " \"hash_current\": \"hash_1.0.0-modified\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " }", + "]" + ) + versions <- tempfile() + writeLines(lines, versions) + out <- check_versions(versions) + str(out) +} diff --git a/man/record_issues.Rd b/man/record_issues.Rd index 001b7cc6..368246dc 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -4,12 +4,9 @@ \alias{record_issues} \title{Record package issues.} \usage{ -record_issues(manifest = "versions.json", output = "issues") +record_issues(versions = "versions.json", output = "issues") } \arguments{ -\item{manifest}{Character of length 1, file path to a JSON manifest -tracking release versions of packages.} - \item{output}{Character of length 1, file path to the folder to record new package issues. Each call to \code{record_issues()} overwrites the contents of the repo.} diff --git a/tests/testthat/test-check_descriptions.R b/tests/testthat/test-check_descriptions.R new file mode 100644 index 00000000..17c5d4db --- /dev/null +++ b/tests/testthat/test-check_descriptions.R @@ -0,0 +1,40 @@ +test_that("check_descriptions() in a mock case", { + index <- structure( + list( + Package = c( + "SBC", "audio.vadwebrtc", "audio.whisper", + "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", + "nanonext", "polars", "secretbase", "stantargets", "string2path", + "targetsketch", "tidypolars", "tidytensor", "tinytest", "zstdlite" + ), + Version = c( + "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", + "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", + "0.1.6", "0.0.1", "0.7.0", "1.0.0", "1.4.1.1", "0.2.6" + ), + Remotes = list( + NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + c("hyunjimoon/SBC", "stan-dev/cmdstanr", ""), + NULL, NULL, "markvanderloo/tinytest/pkg", NULL, NULL, NULL + ) + ), + row.names = c(NA, 18L), + class = "data.frame" + ) + issues <- check_descriptions(index = index) + expected <- list( + audio.whisper = list(remotes = list("bnosac/audio.vadwebrtc")), + stantargets = list( + remotes = list(c("hyunjimoon/SBC", "stan-dev/cmdstanr")) + ), + tidypolars = list(remotes = list("markvanderloo/tinytest/pkg")) + ) + expect_equal(issues, expected) +}) + +test_that("check_descriptions() on a small repo", { + issues <- check_descriptions(repo = "https://wlandau.r-universe.dev") + expect_true(is.list(issues)) + expect_named(issues) +}) diff --git a/tests/testthat/test-check_versions.R b/tests/testthat/test-check_versions.R new file mode 100644 index 00000000..35bf347a --- /dev/null +++ b/tests/testthat/test-check_versions.R @@ -0,0 +1,58 @@ +test_that("check_versions() in a mock repo", { + # Temporary files used in the mock test. + manifest <- tempfile() + # First update to the manifest. + contents <- data.frame( + package = c( + "package_unmodified", + "version_decremented", + "version_incremented", + "version_unmodified" + ), + version_current = rep("1.0.0", 4L), + hash_current = rep("hash_1.0.0", 4L) + ) + record_versions(manifest = manifest, current = contents) + expect_equal(unname(check_versions(manifest)), list()) + # Update the manifest after no changes to packages or versions. + suppressMessages( + record_versions(manifest = manifest, current = contents) + ) + expect_equal(unname(check_versions(manifest)), list()) + # Update the packages in all the ways indicated above. + index <- contents$package == "version_decremented" + contents$version_current[index] <- "0.0.1" + contents$hash_current[index] <- "hash_0.0.1" + index <- contents$package == "version_incremented" + contents$version_current[index] <- "2.0.0" + contents$hash_current[index] <- "hash_2.0.0" + index <- contents$package == "version_unmodified" + contents$version_current[index] <- "1.0.0" + contents$hash_current[index] <- "hash_1.0.0-modified" + for (index in seq_len(2L)) { + record_versions( + manifest = manifest, + current = contents + ) + out <- check_versions(manifest) + expect_equal( + out, + list( + version_decremented = list( + version_current = "0.0.1", + hash_current = "hash_0.0.1", + version_highest = "1.0.0", + hash_highest = "hash_1.0.0" + ), + version_unmodified = list( + version_current = "1.0.0", + hash_current = "hash_1.0.0-modified", + version_highest = "1.0.0", + hash_highest = "hash_1.0.0" + ) + ) + ) + } + # Remove temporary files + unlink(manifest) +}) diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index 2e1a4eb2..38ddb381 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -1,73 +1,3 @@ -test_that("version_issues() in a mock repo", { - # Temporary files used in the mock test. - manifest <- tempfile() - # First update to the manifest. - contents <- data.frame( - package = c( - "package_unmodified", - "version_decremented", - "version_incremented", - "version_unmodified" - ), - version_current = rep("1.0.0", 4L), - hash_current = rep("hash_1.0.0", 4L) - ) - record_versions(manifest = manifest, current = contents) - expect_equal( - version_issues(manifest), - data.frame( - package = character(0L), - version_current = character(0L), - hash_current = character(0L) - ) - ) - # Update the manifest after no changes to packages or versions. - suppressMessages( - record_versions(manifest = manifest, current = contents) - ) - expect_equal( - version_issues(manifest), - data.frame( - package = character(0L), - version_current = character(0L), - hash_current = character(0L), - version_highest = character(0L), - hash_highest = character(0L) - ) - ) - # Update the packages in all the ways indicated above. - index <- contents$package == "version_decremented" - contents$version_current[index] <- "0.0.1" - contents$hash_current[index] <- "hash_0.0.1" - index <- contents$package == "version_incremented" - contents$version_current[index] <- "2.0.0" - contents$hash_current[index] <- "hash_2.0.0" - index <- contents$package == "version_unmodified" - contents$version_current[index] <- "1.0.0" - contents$hash_current[index] <- "hash_1.0.0-modified" - for (index in seq_len(2L)) { - record_versions( - manifest = manifest, - current = contents - ) - out <- version_issues(manifest) - rownames(out) <- NULL - expect_equal( - out, - data.frame( - package = c("version_decremented", "version_unmodified"), - version_current = c("0.0.1", "1.0.0"), - hash_current = c("hash_0.0.1", "hash_1.0.0-modified"), - version_highest = c("1.0.0", "1.0.0"), - hash_highest = c("hash_1.0.0", "hash_1.0.0"), - version_okay = c(FALSE, FALSE) - ) - ) - } - # Remove temporary files - unlink(manifest) -}) - test_that("record_issues() in a mock repo", { # Temporary files used in the mock test. manifest <- tempfile() @@ -92,7 +22,7 @@ test_that("record_issues() in a mock repo", { ) record_issues(manifest = manifest, output = output) expect_equal(list.files(output), character(0L)) - # Update the packages in all the ways indicated above. + # Update the packages in all the ways indicated below. index <- contents$package == "version_decremented" contents$version_current[index] <- "0.0.1" contents$hash_current[index] <- "hash_0.0.1" diff --git a/tests/testthat/test-utils_logic.R b/tests/testthat/test-utils_logic.R new file mode 100644 index 00000000..efc9611a --- /dev/null +++ b/tests/testthat/test-utils_logic.R @@ -0,0 +1,11 @@ +test_that("%||%", { + expect_equal("a" %||% "b", "a") + expect_equal(list() %||% "b", "b") + expect_equal(NULL %||% "b", "b") +}) + +test_that("%|||%", { + expect_equal("a" %|||% "b", "a") + expect_equal(list() %|||% "b", list()) + expect_equal(NULL %|||% "b", "b") +}) From a65279137cb46a9138bf11a18744fa7548e84848 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 14:48:03 -0400 Subject: [PATCH 03/17] check_checks() --- NAMESPACE | 1 + R/check_checks.R | 44 +++++++++ R/check_descriptions.R | 5 +- R/check_versions.R | 11 ++- R/utils_check.R | 20 +++- man/check_checks.Rd | 50 ++++++++++ man/check_descriptions.Rd | 17 +++- man/check_versions.Rd | 18 +++- tests/testthat/test-check_checks.R | 148 +++++++++++++++++++++++++++++ 9 files changed, 305 insertions(+), 9 deletions(-) create mode 100644 R/check_checks.R create mode 100644 man/check_checks.Rd create mode 100644 tests/testthat/test-check_checks.R diff --git a/NAMESPACE b/NAMESPACE index 022ee8e1..5bf93c0b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ export(aggregate_contributions) export(assert_cran_url) export(assert_package) export(assert_release_exists) +export(check_checks) export(check_descriptions) export(check_versions) export(get_current_versions) diff --git a/R/check_checks.R b/R/check_checks.R new file mode 100644 index 00000000..af6e597b --- /dev/null +++ b/R/check_checks.R @@ -0,0 +1,44 @@ +#' @title Check R-universe package check results. +#' @export +#' @family checks +#' @description Check R-universe package check results. +#' @details This function scrapes the `src/contrib/PACKAGES.json` file +#' of the universe to check the data in the `DESCRIPTION` files of packages +#' for compliance. Right now, the only field checked is `Remotes:`. +#' A packages with a `Remotes:` field in the `DESCRIPTION` file may +#' depend on development versions of other packages and so are +#' excluded from the production universe. +#' @inheritSection check_versions Checks +#' @return A named list of information about packages which do not comply +#' with `DESCRPTION` checks. Each name is a package name, +#' and each element contains specific information about +#' non-compliance. +#' @inheritParams check_descriptions +#' @examples +#' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +check_checks <- function( + repo = "https://multiverse.r-multiverse.org", + index = NULL +) { + fields_check <- c( + "_linuxdevel", + "_macbinary", + "_wasmbinary", + "_winbinary", + "_status" + ) + fields_info <- c( + "_buildurl" + ) + fields <- c(fields_check, fields_info) + index <- index %|||% get_package_api(repo = repo, fields = fields) + for (field in fields) { + index[[field]][is.na(index[[field]])] <- "src-failure" + } + success <- rep(TRUE, nrow(index)) + for (field in fields_check) { + success <- success & (index[[field]] %in% c("success", "skipped")) + } + index <- index[!success,, drop = FALSE] # nolint + check_list(index[, c("Package", fields)]) +} diff --git a/R/check_descriptions.R b/R/check_descriptions.R index 3751b2e8..9f3130b9 100644 --- a/R/check_descriptions.R +++ b/R/check_descriptions.R @@ -1,5 +1,6 @@ #' @title Check package `DESCRIPTION` files. #' @export +#' @family checks #' @description Check the `DESCRIPTION` files of packages for specific #' issues. #' @details This function scrapes the `src/contrib/PACKAGES.json` file @@ -8,6 +9,7 @@ #' A packages with a `Remotes:` field in the `DESCRIPTION` file may #' depend on development versions of other packages and so are #' excluded from the production universe. +#' @inheritSection check_versions Checks #' @return A named list of information about packages which do not comply #' with `DESCRPTION` checks. Each name is a package name, #' and each element contains specific information about @@ -15,7 +17,7 @@ #' @param repo Character of length 1, URL of the repository #' of R package candidates for production. #' @param index For testing purposes only, -#' an optional pre-computed data frame with the package index. +#' an optional pre-computed data frame with details about packages. #' @examples #' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) check_descriptions <- function( @@ -26,7 +28,6 @@ check_descriptions <- function( index <- index %|||% get_package_index(repo = repo, fields = fields) index <- check_descriptions_remotes(index) index <- index[, c("Package", fields)] - colnames(index) <- tolower(colnames(index)) check_list(index) } diff --git a/R/check_versions.R b/R/check_versions.R index 3c9eb11b..725e73ad 100644 --- a/R/check_versions.R +++ b/R/check_versions.R @@ -1,15 +1,17 @@ #' @title Check package versions. #' @export +#' @family checks #' @description Check package version number history for compliance. #' @details This function checks the version number history of packages #' in R-multiverse and reports any packages with issues. The current #' released version of a given package must be unique, and it must be #' greater than all the versions of all the previous package releases. #' @section Checks: -#' Functions like [check_versions()] and [check_descriptions()] check +#' Functions like [check_versions()] and [check_descriptions()] #' the packages in . Only packages #' that pass these checks will appear in -#' . +#' . For a complete list of checks, +#' see #' @return A named list of information about packages which do not comply #' with version number history checks. Each name is a package name, #' and each element contains specific information about version @@ -18,7 +20,12 @@ #' release recorded. #' @param versions Character of length 1, file path to a JSON manifest #' tracking the history of released versions of packages. +#' The official versions file for R-multiverse is maintained and +#' updated periodically at +#' . #' @examples +#' # See https://github.com/r-multiverse/checks/blob/main/versions.json +#' # for the official versions JSON for R-multiverse. #' lines <- c( #' "[", #' " {", diff --git a/R/utils_check.R b/R/utils_check.R index 6c4351be..42f96e7d 100644 --- a/R/utils_check.R +++ b/R/utils_check.R @@ -1,9 +1,10 @@ check_list <- function(x) { + colnames(x) <- tolower(colnames(x)) package <- x$package x$package <- NULL out <- lapply(split(x, seq_len(nrow(x))), as.list) names(out) <- package - out + out[order(package)] } get_package_index <- function( @@ -22,3 +23,20 @@ get_package_index <- function( simplifyMatrix = TRUE ) } + +get_package_api <- function( + repo = "https://multiverse.r-multiverse.org", + fields = character(0L) +) { + listing <- file.path( + repo, + "api", + paste0("packages?fields=", paste(fields, collapse = ",")) + ) + jsonlite::parse_json( + json = nanonext::ncurl(url = listing)$data, # TODO: needs to be paginated + simplifyVector = TRUE, + simplifyDataFrame = TRUE, + simplifyMatrix = TRUE + ) +} diff --git a/man/check_checks.Rd b/man/check_checks.Rd new file mode 100644 index 00000000..35b30f7e --- /dev/null +++ b/man/check_checks.Rd @@ -0,0 +1,50 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check_checks.R +\name{check_checks} +\alias{check_checks} +\title{Check R-universe package check results.} +\usage{ +check_checks(repo = "https://multiverse.r-multiverse.org", index = NULL) +} +\arguments{ +\item{repo}{Character of length 1, URL of the repository +of R package candidates for production.} + +\item{index}{For testing purposes only, +an optional pre-computed data frame with details about packages.} +} +\value{ +A named list of information about packages which do not comply +with \code{DESCRPTION} checks. Each name is a package name, +and each element contains specific information about +non-compliance. +} +\description{ +Check R-universe package check results. +} +\details{ +This function scrapes the \code{src/contrib/PACKAGES.json} file +of the universe to check the data in the \code{DESCRIPTION} files of packages +for compliance. Right now, the only field checked is \verb{Remotes:}. +A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may +depend on development versions of other packages and so are +excluded from the production universe. +} +\section{Checks}{ + +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +the packages in \url{https://multiverse.r-multiverse.org}. Only packages +that pass these checks will appear in +\url{https://production.r-multiverse.org}. For a complete list of checks, +see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} +} + +\examples{ + str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +} +\seealso{ +Other checks: +\code{\link{check_descriptions}()}, +\code{\link{check_versions}()} +} +\concept{checks} diff --git a/man/check_descriptions.Rd b/man/check_descriptions.Rd index f0b77044..7dbeccc1 100644 --- a/man/check_descriptions.Rd +++ b/man/check_descriptions.Rd @@ -11,7 +11,7 @@ check_descriptions(repo = "https://multiverse.r-multiverse.org", index = NULL) of R package candidates for production.} \item{index}{For testing purposes only, -an optional pre-computed data frame with the package index.} +an optional pre-computed data frame with details about packages.} } \value{ A named list of information about packages which do not comply @@ -31,6 +31,21 @@ A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may depend on development versions of other packages and so are excluded from the production universe. } +\section{Checks}{ + +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +the packages in \url{https://multiverse.r-multiverse.org}. Only packages +that pass these checks will appear in +\url{https://production.r-multiverse.org}. For a complete list of checks, +see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} +} + \examples{ str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) } +\seealso{ +Other checks: +\code{\link{check_checks}()}, +\code{\link{check_versions}()} +} +\concept{checks} diff --git a/man/check_versions.Rd b/man/check_versions.Rd index d0cd25f3..160344f7 100644 --- a/man/check_versions.Rd +++ b/man/check_versions.Rd @@ -8,7 +8,10 @@ check_versions(versions) } \arguments{ \item{versions}{Character of length 1, file path to a JSON manifest -tracking the history of released versions of packages.} +tracking the history of released versions of packages. +The official versions file for R-multiverse is maintained and +updated periodically at +\url{https://github.com/r-multiverse/checks/blob/main/versions.json}.} } \value{ A named list of information about packages which do not comply @@ -29,13 +32,16 @@ greater than all the versions of all the previous package releases. } \section{Checks}{ -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} check +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} the packages in \url{https://multiverse.r-multiverse.org}. Only packages that pass these checks will appear in -\url{https://production.r-multiverse.org}. +\url{https://production.r-multiverse.org}. For a complete list of checks, +see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} } \examples{ + # See https://github.com/r-multiverse/checks/blob/main/versions.json + # for the official versions JSON for R-multiverse. lines <- c( "[", " {", @@ -73,3 +79,9 @@ that pass these checks will appear in out <- check_versions(versions) str(out) } +\seealso{ +Other checks: +\code{\link{check_checks}()}, +\code{\link{check_descriptions}()} +} +\concept{checks} diff --git a/tests/testthat/test-check_checks.R b/tests/testthat/test-check_checks.R new file mode 100644 index 00000000..c02b7088 --- /dev/null +++ b/tests/testthat/test-check_checks.R @@ -0,0 +1,148 @@ +test_that("check_checks() mock index", { + index <- structure( + list( + Package = c( + "tinytest", "tidytensor", "secretbase", + "multiverse.internals", "SBC", "duckdb", "httpgd", "targetsketch", + "stantargets", "zstdlite", "INLA", "audio.whisper", "tidypolars", + "multitools", "audio.vadwebrtc", "nanonext", "polars", "cmdstanr", + "string2path" + ), + "_user" = c( + "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse" + ), + "_type" = c( + "src", "src", "src", "src", "src", "src", "src", + "src", "src", "src", "failure", "src", "src", "src", "src", "src", + "src", "src", "src" + ), + "_status" = c( + "success", "failure", "success", + "success", "failure", "success", "success", "success", "success", + "success", NA, "success", "success", "success", "success", "success", + "success", "success", "success" + ), + "_winbinary" = c( + "success", "success", "success", "success", + "success", "success", "success", + "success", "success", "success", NA, "success", "success", "success", + "success", "success", "success", "success", "success" + ), + "_macbinary" = c( + "success", "success", "success", "success", + "success", "success", "success", + "success", "success", "success", NA, "success", "success", "success", + "success", "success", "arm64-failure", "success", "success" + ), + "_wasmbinary" = c( + "success", "success", "success", "success", + "success", "success", "none", "success", "success", "success", + NA, "success", "success", "success", "success", "success", + "none", "success", "none" + ), + "_linuxdevel" = c( + "success", "failure", "success", "success", + "failure", "success", "success", + "success", "failure", "success", NA, + "success", "success", + "success", "success", "success", + "failure", "success", "success" + ), + "_buildurl" = c( + "https://github.com/r-universe/r-multiverse/actions/runs/8998731783", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732025", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731915", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732064", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731731", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731753", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732459", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732171", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732490", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732389", + "https://github.com/r-universe/r-multiverse/actions/runs/8487512222", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732607", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732444", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731870", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732026", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732176", + "https://github.com/r-universe/r-multiverse/actions/runs/9005231218", + "https://github.com/r-universe/r-multiverse/actions/runs/9140511697", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732437" + ), + "_indexed" = c( + FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, + FALSE, TRUE, FALSE, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE, + TRUE, TRUE, FALSE), + "_binaries" = list( + list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), + list(), list() + ), + "_failure" = structure( + list( + buildurl = c( + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, + paste0( + "https://github.com/r-universe/r-multiverse", + "/actions/runs/8487512222" + ), + NA, NA, NA, NA, NA, NA, NA, NA + ) + ), + class = "data.frame", + row.names = c(NA, 19L) + ) + ), + class = "data.frame", + row.names = c(NA, 19L) + ) + issues <- check_checks(index = index) + url <- "https://github.com/r-universe/r-multiverse/actions/runs" + expected <- list( + httpgd = list( + "_linuxdevel" = "success", "_macbinary" = "success", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_buildurl" = file.path(url, "8998732459") + ), + INLA = list( + "_linuxdevel" = "src-failure", "_macbinary" = "src-failure", + "_wasmbinary" = "src-failure", "_winbinary" = "src-failure", + "_status" = "src-failure", + "_buildurl" = file.path(url, "8487512222") + ), + polars = list( + "_linuxdevel" = "failure", "_macbinary" = "arm64-failure", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_buildurl" = file.path(url, "9005231218") + ), + SBC = list( + "_linuxdevel" = "failure", "_macbinary" = "success", + "_wasmbinary" = "success", "_winbinary" = "success", + "_status" = "failure", + "_buildurl" = file.path(url, "8998731731") + ), + stantargets = list( + "_linuxdevel" = "failure", "_macbinary" = "success", + "_wasmbinary" = "success", "_winbinary" = "success", + "_status" = "success", + "_buildurl" = file.path(url, "8998732490") + ), + string2path = list( + "_linuxdevel" = "success", "_macbinary" = "success", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_buildurl" = file.path(url, "8998732437") + ), + tidytensor = list( + "_linuxdevel" = "failure", "_macbinary" = "success", + "_wasmbinary" = "success", "_winbinary" = "success", + "_status" = "failure", + "_buildurl" = file.path(url, "8998732025") + ) + ) + expect_equal(issues[order(names(issues))], expected[order(names(expected))]) +}) From 2b390e4cbd97bf41c1e78836bef5555eb91dc969 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:05:52 -0400 Subject: [PATCH 04/17] refactor and test record_issues() --- R/check_checks.R | 4 +- R/check_descriptions.R | 9 +- R/check_versions.R | 6 +- R/record_issues.R | 54 +++++++- R/record_versions.R | 47 +++++-- inst/WORDLIST | 1 + man/check_checks.Rd | 7 +- man/check_descriptions.Rd | 7 +- man/record_issues.Rd | 37 ++++- man/record_versions.Rd | 26 +++- tests/testthat/helper-mock.R | 164 +++++++++++++++++++++++ tests/testthat/test-check_checks.R | 112 ++-------------- tests/testthat/test-check_descriptions.R | 27 +--- tests/testthat/test-check_versions.R | 2 +- tests/testthat/test-record_issues.R | 148 ++++++++++++-------- tests/testthat/test-record_versions.R | 2 +- 16 files changed, 425 insertions(+), 228 deletions(-) create mode 100644 tests/testthat/helper-mock.R diff --git a/R/check_checks.R b/R/check_checks.R index af6e597b..f927ff35 100644 --- a/R/check_checks.R +++ b/R/check_checks.R @@ -18,7 +18,7 @@ #' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) check_checks <- function( repo = "https://multiverse.r-multiverse.org", - index = NULL + mock = NULL ) { fields_check <- c( "_linuxdevel", @@ -31,7 +31,7 @@ check_checks <- function( "_buildurl" ) fields <- c(fields_check, fields_info) - index <- index %|||% get_package_api(repo = repo, fields = fields) + index <- mock %|||% get_package_api(repo = repo, fields = fields) for (field in fields) { index[[field]][is.na(index[[field]])] <- "src-failure" } diff --git a/R/check_descriptions.R b/R/check_descriptions.R index 9f3130b9..96f030db 100644 --- a/R/check_descriptions.R +++ b/R/check_descriptions.R @@ -16,16 +16,17 @@ #' non-compliance. #' @param repo Character of length 1, URL of the repository #' of R package candidates for production. -#' @param index For testing purposes only, -#' an optional pre-computed data frame with details about packages. +#' @param mock For testing purposes only, +#' an optional pre-computed data frame with details about packages +#' for this type of check. #' @examples #' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) check_descriptions <- function( repo = "https://multiverse.r-multiverse.org", - index = NULL + mock = NULL ) { fields <- "Remotes" - index <- index %|||% get_package_index(repo = repo, fields = fields) + index <- mock %|||% get_package_index(repo = repo, fields = fields) index <- check_descriptions_remotes(index) index <- index[, c("Package", fields)] check_list(index) diff --git a/R/check_versions.R b/R/check_versions.R index 725e73ad..23334ae2 100644 --- a/R/check_versions.R +++ b/R/check_versions.R @@ -18,11 +18,7 @@ #' non-compliance: the current version number, the current version hash, #' and the analogous versions and hashes of the highest-versioned #' release recorded. -#' @param versions Character of length 1, file path to a JSON manifest -#' tracking the history of released versions of packages. -#' The official versions file for R-multiverse is maintained and -#' updated periodically at -#' . +#' @inheritParams record_versions #' @examples #' # See https://github.com/r-multiverse/checks/blob/main/versions.json #' # for the official versions JSON for R-multiverse. diff --git a/R/record_issues.R b/R/record_issues.R index a71aa17a..30515c3c 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -3,24 +3,64 @@ #' @description Record package check and version issues in individual JSON #' files. #' @return `NULL` (invisibly). +#' @inheritParams check_checks #' @param output Character of length 1, file path to the folder to record #' new package issues. Each call to `record_issues()` overwrites the #' contents of the repo. +#' @param mock For testing purposes only, a named list of data frames +#' for the `mock` argument of each type of check. +#' @examples +#' # R-multiverse uses https://multiverse.r-multiverse.org as the repo. +#' repo <- "https://wlandau.r-universe.dev" # just for testing and examples +#' output <- tempfile() +#' versions <- tempfile() +#' record_versions( +#' versions = versions, +#' repo = repo +#' ) +#' record_issues( +#' repo = repo, +#' versions = versions, +#' output = output +#' ) +#' files <- list.files(output) +#' print(files) +#' package <- head(files, n = 1) +#' if (length(package)) { +#' print(package) +#' } +#' if (length(package)) { +#' print(readLines(file.path(output, package))) +#' } record_issues <- function( + repo = "https://multiverse.r-multiverse.org", versions = "versions.json", - output = "issues" + output = "issues", + mock = NULL ) { - issues_versions <- check_versions(versions) - issues <- issues_versions - overwrite_issues(issues, output) + list() |> + issues(check_checks(repo, mock$checks), "checks") |> + issues(check_descriptions(repo, mock$descriptions), "descriptions") |> + issues(check_versions(versions = versions), "versions") |> + overwrite_issues(output = output) invisible() } +issues <- function(total, subset, category) { + for (package in names(subset)) { + total[[package]][[category]] <- subset[[package]] + } + total +} + overwrite_issues <- function(issues, output) { unlink(output, recursive = TRUE) dir.create(output) - for (index in seq_len(nrow(issues))) { - row <- vctrs::vec_slice(x = issues, i = index) - jsonlite::write_json(row, file.path(output, row$package)) + for (package in names(issues)) { + jsonlite::write_json( + x = issues[[package]], + path = file.path(output, package), + pretty = TRUE + ) } } diff --git a/R/record_versions.R b/R/record_versions.R index b9b5fb62..923a91fc 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -9,22 +9,43 @@ #' practices for version numbers. #' @return `NULL` (invisibly). Writes a package version manifest #' and a manifest of version issues as JSON files. -#' @param manifest Character of length 1, file path to the JSON manifest. +#' @param versions Character of length 1, file path to a JSON manifest +#' tracking the history of released versions of packages. +#' The official versions file for R-multiverse is maintained and +#' updated periodically at +#' . #' @param repo Character string of package repositories to track. #' @param current A data frame of current versions and hashes of packages #' in `repo`. This argument is exposed for testing only. +#' @examples +#' # R-multiverse uses https://multiverse.r-multiverse.org as the repo. +#' repo <- "https://wlandau.r-universe.dev" # just for testing and examples +#' output <- tempfile() +#' versions <- tempfile() +#' # First snapshot: +#' record_versions( +#' versions = versions, +#' repo = repo +#' ) +#' readLines(versions) +#' # In subsequent snapshots, we have historical information about versions. +#' record_versions( +#' versions = versions, +#' repo = repo +#' ) +#' readLines(versions) record_versions <- function( - manifest = "versions.json", + versions = "versions.json", repo = "https://multiverse.r-multiverse.org", current = multiverse.internals::get_current_versions(repo = repo) ) { - if (!file.exists(manifest)) { - jsonlite::write_json(x = current, path = manifest, pretty = TRUE) + if (!file.exists(versions)) { + jsonlite::write_json(x = current, path = versions, pretty = TRUE) return(invisible()) } - previous <- read_versions_previous(manifest = manifest) - new <- update_version_manifest(current = current, previous = previous) - jsonlite::write_json(x = new, path = manifest, pretty = TRUE) + previous <- read_versions_previous(versions = versions) + new <- update_versions(current = current, previous = previous) + jsonlite::write_json(x = new, path = versions, pretty = TRUE) invisible() } @@ -44,8 +65,8 @@ get_current_versions <- function( index } -read_versions_previous <- function(manifest) { - out <- jsonlite::read_json(path = manifest, simplifyVector = TRUE) +read_versions_previous <- function(versions) { + out <- jsonlite::read_json(path = versions, simplifyVector = TRUE) if (is.null(out$version_highest)) { out$version_highest <- out$version_current } @@ -57,7 +78,7 @@ read_versions_previous <- function(manifest) { out } -update_version_manifest <- function(current, previous) { +update_versions <- function(current, previous) { new <- merge( x = current, y = previous, @@ -65,15 +86,15 @@ update_version_manifest <- function(current, previous) { all.x = TRUE, all.y = FALSE ) - incremented <- manifest_compare_versions(manifest = new) == 1L + incremented <- compare_versions(versions = new) == 1L new$version_highest[incremented] <- new$version_current[incremented] new$hash_highest[incremented] <- new$hash_current[incremented] new } -manifest_compare_versions <- function(manifest) { +compare_versions <- function(versions) { apply( - X = manifest, + X = versions, MARGIN = 1L, FUN = function(row) { utils::compareVersion( diff --git a/inst/WORDLIST b/inst/WORDLIST index b5f86195..5d59fa53 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -4,3 +4,4 @@ JSON json repo pkgdown +pre diff --git a/man/check_checks.Rd b/man/check_checks.Rd index 35b30f7e..ef20cb58 100644 --- a/man/check_checks.Rd +++ b/man/check_checks.Rd @@ -4,14 +4,15 @@ \alias{check_checks} \title{Check R-universe package check results.} \usage{ -check_checks(repo = "https://multiverse.r-multiverse.org", index = NULL) +check_checks(repo = "https://multiverse.r-multiverse.org", mock = NULL) } \arguments{ \item{repo}{Character of length 1, URL of the repository of R package candidates for production.} -\item{index}{For testing purposes only, -an optional pre-computed data frame with details about packages.} +\item{mock}{For testing purposes only, +an optional pre-computed data frame with details about packages +for this type of check.} } \value{ A named list of information about packages which do not comply diff --git a/man/check_descriptions.Rd b/man/check_descriptions.Rd index 7dbeccc1..1049f5ad 100644 --- a/man/check_descriptions.Rd +++ b/man/check_descriptions.Rd @@ -4,14 +4,15 @@ \alias{check_descriptions} \title{Check package \code{DESCRIPTION} files.} \usage{ -check_descriptions(repo = "https://multiverse.r-multiverse.org", index = NULL) +check_descriptions(repo = "https://multiverse.r-multiverse.org", mock = NULL) } \arguments{ \item{repo}{Character of length 1, URL of the repository of R package candidates for production.} -\item{index}{For testing purposes only, -an optional pre-computed data frame with details about packages.} +\item{mock}{For testing purposes only, +an optional pre-computed data frame with details about packages +for this type of check.} } \value{ A named list of information about packages which do not comply diff --git a/man/record_issues.Rd b/man/record_issues.Rd index 368246dc..bc49d03d 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -4,12 +4,23 @@ \alias{record_issues} \title{Record package issues.} \usage{ -record_issues(versions = "versions.json", output = "issues") +record_issues( + repo = "https://multiverse.r-multiverse.org", + versions = "versions.json", + output = "issues", + mock = NULL +) } \arguments{ +\item{repo}{Character of length 1, URL of the repository +of R package candidates for production.} + \item{output}{Character of length 1, file path to the folder to record new package issues. Each call to \code{record_issues()} overwrites the contents of the repo.} + +\item{mock}{For testing purposes only, a named list of data frames +for the \code{mock} argument of each type of check.} } \value{ \code{NULL} (invisibly). @@ -18,3 +29,27 @@ contents of the repo.} Record package check and version issues in individual JSON files. } +\examples{ + # R-multiverse uses https://multiverse.r-multiverse.org as the repo. + repo <- "https://wlandau.r-universe.dev" # just for testing and examples + output <- tempfile() + versions <- tempfile() + record_versions( + versions = versions, + repo = repo + ) + record_issues( + repo = repo, + versions = versions, + output = output + ) + files <- list.files(output) + print(files) + package <- head(files, n = 1) + if (length(package)) { + print(package) + } + if (length(package)) { + print(readLines(file.path(output, package))) + } +} diff --git a/man/record_versions.Rd b/man/record_versions.Rd index 85d7c439..aaa22b5a 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -5,13 +5,17 @@ \title{Record the manifest of package versions.} \usage{ record_versions( - manifest = "versions.json", + versions = "versions.json", repo = "https://multiverse.r-multiverse.org", current = multiverse.internals::get_current_versions(repo = repo) ) } \arguments{ -\item{manifest}{Character of length 1, file path to the JSON manifest.} +\item{versions}{Character of length 1, file path to a JSON manifest +tracking the history of released versions of packages. +The official versions file for R-multiverse is maintained and +updated periodically at +\url{https://github.com/r-multiverse/checks/blob/main/versions.json}.} \item{repo}{Character string of package repositories to track.} @@ -33,3 +37,21 @@ the hash of the highest version ever released. It uses this information to determine whether the package complies with best practices for version numbers. } +\examples{ + # R-multiverse uses https://multiverse.r-multiverse.org as the repo. + repo <- "https://wlandau.r-universe.dev" # just for testing and examples + output <- tempfile() + versions <- tempfile() + # First snapshot: + record_versions( + versions = versions, + repo = repo + ) + readLines(versions) + # In subsequent snapshots, we have historical information about versions. + record_versions( + versions = versions, + repo = repo + ) + readLines(versions) +} diff --git a/tests/testthat/helper-mock.R b/tests/testthat/helper-mock.R new file mode 100644 index 00000000..a6afc7ea --- /dev/null +++ b/tests/testthat/helper-mock.R @@ -0,0 +1,164 @@ +mock_checks <- structure( + list( + Package = c( + "tinytest", "tidytensor", "secretbase", + "multiverse.internals", "SBC", "duckdb", "httpgd", "targetsketch", + "stantargets", "zstdlite", "INLA", "audio.whisper", "tidypolars", + "multitools", "audio.vadwebrtc", "nanonext", "polars", "cmdstanr", + "string2path" + ), + "_user" = c( + "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", + "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse" + ), + "_type" = c( + "src", "src", "src", "src", "src", "src", "src", + "src", "src", "src", "failure", "src", "src", "src", "src", "src", + "src", "src", "src" + ), + "_status" = c( + "success", "failure", "success", + "success", "failure", "success", "success", "success", "success", + "success", NA, "success", "success", "success", "success", "success", + "success", "success", "success" + ), + "_winbinary" = c( + "success", "success", "success", "success", + "success", "success", "success", + "success", "success", "success", NA, "success", "success", "success", + "success", "success", "success", "success", "success" + ), + "_macbinary" = c( + "success", "success", "success", "success", + "success", "success", "success", + "success", "success", "success", NA, "success", "success", "success", + "success", "success", "arm64-failure", "success", "success" + ), + "_wasmbinary" = c( + "success", "success", "success", "success", + "success", "success", "none", "success", "success", "success", + NA, "success", "success", "success", "success", "success", + "none", "success", "none" + ), + "_linuxdevel" = c( + "success", "failure", "success", "success", + "failure", "success", "success", + "success", "failure", "success", NA, + "success", "success", + "success", "success", "success", + "failure", "success", "success" + ), + "_buildurl" = c( + "https://github.com/r-universe/r-multiverse/actions/runs/8998731783", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732025", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731915", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732064", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731731", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731753", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732459", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732171", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732490", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732389", + "https://github.com/r-universe/r-multiverse/actions/runs/8487512222", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732607", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732444", + "https://github.com/r-universe/r-multiverse/actions/runs/8998731870", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732026", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732176", + "https://github.com/r-universe/r-multiverse/actions/runs/9005231218", + "https://github.com/r-universe/r-multiverse/actions/runs/9140511697", + "https://github.com/r-universe/r-multiverse/actions/runs/8998732437" + ), + "_indexed" = c( + FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, + FALSE, TRUE, FALSE, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE, + TRUE, TRUE, FALSE), + "_binaries" = list( + list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), + list(), list() + ), + "_failure" = structure( + list( + buildurl = c( + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, + paste0( + "https://github.com/r-universe/r-multiverse", + "/actions/runs/8487512222" + ), + NA, NA, NA, NA, NA, NA, NA, NA + ) + ), + class = "data.frame", + row.names = c(NA, 19L) + ) + ), + class = "data.frame", + row.names = c(NA, 19L) +) + +mock_descriptions <- structure( + list( + Package = c( + "SBC", "audio.vadwebrtc", "audio.whisper", + "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", + "nanonext", "polars", "secretbase", "stantargets", "string2path", + "targetsketch", "tidypolars", "tidytensor", "tinytest", "zstdlite" + ), + Version = c( + "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", + "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", + "0.1.6", "0.0.1", "0.7.0", "1.0.0", "1.4.1.1", "0.2.6" + ), + Remotes = list( + NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + c("hyunjimoon/SBC", "stan-dev/cmdstanr", ""), + NULL, NULL, "markvanderloo/tinytest/pkg", NULL, NULL, NULL + ) + ), + row.names = c(NA, 18L), + class = "data.frame" +) + +mock_versions <- function() { + lines <- c( + "[", + " {", + " \"package\": \"package_unmodified\",", + " \"version_current\": \"1.0.0\",", + " \"hash_current\": \"hash_1.0.0\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " },", + " {", + " \"package\": \"version_decremented\",", + " \"version_current\": \"0.0.1\",", + " \"hash_current\": \"hash_0.0.1\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " },", + " {", + " \"package\": \"version_incremented\",", + " \"version_current\": \"2.0.0\",", + " \"hash_current\": \"hash_2.0.0\",", + " \"version_highest\": \"2.0.0\",", + " \"hash_highest\": \"hash_2.0.0\"", + " },", + " {", + " \"package\": \"version_unmodified\",", + " \"version_current\": \"1.0.0\",", + " \"hash_current\": \"hash_1.0.0-modified\",", + " \"version_highest\": \"1.0.0\",", + " \"hash_highest\": \"hash_1.0.0\"", + " }", + "]" + ) + versions <- tempfile() + writeLines(lines, versions) + versions +} diff --git a/tests/testthat/test-check_checks.R b/tests/testthat/test-check_checks.R index c02b7088..9fa9d0a3 100644 --- a/tests/testthat/test-check_checks.R +++ b/tests/testthat/test-check_checks.R @@ -1,107 +1,5 @@ -test_that("check_checks() mock index", { - index <- structure( - list( - Package = c( - "tinytest", "tidytensor", "secretbase", - "multiverse.internals", "SBC", "duckdb", "httpgd", "targetsketch", - "stantargets", "zstdlite", "INLA", "audio.whisper", "tidypolars", - "multitools", "audio.vadwebrtc", "nanonext", "polars", "cmdstanr", - "string2path" - ), - "_user" = c( - "r-multiverse", "r-multiverse", "r-multiverse", - "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", - "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", - "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse", - "r-multiverse", "r-multiverse", "r-multiverse", "r-multiverse" - ), - "_type" = c( - "src", "src", "src", "src", "src", "src", "src", - "src", "src", "src", "failure", "src", "src", "src", "src", "src", - "src", "src", "src" - ), - "_status" = c( - "success", "failure", "success", - "success", "failure", "success", "success", "success", "success", - "success", NA, "success", "success", "success", "success", "success", - "success", "success", "success" - ), - "_winbinary" = c( - "success", "success", "success", "success", - "success", "success", "success", - "success", "success", "success", NA, "success", "success", "success", - "success", "success", "success", "success", "success" - ), - "_macbinary" = c( - "success", "success", "success", "success", - "success", "success", "success", - "success", "success", "success", NA, "success", "success", "success", - "success", "success", "arm64-failure", "success", "success" - ), - "_wasmbinary" = c( - "success", "success", "success", "success", - "success", "success", "none", "success", "success", "success", - NA, "success", "success", "success", "success", "success", - "none", "success", "none" - ), - "_linuxdevel" = c( - "success", "failure", "success", "success", - "failure", "success", "success", - "success", "failure", "success", NA, - "success", "success", - "success", "success", "success", - "failure", "success", "success" - ), - "_buildurl" = c( - "https://github.com/r-universe/r-multiverse/actions/runs/8998731783", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732025", - "https://github.com/r-universe/r-multiverse/actions/runs/8998731915", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732064", - "https://github.com/r-universe/r-multiverse/actions/runs/8998731731", - "https://github.com/r-universe/r-multiverse/actions/runs/8998731753", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732459", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732171", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732490", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732389", - "https://github.com/r-universe/r-multiverse/actions/runs/8487512222", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732607", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732444", - "https://github.com/r-universe/r-multiverse/actions/runs/8998731870", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732026", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732176", - "https://github.com/r-universe/r-multiverse/actions/runs/9005231218", - "https://github.com/r-universe/r-multiverse/actions/runs/9140511697", - "https://github.com/r-universe/r-multiverse/actions/runs/8998732437" - ), - "_indexed" = c( - FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, - FALSE, TRUE, FALSE, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE, - TRUE, TRUE, FALSE), - "_binaries" = list( - list(), list(), list(), - list(), list(), list(), list(), list(), list(), list(), - list(), list(), list(), list(), list(), list(), list(), - list(), list() - ), - "_failure" = structure( - list( - buildurl = c( - NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, - paste0( - "https://github.com/r-universe/r-multiverse", - "/actions/runs/8487512222" - ), - NA, NA, NA, NA, NA, NA, NA, NA - ) - ), - class = "data.frame", - row.names = c(NA, 19L) - ) - ), - class = "data.frame", - row.names = c(NA, 19L) - ) - issues <- check_checks(index = index) +test_that("check_checks() mocked", { + issues <- check_checks(mock = mock_checks) url <- "https://github.com/r-universe/r-multiverse/actions/runs" expected <- list( httpgd = list( @@ -146,3 +44,9 @@ test_that("check_checks() mock index", { ) expect_equal(issues[order(names(issues))], expected[order(names(expected))]) }) + +test_that("check_checks() on a small repo", { + issues <- check_checks(repo = "https://wlandau.r-universe.dev") + expect_true(is.list(issues)) + expect_named(issues) +}) diff --git a/tests/testthat/test-check_descriptions.R b/tests/testthat/test-check_descriptions.R index 17c5d4db..7d16d331 100644 --- a/tests/testthat/test-check_descriptions.R +++ b/tests/testthat/test-check_descriptions.R @@ -1,28 +1,5 @@ -test_that("check_descriptions() in a mock case", { - index <- structure( - list( - Package = c( - "SBC", "audio.vadwebrtc", "audio.whisper", - "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", - "nanonext", "polars", "secretbase", "stantargets", "string2path", - "targetsketch", "tidypolars", "tidytensor", "tinytest", "zstdlite" - ), - Version = c( - "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", - "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", - "0.1.6", "0.0.1", "0.7.0", "1.0.0", "1.4.1.1", "0.2.6" - ), - Remotes = list( - NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - c("hyunjimoon/SBC", "stan-dev/cmdstanr", ""), - NULL, NULL, "markvanderloo/tinytest/pkg", NULL, NULL, NULL - ) - ), - row.names = c(NA, 18L), - class = "data.frame" - ) - issues <- check_descriptions(index = index) +test_that("check_descriptions() mocked", { + issues <- check_descriptions(mock = mock_descriptions) expected <- list( audio.whisper = list(remotes = list("bnosac/audio.vadwebrtc")), stantargets = list( diff --git a/tests/testthat/test-check_versions.R b/tests/testthat/test-check_versions.R index 35bf347a..bda00bbd 100644 --- a/tests/testthat/test-check_versions.R +++ b/tests/testthat/test-check_versions.R @@ -1,4 +1,4 @@ -test_that("check_versions() in a mock repo", { +test_that("check_versions() mocked", { # Temporary files used in the mock test. manifest <- tempfile() # First update to the manifest. diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index 38ddb381..93a192c8 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -1,72 +1,106 @@ -test_that("record_issues() in a mock repo", { - # Temporary files used in the mock test. - manifest <- tempfile() +test_that("record_issues() mocked", { output <- tempfile() - # First update to the manifest. - contents <- data.frame( - package = c( - "package_unmodified", - "version_decremented", - "version_incremented", - "version_unmodified" + record_issues( + versions = mock_versions(), + mock = list( + checks = mock_checks, + descriptions = mock_descriptions ), - version_current = rep("1.0.0", 4L), - hash_current = rep("hash_1.0.0", 4L) + output = output ) - record_versions(manifest = manifest, current = contents) - record_issues(manifest = manifest, output = output) - expect_equal(list.files(output), character(0L)) - # Update the manifest after no changes to packages or versions. - suppressMessages( - record_versions(manifest = manifest, current = contents) + expect_equal( + sort(c(list.files(output))), + sort( + c( + "audio.whisper", + "httpgd", + "INLA", + "polars", + "SBC", + "stantargets", + "string2path", + "tidypolars", + "tidytensor", + "version_decremented", + "version_unmodified" + ) + ) ) - record_issues(manifest = manifest, output = output) - expect_equal(list.files(output), character(0L)) - # Update the packages in all the ways indicated below. - index <- contents$package == "version_decremented" - contents$version_current[index] <- "0.0.1" - contents$hash_current[index] <- "hash_0.0.1" - index <- contents$package == "version_incremented" - contents$version_current[index] <- "2.0.0" - contents$hash_current[index] <- "hash_2.0.0" - index <- contents$package == "version_unmodified" - contents$version_current[index] <- "1.0.0" - contents$hash_current[index] <- "hash_1.0.0-modified" - for (index in seq_len(2L)) { - record_versions( - manifest = manifest, - current = contents + runs <- "https://github.com/r-universe/r-multiverse/actions/runs" + expect_equal( + jsonlite::read_json(file.path(output, "INLA"), simplifyVector = TRUE), + list( + checks = list( + "_linuxdevel" = "src-failure", + "_macbinary" = "src-failure", + "_wasmbinary" = "src-failure", + "_winbinary" = "src-failure", + "_status" = "src-failure", + "_buildurl" = file.path(runs, "8487512222") + ) ) - record_issues(manifest = manifest, output = output) - expect_equal( - sort(list.files(output)), - sort(c("version_decremented", "version_unmodified")) + ) + expect_equal( + jsonlite::read_json( + file.path(output, "stantargets"), + simplifyVector = TRUE + ), + list( + checks = list( + "_linuxdevel" = "failure", + "_macbinary" = "success", + "_wasmbinary" = "success", + "_winbinary" = "success", + "_status" = "success", + "_buildurl" = file.path(runs, "8998732490") + ), + descriptions = list( + remotes = matrix(c("hyunjimoon/SBC", "stan-dev/cmdstanr"), nrow = 1) + ) ) - out <- jsonlite::read_json(file.path(output, "version_decremented")) - expect_equal( - unlist(out, recursive = TRUE), - c( - package = "version_decremented", + ) + expect_equal( + jsonlite::read_json( + file.path(output, "version_decremented"), + simplifyVector = TRUE + ), + list( + versions = list( version_current = "0.0.1", - hash_current = "hash_0.0.1", + hash_current = "hash_0.0.1", version_highest = "1.0.0", - hash_highest = "hash_1.0.0", - version_okay = FALSE + hash_highest = "hash_1.0.0" ) ) - out <- jsonlite::read_json(file.path(output, "version_unmodified")) - expect_equal( - unlist(out, recursive = TRUE), - c( - package = "version_unmodified", + ) + expect_equal( + jsonlite::read_json( + file.path(output, "version_unmodified"), + simplifyVector = TRUE + ), + list( + versions = list( version_current = "1.0.0", - hash_current = "hash_1.0.0-modified", + hash_current = "hash_1.0.0-modified", version_highest = "1.0.0", - hash_highest = "hash_1.0.0", - version_okay = FALSE + hash_highest = "hash_1.0.0" ) ) - } - # Remove temporary files - unlink(manifest) + ) +}) + +test_that("record_issues() on a small repo", { + output <- tempfile() + versions <- tempfile() + record_versions( + manifest = versions, + repo = "https://wlandau.r-universe.dev" + ) + record_issues( + repo = "https://wlandau.r-universe.dev", + versions = versions, + output = output + ) + expect_true(dir.exists(output)) }) + \ No newline at end of file diff --git a/tests/testthat/test-record_versions.R b/tests/testthat/test-record_versions.R index 0e1a453c..2bea90c3 100644 --- a/tests/testthat/test-record_versions.R +++ b/tests/testthat/test-record_versions.R @@ -1,4 +1,4 @@ -test_that("record_versions() in a mock repo", { +test_that("record_versions() mocked", { # Temporary files used in the mock test. manifest <- tempfile() # First update to the manifest. From f3493864124edfdb36dfbcb5fcdcc3f6e1229cd2 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:09:32 -0400 Subject: [PATCH 05/17] lints --- tests/testthat/helper-mock.R | 27 +++++++++--------- tests/testthat/test-check_checks.R | 36 ++++++++++++------------ tests/testthat/test-check_descriptions.R | 2 +- tests/testthat/test-check_versions.R | 4 +-- tests/testthat/test-record_issues.R | 19 ++++++------- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/testthat/helper-mock.R b/tests/testthat/helper-mock.R index a6afc7ea..4f1742a2 100644 --- a/tests/testthat/helper-mock.R +++ b/tests/testthat/helper-mock.R @@ -73,13 +73,14 @@ mock_checks <- structure( "https://github.com/r-universe/r-multiverse/actions/runs/8998732437" ), "_indexed" = c( - FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, - FALSE, TRUE, FALSE, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE, - TRUE, TRUE, FALSE), + FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, + FALSE, TRUE, FALSE, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE, + TRUE, TRUE, FALSE + ), "_binaries" = list( - list(), list(), list(), - list(), list(), list(), list(), list(), list(), list(), - list(), list(), list(), list(), list(), list(), list(), + list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), + list(), list(), list(), list(), list(), list(), list(), list(), list() ), "_failure" = structure( @@ -89,7 +90,7 @@ mock_checks <- structure( paste0( "https://github.com/r-universe/r-multiverse", "/actions/runs/8487512222" - ), + ), NA, NA, NA, NA, NA, NA, NA, NA ) ), @@ -104,18 +105,18 @@ mock_checks <- structure( mock_descriptions <- structure( list( Package = c( - "SBC", "audio.vadwebrtc", "audio.whisper", - "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", - "nanonext", "polars", "secretbase", "stantargets", "string2path", + "SBC", "audio.vadwebrtc", "audio.whisper", + "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", + "nanonext", "polars", "secretbase", "stantargets", "string2path", "targetsketch", "tidypolars", "tidytensor", "tinytest", "zstdlite" ), Version = c( - "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", - "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", + "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", + "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", "0.1.6", "0.0.1", "0.7.0", "1.0.0", "1.4.1.1", "0.2.6" ), Remotes = list( - NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, + NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, c("hyunjimoon/SBC", "stan-dev/cmdstanr", ""), NULL, NULL, "markvanderloo/tinytest/pkg", NULL, NULL, NULL diff --git a/tests/testthat/test-check_checks.R b/tests/testthat/test-check_checks.R index 9fa9d0a3..6ff5467c 100644 --- a/tests/testthat/test-check_checks.R +++ b/tests/testthat/test-check_checks.R @@ -3,41 +3,41 @@ test_that("check_checks() mocked", { url <- "https://github.com/r-universe/r-multiverse/actions/runs" expected <- list( httpgd = list( - "_linuxdevel" = "success", "_macbinary" = "success", - "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_linuxdevel" = "success", "_macbinary" = "success", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", "_buildurl" = file.path(url, "8998732459") - ), + ), INLA = list( - "_linuxdevel" = "src-failure", "_macbinary" = "src-failure", - "_wasmbinary" = "src-failure", "_winbinary" = "src-failure", + "_linuxdevel" = "src-failure", "_macbinary" = "src-failure", + "_wasmbinary" = "src-failure", "_winbinary" = "src-failure", "_status" = "src-failure", "_buildurl" = file.path(url, "8487512222") - ), + ), polars = list( - "_linuxdevel" = "failure", "_macbinary" = "arm64-failure", - "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_linuxdevel" = "failure", "_macbinary" = "arm64-failure", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", "_buildurl" = file.path(url, "9005231218") - ), + ), SBC = list( "_linuxdevel" = "failure", "_macbinary" = "success", "_wasmbinary" = "success", "_winbinary" = "success", "_status" = "failure", "_buildurl" = file.path(url, "8998731731") - ), + ), stantargets = list( - "_linuxdevel" = "failure", "_macbinary" = "success", - "_wasmbinary" = "success", "_winbinary" = "success", + "_linuxdevel" = "failure", "_macbinary" = "success", + "_wasmbinary" = "success", "_winbinary" = "success", "_status" = "success", "_buildurl" = file.path(url, "8998732490") - ), + ), string2path = list( - "_linuxdevel" = "success", "_macbinary" = "success", - "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", + "_linuxdevel" = "success", "_macbinary" = "success", + "_wasmbinary" = "none", "_winbinary" = "success", "_status" = "success", "_buildurl" = file.path(url, "8998732437") - ), + ), tidytensor = list( - "_linuxdevel" = "failure", "_macbinary" = "success", - "_wasmbinary" = "success", "_winbinary" = "success", + "_linuxdevel" = "failure", "_macbinary" = "success", + "_wasmbinary" = "success", "_winbinary" = "success", "_status" = "failure", "_buildurl" = file.path(url, "8998732025") ) diff --git a/tests/testthat/test-check_descriptions.R b/tests/testthat/test-check_descriptions.R index 7d16d331..f906e919 100644 --- a/tests/testthat/test-check_descriptions.R +++ b/tests/testthat/test-check_descriptions.R @@ -1,7 +1,7 @@ test_that("check_descriptions() mocked", { issues <- check_descriptions(mock = mock_descriptions) expected <- list( - audio.whisper = list(remotes = list("bnosac/audio.vadwebrtc")), + audio.whisper = list(remotes = list("bnosac/audio.vadwebrtc")), stantargets = list( remotes = list(c("hyunjimoon/SBC", "stan-dev/cmdstanr")) ), diff --git a/tests/testthat/test-check_versions.R b/tests/testthat/test-check_versions.R index bda00bbd..332bcc6b 100644 --- a/tests/testthat/test-check_versions.R +++ b/tests/testthat/test-check_versions.R @@ -40,10 +40,10 @@ test_that("check_versions() mocked", { list( version_decremented = list( version_current = "0.0.1", - hash_current = "hash_0.0.1", + hash_current = "hash_0.0.1", version_highest = "1.0.0", hash_highest = "hash_1.0.0" - ), + ), version_unmodified = list( version_current = "1.0.0", hash_current = "hash_1.0.0-modified", diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index 93a192c8..6dcc6051 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -17,11 +17,11 @@ test_that("record_issues() mocked", { "INLA", "polars", "SBC", - "stantargets", + "stantargets", "string2path", "tidypolars", "tidytensor", - "version_decremented", + "version_decremented", "version_unmodified" ) ) @@ -32,9 +32,9 @@ test_that("record_issues() mocked", { list( checks = list( "_linuxdevel" = "src-failure", - "_macbinary" = "src-failure", + "_macbinary" = "src-failure", "_wasmbinary" = "src-failure", - "_winbinary" = "src-failure", + "_winbinary" = "src-failure", "_status" = "src-failure", "_buildurl" = file.path(runs, "8487512222") ) @@ -48,12 +48,12 @@ test_that("record_issues() mocked", { list( checks = list( "_linuxdevel" = "failure", - "_macbinary" = "success", + "_macbinary" = "success", "_wasmbinary" = "success", "_winbinary" = "success", - "_status" = "success", + "_status" = "success", "_buildurl" = file.path(runs, "8998732490") - ), + ), descriptions = list( remotes = matrix(c("hyunjimoon/SBC", "stan-dev/cmdstanr"), nrow = 1) ) @@ -67,7 +67,7 @@ test_that("record_issues() mocked", { list( versions = list( version_current = "0.0.1", - hash_current = "hash_0.0.1", + hash_current = "hash_0.0.1", version_highest = "1.0.0", hash_highest = "hash_1.0.0" ) @@ -81,7 +81,7 @@ test_that("record_issues() mocked", { list( versions = list( version_current = "1.0.0", - hash_current = "hash_1.0.0-modified", + hash_current = "hash_1.0.0-modified", version_highest = "1.0.0", hash_highest = "hash_1.0.0" ) @@ -103,4 +103,3 @@ test_that("record_issues() on a small repo", { ) expect_true(dir.exists(output)) }) - \ No newline at end of file From 2bf9f9f1af378761240ad0df6b6d23a5c8490fb0 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:12:21 -0400 Subject: [PATCH 06/17] fix tests --- tests/testthat/test-check_versions.R | 16 ++++++------ tests/testthat/test-record_issues.R | 2 +- tests/testthat/test-record_versions.R | 36 +++++++++++++-------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/testthat/test-check_versions.R b/tests/testthat/test-check_versions.R index 332bcc6b..6aa29c82 100644 --- a/tests/testthat/test-check_versions.R +++ b/tests/testthat/test-check_versions.R @@ -1,6 +1,6 @@ test_that("check_versions() mocked", { # Temporary files used in the mock test. - manifest <- tempfile() + versions <- tempfile() # First update to the manifest. contents <- data.frame( package = c( @@ -12,13 +12,13 @@ test_that("check_versions() mocked", { version_current = rep("1.0.0", 4L), hash_current = rep("hash_1.0.0", 4L) ) - record_versions(manifest = manifest, current = contents) - expect_equal(unname(check_versions(manifest)), list()) + record_versions(versions = versions, current = contents) + expect_equal(unname(check_versions(versions)), list()) # Update the manifest after no changes to packages or versions. suppressMessages( - record_versions(manifest = manifest, current = contents) + record_versions(versions = versions, current = contents) ) - expect_equal(unname(check_versions(manifest)), list()) + expect_equal(unname(check_versions(versions)), list()) # Update the packages in all the ways indicated above. index <- contents$package == "version_decremented" contents$version_current[index] <- "0.0.1" @@ -31,10 +31,10 @@ test_that("check_versions() mocked", { contents$hash_current[index] <- "hash_1.0.0-modified" for (index in seq_len(2L)) { record_versions( - manifest = manifest, + versions = versions, current = contents ) - out <- check_versions(manifest) + out <- check_versions(versions) expect_equal( out, list( @@ -54,5 +54,5 @@ test_that("check_versions() mocked", { ) } # Remove temporary files - unlink(manifest) + unlink(versions) }) diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index 6dcc6051..fc588bc9 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -93,7 +93,7 @@ test_that("record_issues() on a small repo", { output <- tempfile() versions <- tempfile() record_versions( - manifest = versions, + versions = versions, repo = "https://wlandau.r-universe.dev" ) record_issues( diff --git a/tests/testthat/test-record_versions.R b/tests/testthat/test-record_versions.R index 2bea90c3..173de481 100644 --- a/tests/testthat/test-record_versions.R +++ b/tests/testthat/test-record_versions.R @@ -1,7 +1,7 @@ test_that("record_versions() mocked", { # Temporary files used in the mock test. - manifest <- tempfile() - # First update to the manifest. + versions <- tempfile() + # First update to the version manifest. contents <- data.frame( package = c( "package_unmodified", @@ -13,10 +13,10 @@ test_that("record_versions() mocked", { hash_current = rep("hash_1.0.0", 4L) ) record_versions( - manifest = manifest, + versions = versions, current = contents ) - written <- jsonlite::read_json(manifest) + written <- jsonlite::read_json(versions) expected <- list( list( package = "package_unmodified", @@ -43,11 +43,11 @@ test_that("record_versions() mocked", { # Update the manifest after no changes to packages or versions. suppressMessages( record_versions( - manifest = manifest, + versions = versions, current = contents ) ) - written <- jsonlite::read_json(manifest) + written <- jsonlite::read_json(versions) expected <- list( list( package = "package_unmodified", @@ -91,10 +91,10 @@ test_that("record_versions() mocked", { contents$hash_current[index] <- "hash_1.0.0-modified" for (index in seq_len(2L)) { record_versions( - manifest = manifest, + versions = versions, current = contents ) - written <- jsonlite::read_json(manifest) + written <- jsonlite::read_json(versions) expected <- list( list( package = "package_unmodified", @@ -128,34 +128,34 @@ test_that("record_versions() mocked", { expect_true(identical(written, expected)) } # Remove temporary files - unlink(manifest) + unlink(versions) }) -test_that("manifest can be created and updated from an actual repo", { - manifest <- tempfile() +test_that("version manifest can be created and updated from an actual repo", { + versions <- tempfile() temp <- utils::capture.output( suppressMessages( record_versions( - manifest = manifest, + versions = versions, repo = "https://wlandau.r-universe.dev" ) ) ) - expect_true(file.exists(manifest)) - contents <- do.call(vctrs::vec_rbind, jsonlite::read_json(manifest)) + expect_true(file.exists(versions)) + contents <- do.call(vctrs::vec_rbind, jsonlite::read_json(versions)) contents <- lapply(contents, as.character) lapply(contents, function(x) expect_true(!anyNA(x))) temp <- utils::capture.output( suppressMessages( record_versions( - manifest = manifest, + versions = versions, repo = "https://wlandau.r-universe.dev" ) ) ) - contents <- jsonlite::read_json(manifest) + contents <- jsonlite::read_json(versions) expect_true(is.character(contents[[1L]]$package)) expect_true(length(contents[[1L]]$package) == 1L) - expect_true(file.exists(manifest)) - unlink(manifest) + expect_true(file.exists(versions)) + unlink(versions) }) From 5650422536737bfd9382c34ffd653093df75d334 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:14:49 -0400 Subject: [PATCH 07/17] fix docs --- R/record_issues.R | 2 ++ man/record_issues.Rd | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/R/record_issues.R b/R/record_issues.R index 30515c3c..d53279fc 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -1,9 +1,11 @@ #' @title Record package issues. #' @export +#' @family Recording checks #' @description Record package check and version issues in individual JSON #' files. #' @return `NULL` (invisibly). #' @inheritParams check_checks +#' @inheritParams check_versions #' @param output Character of length 1, file path to the folder to record #' new package issues. Each call to `record_issues()` overwrites the #' contents of the repo. diff --git a/man/record_issues.Rd b/man/record_issues.Rd index bc49d03d..9e810bb6 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -15,6 +15,12 @@ record_issues( \item{repo}{Character of length 1, URL of the repository of R package candidates for production.} +\item{versions}{Character of length 1, file path to a JSON manifest +tracking the history of released versions of packages. +The official versions file for R-multiverse is maintained and +updated periodically at +\url{https://github.com/r-multiverse/checks/blob/main/versions.json}.} + \item{output}{Character of length 1, file path to the folder to record new package issues. Each call to \code{record_issues()} overwrites the contents of the repo.} @@ -53,3 +59,4 @@ files. print(readLines(file.path(output, package))) } } +\concept{Recording checks} From 640bc500cf877fe90970adf6f7fa290d0b6e13f1 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:35:45 -0400 Subject: [PATCH 08/17] Add pkgdown workflow --- .github/workflows/pkgdown.yaml | 50 +++++++++++++++++++++++++++++ R/check_checks.R | 13 +++----- R/check_descriptions.R | 4 +-- R/check_versions.R | 9 ++---- R/package.R | 4 --- R/record_issues.R | 15 +++++++-- R/record_versions.R | 5 ++- README.md | 4 +-- _pkgdown.yml | 20 ++++++++++++ man/check_checks.Rd | 29 +++++++++-------- man/check_descriptions.Rd | 18 +++++++---- man/check_versions.Rd | 18 +++++++---- man/multiverse.internals-package.Rd | 9 ------ man/record_issues.Rd | 21 ++++++++++-- man/record_versions.Rd | 17 +++++++++- 15 files changed, 167 insertions(+), 69 deletions(-) create mode 100644 .github/workflows/pkgdown.yaml create mode 100644 _pkgdown.yml delete mode 100644 man/multiverse.internals-package.Rd diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 00000000..485433e4 --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,50 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main] + pull_request: + branches: [main] + release: + types: [published] + workflow_dispatch: + +name: pkgdown + +jobs: + pkgdown: + runs-on: ubuntu-latest + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-pandoc@v2 + + - name: system dependencies + if: runner.os == 'Linux' + run: sudo apt-get install -y libmbedtls-dev + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + cache-version: 2 + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.6.1 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/R/check_checks.R b/R/check_checks.R index f927ff35..eaf13641 100644 --- a/R/check_checks.R +++ b/R/check_checks.R @@ -1,14 +1,11 @@ #' @title Check R-universe package check results. #' @export -#' @family checks +#' @family package checks for production #' @description Check R-universe package check results. -#' @details This function scrapes the `src/contrib/PACKAGES.json` file -#' of the universe to check the data in the `DESCRIPTION` files of packages -#' for compliance. Right now, the only field checked is `Remotes:`. -#' A packages with a `Remotes:` field in the `DESCRIPTION` file may -#' depend on development versions of other packages and so are -#' excluded from the production universe. -#' @inheritSection check_versions Checks +#' @details [check_checks()] function scrapes the R-universe check API +#' to scan all R-multiverse packages for issues that may have +#' happened during building and testing. +#' @inheritSection record_issues Package checks for production #' @return A named list of information about packages which do not comply #' with `DESCRPTION` checks. Each name is a package name, #' and each element contains specific information about diff --git a/R/check_descriptions.R b/R/check_descriptions.R index 96f030db..e82c1e2a 100644 --- a/R/check_descriptions.R +++ b/R/check_descriptions.R @@ -1,6 +1,6 @@ #' @title Check package `DESCRIPTION` files. #' @export -#' @family checks +#' @family package checks for production #' @description Check the `DESCRIPTION` files of packages for specific #' issues. #' @details This function scrapes the `src/contrib/PACKAGES.json` file @@ -9,7 +9,7 @@ #' A packages with a `Remotes:` field in the `DESCRIPTION` file may #' depend on development versions of other packages and so are #' excluded from the production universe. -#' @inheritSection check_versions Checks +#' @inheritSection record_issues Package checks for production #' @return A named list of information about packages which do not comply #' with `DESCRPTION` checks. Each name is a package name, #' and each element contains specific information about diff --git a/R/check_versions.R b/R/check_versions.R index 23334ae2..8e8cf404 100644 --- a/R/check_versions.R +++ b/R/check_versions.R @@ -1,17 +1,12 @@ #' @title Check package versions. #' @export -#' @family checks +#' @family package checks for production #' @description Check package version number history for compliance. #' @details This function checks the version number history of packages #' in R-multiverse and reports any packages with issues. The current #' released version of a given package must be unique, and it must be #' greater than all the versions of all the previous package releases. -#' @section Checks: -#' Functions like [check_versions()] and [check_descriptions()] -#' the packages in . Only packages -#' that pass these checks will appear in -#' . For a complete list of checks, -#' see +#' @inheritSection record_issues Package checks for production #' @return A named list of information about packages which do not comply #' with version number history checks. Each name is a package name, #' and each element contains specific information about version diff --git a/R/package.R b/R/package.R index c82d1ff7..76f04ab4 100644 --- a/R/package.R +++ b/R/package.R @@ -1,7 +1,3 @@ -#' multiverse.internals: Internal Infrastructure for R-multiverse. -#' @description Internal Infrastructure for R-multiverse. -#' @name multiverse.internals-package -#' @family help #' @importFrom gh gh #' @importFrom jsonlite parse_json read_json stream_in write_json #' @importFrom nanonext ncurl parse_url status_code diff --git a/R/record_issues.R b/R/record_issues.R index d53279fc..726b52de 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -1,8 +1,17 @@ #' @title Record package issues. #' @export -#' @family Recording checks -#' @description Record package check and version issues in individual JSON -#' files. +#' @keywords package check data management +#' @description Record R-multiverse package issues in compact JSON files. +#' @section Package checks for production: +#' Functions like [check_versions()] and [check_descriptions()] +#' perform health checks for all packages in R-multiverse. +#' Only packages that pass these checks go to the production repository at +#' . For a complete list of checks, see +#' the `check_*()` functions listed at +#' . +#' [record_versions()] updates the version number history +#' of releases in R-multiverse, and [record_issues()] gathers +#' together all the issues about R-multiverse packages. #' @return `NULL` (invisibly). #' @inheritParams check_checks #' @inheritParams check_versions diff --git a/R/record_versions.R b/R/record_versions.R index 923a91fc..a3f875f0 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -1,12 +1,15 @@ #' @title Record the manifest of package versions. #' @export +#' @family package check data management #' @description Record the manifest of versions of packages #' and their hashes. #' @details This function tracks a manifest containing the current version, #' the current hash, the highest version ever released, and -#' the hash of the highest version ever released. It uses this information +#' the hash of the highest version ever released. +#' [check_versions()] uses this information #' to determine whether the package complies with best #' practices for version numbers. +#' @inheritSection record_issues Package checks for production #' @return `NULL` (invisibly). Writes a package version manifest #' and a manifest of version issues as JSON files. #' @param versions Character of length 1, file path to a JSON manifest diff --git a/README.md b/README.md index 05539e98..fcd49e59 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,4 @@ [![check](https://github.com/r-multiverse/multiverse.internals/actions/workflows/check.yaml/badge.svg)](https://github.com/r-multiverse/multiverse.internals/actions?query=workflow%3Acheck) [![lint](https://github.com/r-multiverse/multiverse.internals/actions/workflows/lint.yaml/badge.svg)](https://github.com/r-multiverse/multiverse.internals/actions?query=workflow%3Alint) -`multiverse.internals` is an R package to support the internal infrastructure for the R-multiverse project. - -For all matters please refer to . +`multiverse.internals` is an R package to support the internal infrastructure for the R-multiverse project. To learn about specific pieces of the R-multiverse infrastructure for reviewing and checking packages, please visit . For all other matters, please refer to . diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 00000000..31471613 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,20 @@ +url: https://r-multiverse.org/multiverse.internals/ +template: + bootstrap: 5 + bslib: + primary: "#152640" + +reference: +- title: Package contribution reviews + contents: + - review_pull_request + - review_pull_requests +- title: Package checks for production + contents: + - check_checks + - check_descriptions + - check_versions +- title: Package check data management + contents: + - record_issues + - record_versions diff --git a/man/check_checks.Rd b/man/check_checks.Rd index ef20cb58..39be524f 100644 --- a/man/check_checks.Rd +++ b/man/check_checks.Rd @@ -24,28 +24,29 @@ non-compliance. Check R-universe package check results. } \details{ -This function scrapes the \code{src/contrib/PACKAGES.json} file -of the universe to check the data in the \code{DESCRIPTION} files of packages -for compliance. Right now, the only field checked is \verb{Remotes:}. -A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may -depend on development versions of other packages and so are -excluded from the production universe. -} -\section{Checks}{ +\code{\link[=check_checks]{check_checks()}} function scrapes the R-universe check API +to scan all R-multiverse packages for issues that may have +happened during building and testing. +} +\section{Package checks for production}{ Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} -the packages in \url{https://multiverse.r-multiverse.org}. Only packages -that pass these checks will appear in -\url{https://production.r-multiverse.org}. For a complete list of checks, -see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{check_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. } \examples{ str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) } \seealso{ -Other checks: +Other package checks for production: \code{\link{check_descriptions}()}, \code{\link{check_versions}()} } -\concept{checks} +\concept{package checks for production} diff --git a/man/check_descriptions.Rd b/man/check_descriptions.Rd index 1049f5ad..a855bbf5 100644 --- a/man/check_descriptions.Rd +++ b/man/check_descriptions.Rd @@ -32,21 +32,25 @@ A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may depend on development versions of other packages and so are excluded from the production universe. } -\section{Checks}{ +\section{Package checks for production}{ Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} -the packages in \url{https://multiverse.r-multiverse.org}. Only packages -that pass these checks will appear in -\url{https://production.r-multiverse.org}. For a complete list of checks, -see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{check_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. } \examples{ str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) } \seealso{ -Other checks: +Other package checks for production: \code{\link{check_checks}()}, \code{\link{check_versions}()} } -\concept{checks} +\concept{package checks for production} diff --git a/man/check_versions.Rd b/man/check_versions.Rd index 160344f7..2d1dc05d 100644 --- a/man/check_versions.Rd +++ b/man/check_versions.Rd @@ -30,13 +30,17 @@ in R-multiverse and reports any packages with issues. The current released version of a given package must be unique, and it must be greater than all the versions of all the previous package releases. } -\section{Checks}{ +\section{Package checks for production}{ Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} -the packages in \url{https://multiverse.r-multiverse.org}. Only packages -that pass these checks will appear in -\url{https://production.r-multiverse.org}. For a complete list of checks, -see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{check_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. } \examples{ @@ -80,8 +84,8 @@ see \url{https://r-multiverse.org/multiverse.internals/reference.html#checks} str(out) } \seealso{ -Other checks: +Other package checks for production: \code{\link{check_checks}()}, \code{\link{check_descriptions}()} } -\concept{checks} +\concept{package checks for production} diff --git a/man/multiverse.internals-package.Rd b/man/multiverse.internals-package.Rd deleted file mode 100644 index a9c86f0c..00000000 --- a/man/multiverse.internals-package.Rd +++ /dev/null @@ -1,9 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/package.R -\name{multiverse.internals-package} -\alias{multiverse.internals-package} -\title{multiverse.internals: Internal Infrastructure for R-multiverse.} -\description{ -Internal Infrastructure for R-multiverse. -} -\concept{help} diff --git a/man/record_issues.Rd b/man/record_issues.Rd index 9e810bb6..5fc39b48 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -32,9 +32,21 @@ for the \code{mock} argument of each type of check.} \code{NULL} (invisibly). } \description{ -Record package check and version issues in individual JSON -files. +Record R-multiverse package issues in compact JSON files. } +\section{Package checks for production}{ + +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{check_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. +} + \examples{ # R-multiverse uses https://multiverse.r-multiverse.org as the repo. repo <- "https://wlandau.r-universe.dev" # just for testing and examples @@ -59,4 +71,7 @@ files. print(readLines(file.path(output, package))) } } -\concept{Recording checks} +\keyword{check} +\keyword{data} +\keyword{management} +\keyword{package} diff --git a/man/record_versions.Rd b/man/record_versions.Rd index aaa22b5a..608723ba 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -33,10 +33,24 @@ and their hashes. \details{ This function tracks a manifest containing the current version, the current hash, the highest version ever released, and -the hash of the highest version ever released. It uses this information +the hash of the highest version ever released. +\code{\link[=check_versions]{check_versions()}} uses this information to determine whether the package complies with best practices for version numbers. } +\section{Package checks for production}{ + +Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{check_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. +} + \examples{ # R-multiverse uses https://multiverse.r-multiverse.org as the repo. repo <- "https://wlandau.r-universe.dev" # just for testing and examples @@ -55,3 +69,4 @@ practices for version numbers. ) readLines(versions) } +\concept{package check data management} From 4d23c2d03cb0d5a53faa3325231b70af7192d8ae Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 21 May 2024 16:38:02 -0400 Subject: [PATCH 09/17] version and news --- DESCRIPTION | 2 +- NEWS.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 63f2de54..06ecd984 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Package: multiverse.internals Title: Internal Infrastructure for R-multiverse Description: R-multiverse requires this internal internal infrastructure package to automate contribution reviews and populate universes. -Version: 0.1.4 +Version: 0.2.0 License: MIT + file LICENSE URL: https://github.com/r-multiverse/multiverse.internals BugReports: https://github.com/r-multiverse/multiverse.internals/issues diff --git a/NEWS.md b/NEWS.md index 9a1b2924..45edeefa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# multiverse.internals 0.2.0 + +* Add more checks to `record_issues()`: results from the R-universe check API, plus specific results from package `DESCRIPTION` files. +* Refactor and document specific checks in `check_checks()`, `check_descriptions()`, and `check_versions()`. +* Add a `pkgdown` website. + # multiverse.internals 0.1.4 * Do not write `version_issues.json` from `record_versions()`. From 8ce55479430c12ec2b8315b9331b3caadd7a1d67 Mon Sep 17 00:00:00 2001 From: wlandau Date: Wed, 22 May 2024 10:16:26 -0400 Subject: [PATCH 10/17] Stream in R-universe check API JSON --- R/check_checks.R | 2 +- R/utils_check.R | 7 ++++--- man/check_checks.Rd | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/R/check_checks.R b/R/check_checks.R index eaf13641..cafaa364 100644 --- a/R/check_checks.R +++ b/R/check_checks.R @@ -12,7 +12,7 @@ #' non-compliance. #' @inheritParams check_descriptions #' @examples -#' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +#' str(check_checks(repo = "https://multiverse.r-multiverse.org")) check_checks <- function( repo = "https://multiverse.r-multiverse.org", mock = NULL diff --git a/R/utils_check.R b/R/utils_check.R index 42f96e7d..ad6d6ff8 100644 --- a/R/utils_check.R +++ b/R/utils_check.R @@ -31,10 +31,11 @@ get_package_api <- function( listing <- file.path( repo, "api", - paste0("packages?fields=", paste(fields, collapse = ",")) + paste0("packages?stream=true&fields=", paste(fields, collapse = ",")) ) - jsonlite::parse_json( - json = nanonext::ncurl(url = listing)$data, # TODO: needs to be paginated + jsonlite::stream_in( + con = gzcon(url(listing)), + verbose = FALSE, simplifyVector = TRUE, simplifyDataFrame = TRUE, simplifyMatrix = TRUE diff --git a/man/check_checks.Rd b/man/check_checks.Rd index 39be524f..2061b739 100644 --- a/man/check_checks.Rd +++ b/man/check_checks.Rd @@ -42,7 +42,7 @@ together all the issues about R-multiverse packages. } \examples{ - str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) + str(check_checks(repo = "https://multiverse.r-multiverse.org")) } \seealso{ Other package checks for production: From 1cad4f03b0278debe42d2d2f9dc3b1d943d42e30 Mon Sep 17 00:00:00 2001 From: wlandau Date: Wed, 22 May 2024 11:05:51 -0400 Subject: [PATCH 11/17] Record date that an issue was first noticed --- R/record_issues.R | 57 ++++++++++++++++++---- man/record_issues.Rd | 16 +++++- tests/testthat/test-record_issues.R | 75 +++++++++++++++++++++++++++-- 3 files changed, 132 insertions(+), 16 deletions(-) diff --git a/R/record_issues.R b/R/record_issues.R index 726b52de..b1fb577b 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -1,7 +1,8 @@ #' @title Record package issues. #' @export #' @keywords package check data management -#' @description Record R-multiverse package issues in compact JSON files. +#' @description Record R-multiverse package issues in +#' package-specific JSON files. #' @section Package checks for production: #' Functions like [check_versions()] and [check_descriptions()] #' perform health checks for all packages in R-multiverse. @@ -12,6 +13,16 @@ #' [record_versions()] updates the version number history #' of releases in R-multiverse, and [record_issues()] gathers #' together all the issues about R-multiverse packages. +#' @section Issue files: +#' For each package with observed problems, [record_issues()] writes +#' an issue file. This issue file is a JSON list with one element +#' per type of failing check. Each element has an informative name +#' (for example, `checks`, `descriptions`, or `versions`) +#' and a list of diagnostic information. +#' +#' Each issue file also has a `date` field. This date the day that +#' an issue was first noticed. It automatically resets the next time +#' all package are resolved. #' @return `NULL` (invisibly). #' @inheritParams check_checks #' @inheritParams check_versions @@ -49,11 +60,12 @@ record_issues <- function( output = "issues", mock = NULL ) { + today <- mock$today %|||% format(Sys.Date(), fmt = "yyyy-mm-dd") list() |> issues(check_checks(repo, mock$checks), "checks") |> issues(check_descriptions(repo, mock$descriptions), "descriptions") |> issues(check_versions(versions = versions), "versions") |> - overwrite_issues(output = output) + overwrite_issues(output = output, today = today) invisible() } @@ -64,14 +76,39 @@ issues <- function(total, subset, category) { total } -overwrite_issues <- function(issues, output) { +overwrite_issues <- function(issues, output, today) { + packages <- list.files(output) + dates <- lapply( + X = packages, + FUN = function(path) { + jsonlite::read_json(file.path(output, path), simplifyVector = TRUE)$date + } + ) + names(dates) <- packages unlink(output, recursive = TRUE) dir.create(output) - for (package in names(issues)) { - jsonlite::write_json( - x = issues[[package]], - path = file.path(output, package), - pretty = TRUE - ) - } + lapply( + X = names(issues), + FUN = overwrite_package_issues, + issues = issues, + output = output, + today = today, + dates = dates + ) +} + +overwrite_package_issues <- function( + package, + issues, + output, + today, + dates +) { + path <- file.path(output, package) + issues[[package]]$date <- dates[[package]] %|||% today + jsonlite::write_json( + x = issues[[package]], + path = file.path(output, package), + pretty = TRUE + ) } diff --git a/man/record_issues.Rd b/man/record_issues.Rd index 5fc39b48..f35f00a9 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -32,7 +32,8 @@ for the \code{mock} argument of each type of check.} \code{NULL} (invisibly). } \description{ -Record R-multiverse package issues in compact JSON files. +Record R-multiverse package issues in +package-specific JSON files. } \section{Package checks for production}{ @@ -47,6 +48,19 @@ of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} g together all the issues about R-multiverse packages. } +\section{Issue files}{ + +For each package with observed problems, \code{\link[=record_issues]{record_issues()}} writes +an issue file. This issue file is a JSON list with one element +per type of failing check. Each element has an informative name +(for example, \code{checks}, \code{descriptions}, or \code{versions}) +and a list of diagnostic information. + +Each issue file also has a \code{date} field. This date the day that +an issue was first noticed. It automatically resets the next time +all package are resolved. +} + \examples{ # R-multiverse uses https://multiverse.r-multiverse.org as the repo. repo <- "https://wlandau.r-universe.dev" # just for testing and examples diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index fc588bc9..ad97cd4d 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -4,7 +4,8 @@ test_that("record_issues() mocked", { versions = mock_versions(), mock = list( checks = mock_checks, - descriptions = mock_descriptions + descriptions = mock_descriptions, + today = "2024-01-01" ), output = output ) @@ -37,7 +38,8 @@ test_that("record_issues() mocked", { "_winbinary" = "src-failure", "_status" = "src-failure", "_buildurl" = file.path(runs, "8487512222") - ) + ), + date = "2024-01-01" ) ) expect_equal( @@ -56,7 +58,8 @@ test_that("record_issues() mocked", { ), descriptions = list( remotes = matrix(c("hyunjimoon/SBC", "stan-dev/cmdstanr"), nrow = 1) - ) + ), + date = "2024-01-01" ) ) expect_equal( @@ -70,7 +73,8 @@ test_that("record_issues() mocked", { hash_current = "hash_0.0.1", version_highest = "1.0.0", hash_highest = "hash_1.0.0" - ) + ), + date = "2024-01-01" ) ) expect_equal( @@ -84,11 +88,72 @@ test_that("record_issues() mocked", { hash_current = "hash_1.0.0-modified", version_highest = "1.0.0", hash_highest = "hash_1.0.0" - ) + ), + date = "2024-01-01" ) ) }) +test_that("record_issues() date works", { + output <- tempfile() + record_issues( + versions = mock_versions(), + mock = list( + checks = mock_checks, + descriptions = mock_descriptions, + today = "2024-01-01" + ), + output = output + ) + record_issues( + versions = mock_versions(), + mock = list( + checks = mock_checks, + descriptions = mock_descriptions + ), + output = output + ) + for (file in list.files(output, full.names = TRUE)) { + date <- jsonlite::read_json(file, simplifyVector = TRUE)$date + expect_equal(date, "2024-01-01") + } + never_fixed <- c( + "httpgd", + "INLA", + "stantargets", + "string2path", + "tidytensor", + "version_decremented" + ) + once_fixed <- c( + "audio.whisper", + "polars", + "SBC", + "tidypolars", + "version_unmodified" + ) + lapply(file.path(output, once_fixed), unlink) + record_issues( + versions = mock_versions(), + mock = list( + checks = mock_checks, + descriptions = mock_descriptions + ), + output = output + ) + for (package in never_fixed) { + path <- file.path(output, package) + date <- jsonlite::read_json(path, simplifyVector = TRUE)$date + expect_equal(date, "2024-01-01") + } + today <- format(Sys.Date(), fmt = "yyyy-mm-dd") + for (package in once_fixed) { + path <- file.path(output, package) + date <- jsonlite::read_json(path, simplifyVector = TRUE)$date + expect_equal(date, today) + } +}) + test_that("record_issues() on a small repo", { output <- tempfile() versions <- tempfile() From e494c0f72b582a8135f4882708577a52dc7674d9 Mon Sep 17 00:00:00 2001 From: wlandau Date: Wed, 22 May 2024 11:10:19 -0400 Subject: [PATCH 12/17] change url --- R/check_checks.R | 6 +++++- man/check_checks.Rd | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/R/check_checks.R b/R/check_checks.R index cafaa364..3dce20bb 100644 --- a/R/check_checks.R +++ b/R/check_checks.R @@ -12,7 +12,11 @@ #' non-compliance. #' @inheritParams check_descriptions #' @examples -#' str(check_checks(repo = "https://multiverse.r-multiverse.org")) +#' issues <- check_checks( +#' # R-multiverse uses https://multiverse.r-multiverse.org +#' repo = "https://wlandau.r-universe.dev" +#' ) +#' str(issues) check_checks <- function( repo = "https://multiverse.r-multiverse.org", mock = NULL diff --git a/man/check_checks.Rd b/man/check_checks.Rd index 2061b739..295bb76f 100644 --- a/man/check_checks.Rd +++ b/man/check_checks.Rd @@ -42,7 +42,11 @@ together all the issues about R-multiverse packages. } \examples{ - str(check_checks(repo = "https://multiverse.r-multiverse.org")) + issues <- check_checks( + # R-multiverse uses https://multiverse.r-multiverse.org + repo = "https://wlandau.r-universe.dev" + ) + str(issues) } \seealso{ Other package checks for production: From 1e0250de0a9a74ba8a9eee47fe8c759b58f2fad9 Mon Sep 17 00:00:00 2001 From: wlandau Date: Wed, 22 May 2024 11:14:56 -0400 Subject: [PATCH 13/17] Use different URL in example --- R/check_descriptions.R | 6 +++++- man/check_descriptions.Rd | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/R/check_descriptions.R b/R/check_descriptions.R index e82c1e2a..f613b472 100644 --- a/R/check_descriptions.R +++ b/R/check_descriptions.R @@ -20,7 +20,11 @@ #' an optional pre-computed data frame with details about packages #' for this type of check. #' @examples -#' str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) +#' issues <- check_descriptions( +#' # R-multiverse uses https://multiverse.r-multiverse.org +#' repo = "https://wlandau.r-universe.dev" +#' ) +#' str(issues) check_descriptions <- function( repo = "https://multiverse.r-multiverse.org", mock = NULL diff --git a/man/check_descriptions.Rd b/man/check_descriptions.Rd index a855bbf5..5343165b 100644 --- a/man/check_descriptions.Rd +++ b/man/check_descriptions.Rd @@ -46,7 +46,11 @@ together all the issues about R-multiverse packages. } \examples{ - str(check_descriptions(repo = "https://multiverse.r-multiverse.org")) + issues <- check_descriptions( + # R-multiverse uses https://multiverse.r-multiverse.org + repo = "https://wlandau.r-universe.dev" + ) + str(issues) } \seealso{ Other package checks for production: From 50be3cdafc29839d6598c5b9e255ff0645535410 Mon Sep 17 00:00:00 2001 From: wlandau Date: Fri, 24 May 2024 10:21:31 -0400 Subject: [PATCH 14/17] Improve names and infrastructure --- NAMESPACE | 8 ++- R/check_checks.R | 45 --------------- R/check_descriptions.R | 43 -------------- R/issues_checks.R | 40 +++++++++++++ R/issues_descriptions.R | 33 +++++++++++ R/{check_versions.R => issues_versions.R} | 10 ++-- R/meta_checks.R | 35 ++++++++++++ R/meta_packages.R | 25 +++++++++ R/record_issues.R | 28 +++++----- R/record_versions.R | 14 ++--- R/utils_check.R | 43 -------------- R/utils_issues.R | 10 ++++ _pkgdown.yml | 14 +++-- man/check_checks.Rd | 56 ------------------- man/issues_checks.Rd | 50 +++++++++++++++++ ...descriptions.Rd => issues_descriptions.Rd} | 35 +++++------- man/{check_versions.Rd => issues_versions.Rd} | 24 ++++---- man/meta_checks.Rd | 24 ++++++++ man/meta_packages.Rd | 23 ++++++++ man/record_issues.Rd | 15 +++-- man/record_versions.Rd | 8 +-- tests/testthat/helper-mock.R | 12 ++-- tests/testthat/test-check_descriptions.R | 17 ------ ...st-check_checks.R => test-issues_checks.R} | 9 +-- tests/testthat/test-issues_descriptions.R | 18 ++++++ ...heck_versions.R => test-issues_versions.R} | 8 +-- tests/testthat/test-meta_checks.R | 14 +++++ tests/testthat/test-meta_packages.R | 11 ++++ tests/testthat/test-record_issues.R | 18 +++--- 29 files changed, 385 insertions(+), 305 deletions(-) delete mode 100644 R/check_checks.R delete mode 100644 R/check_descriptions.R create mode 100644 R/issues_checks.R create mode 100644 R/issues_descriptions.R rename R/{check_versions.R => issues_versions.R} (92%) create mode 100644 R/meta_checks.R create mode 100644 R/meta_packages.R delete mode 100644 R/utils_check.R create mode 100644 R/utils_issues.R delete mode 100644 man/check_checks.Rd create mode 100644 man/issues_checks.Rd rename man/{check_descriptions.Rd => issues_descriptions.Rd} (60%) rename man/{check_versions.Rd => issues_versions.Rd} (84%) create mode 100644 man/meta_checks.Rd create mode 100644 man/meta_packages.Rd delete mode 100644 tests/testthat/test-check_descriptions.R rename tests/testthat/{test-check_checks.R => test-issues_checks.R} (88%) create mode 100644 tests/testthat/test-issues_descriptions.R rename tests/testthat/{test-check_versions.R => test-issues_versions.R} (89%) create mode 100644 tests/testthat/test-meta_checks.R create mode 100644 tests/testthat/test-meta_packages.R diff --git a/NAMESPACE b/NAMESPACE index 5bf93c0b..f976b559 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,10 +4,12 @@ export(aggregate_contributions) export(assert_cran_url) export(assert_package) export(assert_release_exists) -export(check_checks) -export(check_descriptions) -export(check_versions) export(get_current_versions) +export(issues_checks) +export(issues_descriptions) +export(issues_versions) +export(meta_checks) +export(meta_packages) export(record_issues) export(record_versions) export(review_pull_request) diff --git a/R/check_checks.R b/R/check_checks.R deleted file mode 100644 index 3dce20bb..00000000 --- a/R/check_checks.R +++ /dev/null @@ -1,45 +0,0 @@ -#' @title Check R-universe package check results. -#' @export -#' @family package checks for production -#' @description Check R-universe package check results. -#' @details [check_checks()] function scrapes the R-universe check API -#' to scan all R-multiverse packages for issues that may have -#' happened during building and testing. -#' @inheritSection record_issues Package checks for production -#' @return A named list of information about packages which do not comply -#' with `DESCRPTION` checks. Each name is a package name, -#' and each element contains specific information about -#' non-compliance. -#' @inheritParams check_descriptions -#' @examples -#' issues <- check_checks( -#' # R-multiverse uses https://multiverse.r-multiverse.org -#' repo = "https://wlandau.r-universe.dev" -#' ) -#' str(issues) -check_checks <- function( - repo = "https://multiverse.r-multiverse.org", - mock = NULL -) { - fields_check <- c( - "_linuxdevel", - "_macbinary", - "_wasmbinary", - "_winbinary", - "_status" - ) - fields_info <- c( - "_buildurl" - ) - fields <- c(fields_check, fields_info) - index <- mock %|||% get_package_api(repo = repo, fields = fields) - for (field in fields) { - index[[field]][is.na(index[[field]])] <- "src-failure" - } - success <- rep(TRUE, nrow(index)) - for (field in fields_check) { - success <- success & (index[[field]] %in% c("success", "skipped")) - } - index <- index[!success,, drop = FALSE] # nolint - check_list(index[, c("Package", fields)]) -} diff --git a/R/check_descriptions.R b/R/check_descriptions.R deleted file mode 100644 index f613b472..00000000 --- a/R/check_descriptions.R +++ /dev/null @@ -1,43 +0,0 @@ -#' @title Check package `DESCRIPTION` files. -#' @export -#' @family package checks for production -#' @description Check the `DESCRIPTION` files of packages for specific -#' issues. -#' @details This function scrapes the `src/contrib/PACKAGES.json` file -#' of the universe to check the data in the `DESCRIPTION` files of packages -#' for compliance. Right now, the only field checked is `Remotes:`. -#' A packages with a `Remotes:` field in the `DESCRIPTION` file may -#' depend on development versions of other packages and so are -#' excluded from the production universe. -#' @inheritSection record_issues Package checks for production -#' @return A named list of information about packages which do not comply -#' with `DESCRPTION` checks. Each name is a package name, -#' and each element contains specific information about -#' non-compliance. -#' @param repo Character of length 1, URL of the repository -#' of R package candidates for production. -#' @param mock For testing purposes only, -#' an optional pre-computed data frame with details about packages -#' for this type of check. -#' @examples -#' issues <- check_descriptions( -#' # R-multiverse uses https://multiverse.r-multiverse.org -#' repo = "https://wlandau.r-universe.dev" -#' ) -#' str(issues) -check_descriptions <- function( - repo = "https://multiverse.r-multiverse.org", - mock = NULL -) { - fields <- "Remotes" - index <- mock %|||% get_package_index(repo = repo, fields = fields) - index <- check_descriptions_remotes(index) - index <- index[, c("Package", fields)] - check_list(index) -} - -check_descriptions_remotes <- function(index) { - index$Remotes <- index$Remotes %|||% replicate(nrow(index), NULL) - index$Remotes <- lapply(index$Remotes, function(x) x[nzchar(x)]) - index[vapply(index$Remotes, length, integer(1L)) > 0L, ] -} diff --git a/R/issues_checks.R b/R/issues_checks.R new file mode 100644 index 00000000..03fbc6db --- /dev/null +++ b/R/issues_checks.R @@ -0,0 +1,40 @@ +#' @title Report issues from R-universe package check results. +#' @export +#' @family issues +#' @description Check R-universe package check results. +#' @details [issues_checks()] function scrapes the R-universe check API +#' to scan all R-multiverse packages for issues that may have +#' happened during building and testing. +#' @inheritSection record_issues Package issues +#' @return A named list of information about packages which do not comply +#' with `DESCRPTION` checks. Each name is a package name, +#' and each element contains specific information about +#' non-compliance. +#' @param meta A data frame with R-universe package check results +#' returned by [meta_checks()]. +#' @examples +#' meta <- meta_checks(repo = "https://wlandau.r-universe.dev") +#' issues <- issues_checks(meta = meta) +#' str(issues) +issues_checks <- function(meta) { + fields_check <- c( + "_linuxdevel", + "_macbinary", + "_wasmbinary", + "_winbinary", + "_status" + ) + fields_info <- c( + "_buildurl" + ) + fields <- c(fields_check, fields_info) + for (field in fields) { + meta[[field]][is.na(meta[[field]])] <- "src-failure" + } + success <- rep(TRUE, nrow(meta)) + for (field in fields_check) { + success <- success & (meta[[field]] %in% c("success", "skipped")) + } + meta <- meta[!success,, drop = FALSE] # nolint + issues_list(meta[, c("package", fields)]) +} diff --git a/R/issues_descriptions.R b/R/issues_descriptions.R new file mode 100644 index 00000000..b77c0e0f --- /dev/null +++ b/R/issues_descriptions.R @@ -0,0 +1,33 @@ +#' @title Check package `DESCRIPTION` files. +#' @export +#' @family issues +#' @description Check the `DESCRIPTION` files of packages for specific +#' issues. +#' @details This function scrapes the `src/contrib/PACKAGES.json` file +#' of the universe to check the data in the `DESCRIPTION` files of packages +#' for compliance. Right now, the only field checked is `Remotes:`. +#' A packages with a `Remotes:` field in the `DESCRIPTION` file may +#' depend on development versions of other packages and so are +#' excluded from the production universe. +#' @inheritSection record_issues Package issues +#' @return A named list of information about packages which do not comply +#' with `DESCRPTION` checks. Each name is a package name, +#' and each element contains specific information about +#' non-compliance. +#' @param meta A data frame of package metadata returned by [meta_packages()]. +#' @examples +#' meta <- meta_packages(repo = "https://wlandau.r-universe.dev") +#' issues <- issues_descriptions(meta = meta) +#' str(issues) +issues_descriptions <- function(meta) { + meta <- issues_descriptions_remotes(meta) + fields <- "remotes" + meta <- meta[, c("package", fields)] + issues_list(meta) +} + +issues_descriptions_remotes <- function(meta) { + meta$remotes <- meta$remotes %|||% replicate(nrow(meta), NULL) + meta$remotes <- lapply(meta$remotes, function(x) x[nzchar(x)]) + meta[vapply(meta$remotes, length, integer(1L)) > 0L, ] +} diff --git a/R/check_versions.R b/R/issues_versions.R similarity index 92% rename from R/check_versions.R rename to R/issues_versions.R index 8e8cf404..523b643d 100644 --- a/R/check_versions.R +++ b/R/issues_versions.R @@ -1,12 +1,12 @@ #' @title Check package versions. #' @export -#' @family package checks for production +#' @family issues #' @description Check package version number history for compliance. #' @details This function checks the version number history of packages #' in R-multiverse and reports any packages with issues. The current #' released version of a given package must be unique, and it must be #' greater than all the versions of all the previous package releases. -#' @inheritSection record_issues Package checks for production +#' @inheritSection record_issues Package issues #' @return A named list of information about packages which do not comply #' with version number history checks. Each name is a package name, #' and each element contains specific information about version @@ -51,13 +51,13 @@ #' ) #' versions <- tempfile() #' writeLines(lines, versions) -#' out <- check_versions(versions) +#' out <- issues_versions(versions) #' str(out) -check_versions <- function(versions) { +issues_versions <- function(versions) { history <- jsonlite::read_json(path = versions, simplifyVector = TRUE) aligned <- (history$version_current == history$version_highest) & (history$hash_current == history$hash_highest) aligned[is.na(aligned)] <- TRUE out <- history[!aligned,, drop = FALSE] # nolint - check_list(out) + issues_list(out) } diff --git a/R/meta_checks.R b/R/meta_checks.R new file mode 100644 index 00000000..a1bc56a9 --- /dev/null +++ b/R/meta_checks.R @@ -0,0 +1,35 @@ +#' @title List metadata about R-universe package checks +#' @export +#' @family list +#' @description List package checks results reported by the +#' R-universe package API. +#' @return A data frame with one row per package and columns with +#' package check results. +#' @param repo Character of length 1, URL of the package repository. +#' R-multiverse uses `"https://multiverse.r-multiverse.org"`. +#' @examples +#' meta_checks(repo = "https://wlandau.r-universe.dev") +meta_checks <- function(repo = "https://multiverse.r-multiverse.org") { + fields <- c( + "_buildurl", + "_linuxdevel", + "_macbinary", + "_wasmbinary", + "_winbinary", + "_status" + ) + listing <- file.path( + repo, + "api", + paste0("packages?stream=true&fields=", paste(fields, collapse = ",")) + ) + out <- jsonlite::stream_in( + con = gzcon(url(listing)), + verbose = FALSE, + simplifyVector = TRUE, + simplifyDataFrame = TRUE, + simplifyMatrix = TRUE + ) + colnames(out) <- tolower(colnames(out)) + out +} diff --git a/R/meta_packages.R b/R/meta_packages.R new file mode 100644 index 00000000..54ed0cae --- /dev/null +++ b/R/meta_packages.R @@ -0,0 +1,25 @@ +#' @title List package metadata +#' @export +#' @family meta +#' @description List package metadata in an R universe. +#' @return A data frame with one row per package and columns with package +#' metadata. +#' @inheritParams meta_checks +#' @examples +#' meta_packages(repo = "https://wlandau.r-universe.dev") +meta_packages <- function(repo = "https://multiverse.r-multiverse.org") { + fields <- c("Version", "Remotes", "RemoteSha") + listing <- file.path( + contrib.url(repos = repo, type = "source"), + paste0("PACKAGES.json?fields=", paste(fields, collapse = ",")) + ) + out <- jsonlite::stream_in( + con = gzcon(url(listing)), + verbose = FALSE, + simplifyVector = TRUE, + simplifyDataFrame = TRUE, + simplifyMatrix = TRUE + ) + colnames(out) <- tolower(colnames(out)) + out +} diff --git a/R/record_issues.R b/R/record_issues.R index b1fb577b..3a2ca96a 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -3,12 +3,12 @@ #' @keywords package check data management #' @description Record R-multiverse package issues in #' package-specific JSON files. -#' @section Package checks for production: -#' Functions like [check_versions()] and [check_descriptions()] +#' @section Package issues: +#' Functions like [issues_versions()] and [issues_descriptions()] #' perform health checks for all packages in R-multiverse. #' Only packages that pass these checks go to the production repository at #' . For a complete list of checks, see -#' the `check_*()` functions listed at +#' the `issues_*()` functions listed at #' . #' [record_versions()] updates the version number history #' of releases in R-multiverse, and [record_issues()] gathers @@ -24,16 +24,16 @@ #' an issue was first noticed. It automatically resets the next time #' all package are resolved. #' @return `NULL` (invisibly). -#' @inheritParams check_checks -#' @inheritParams check_versions +#' @inheritParams meta_checks +#' @inheritParams issues_checks +#' @inheritParams issues_versions #' @param output Character of length 1, file path to the folder to record #' new package issues. Each call to `record_issues()` overwrites the #' contents of the repo. #' @param mock For testing purposes only, a named list of data frames -#' for the `mock` argument of each type of check. +#' for inputs to various intermediate functions. #' @examples -#' # R-multiverse uses https://multiverse.r-multiverse.org as the repo. -#' repo <- "https://wlandau.r-universe.dev" # just for testing and examples +#' repo <- "https://wlandau.r-universe.dev" #' output <- tempfile() #' versions <- tempfile() #' record_versions( @@ -61,15 +61,17 @@ record_issues <- function( mock = NULL ) { today <- mock$today %|||% format(Sys.Date(), fmt = "yyyy-mm-dd") - list() |> - issues(check_checks(repo, mock$checks), "checks") |> - issues(check_descriptions(repo, mock$descriptions), "descriptions") |> - issues(check_versions(versions = versions), "versions") |> + checks <- mock$checks %|||% meta_checks(repo = repo) + packages <- mock$packages %|||% meta_packages(repo = repo) + issues <- list() |> + add_issues(issues_checks(meta = checks), "checks") |> + add_issues(issues_descriptions(meta = packages), "descriptions") |> + add_issues(issues_versions(versions = versions), "versions") |> overwrite_issues(output = output, today = today) invisible() } -issues <- function(total, subset, category) { +add_issues <- function(total, subset, category) { for (package in names(subset)) { total[[package]][[category]] <- subset[[package]] } diff --git a/R/record_versions.R b/R/record_versions.R index a3f875f0..1504846f 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -6,10 +6,10 @@ #' @details This function tracks a manifest containing the current version, #' the current hash, the highest version ever released, and #' the hash of the highest version ever released. -#' [check_versions()] uses this information +#' [issues_versions()] uses this information #' to determine whether the package complies with best #' practices for version numbers. -#' @inheritSection record_issues Package checks for production +#' @inheritSection record_issues Package issues #' @return `NULL` (invisibly). Writes a package version manifest #' and a manifest of version issues as JSON files. #' @param versions Character of length 1, file path to a JSON manifest @@ -61,11 +61,11 @@ record_versions <- function( get_current_versions <- function( repo = "https://multiverse.r-multiverse.org" ) { - index <- get_package_index(repo = repo, fields = "RemoteSha") - index <- index[, c("Package", "Version", "RemoteSha")] - colnames(index) <- c("package", "version_current", "hash_current") - rownames(index) <- NULL - index + meta <- meta_packages(repo = repo) + meta <- meta[, c("package", "version", "remotesha")] + colnames(meta) <- c("package", "version_current", "hash_current") + rownames(meta) <- NULL + meta } read_versions_previous <- function(versions) { diff --git a/R/utils_check.R b/R/utils_check.R deleted file mode 100644 index ad6d6ff8..00000000 --- a/R/utils_check.R +++ /dev/null @@ -1,43 +0,0 @@ -check_list <- function(x) { - colnames(x) <- tolower(colnames(x)) - package <- x$package - x$package <- NULL - out <- lapply(split(x, seq_len(nrow(x))), as.list) - names(out) <- package - out[order(package)] -} - -get_package_index <- function( - repo = "https://multiverse.r-multiverse.org", - fields = character(0L) -) { - listing <- file.path( - contrib.url(repos = repo, type = "source"), - paste0("PACKAGES.json?fields=", paste(fields, collapse = ",")) - ) - jsonlite::stream_in( - con = gzcon(url(listing)), - verbose = FALSE, - simplifyVector = TRUE, - simplifyDataFrame = TRUE, - simplifyMatrix = TRUE - ) -} - -get_package_api <- function( - repo = "https://multiverse.r-multiverse.org", - fields = character(0L) -) { - listing <- file.path( - repo, - "api", - paste0("packages?stream=true&fields=", paste(fields, collapse = ",")) - ) - jsonlite::stream_in( - con = gzcon(url(listing)), - verbose = FALSE, - simplifyVector = TRUE, - simplifyDataFrame = TRUE, - simplifyMatrix = TRUE - ) -} diff --git a/R/utils_issues.R b/R/utils_issues.R new file mode 100644 index 00000000..4b7bf97d --- /dev/null +++ b/R/utils_issues.R @@ -0,0 +1,10 @@ +issues_list <- function(x) { + colnames(x) <- tolower(colnames(x)) + out <- list() + for (index in seq_len(nrow(x))) { + for (field in setdiff(colnames(x), "package")) { + out[[x$package[index]]][[field]] <- x[[field]][[index]] + } + } + out[order(as.character(names(out)))] +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 31471613..e5e165fc 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -9,12 +9,16 @@ reference: contents: - review_pull_request - review_pull_requests -- title: Package checks for production +- title: List metadata contents: - - check_checks - - check_descriptions - - check_versions -- title: Package check data management + - meta_checks + - meta_packages +- title: Check issues + contents: + - issues_checks + - issues_descriptions + - issues_versions +- title: Record issues contents: - record_issues - record_versions diff --git a/man/check_checks.Rd b/man/check_checks.Rd deleted file mode 100644 index 295bb76f..00000000 --- a/man/check_checks.Rd +++ /dev/null @@ -1,56 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check_checks.R -\name{check_checks} -\alias{check_checks} -\title{Check R-universe package check results.} -\usage{ -check_checks(repo = "https://multiverse.r-multiverse.org", mock = NULL) -} -\arguments{ -\item{repo}{Character of length 1, URL of the repository -of R package candidates for production.} - -\item{mock}{For testing purposes only, -an optional pre-computed data frame with details about packages -for this type of check.} -} -\value{ -A named list of information about packages which do not comply -with \code{DESCRPTION} checks. Each name is a package name, -and each element contains specific information about -non-compliance. -} -\description{ -Check R-universe package check results. -} -\details{ -\code{\link[=check_checks]{check_checks()}} function scrapes the R-universe check API -to scan all R-multiverse packages for issues that may have -happened during building and testing. -} -\section{Package checks for production}{ - -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} -perform health checks for all packages in R-multiverse. -Only packages that pass these checks go to the production repository at -\url{https://production.r-multiverse.org}. For a complete list of checks, see -the \verb{check_*()} functions listed at -\url{https://r-multiverse.org/multiverse.internals/reference.html}. -\code{\link[=record_versions]{record_versions()}} updates the version number history -of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers -together all the issues about R-multiverse packages. -} - -\examples{ - issues <- check_checks( - # R-multiverse uses https://multiverse.r-multiverse.org - repo = "https://wlandau.r-universe.dev" - ) - str(issues) -} -\seealso{ -Other package checks for production: -\code{\link{check_descriptions}()}, -\code{\link{check_versions}()} -} -\concept{package checks for production} diff --git a/man/issues_checks.Rd b/man/issues_checks.Rd new file mode 100644 index 00000000..560502cc --- /dev/null +++ b/man/issues_checks.Rd @@ -0,0 +1,50 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/issues_checks.R +\name{issues_checks} +\alias{issues_checks} +\title{Report issues from R-universe package check results.} +\usage{ +issues_checks(meta) +} +\arguments{ +\item{meta}{A data frame with R-universe package check results +returned by \code{\link[=meta_checks]{meta_checks()}}.} +} +\value{ +A named list of information about packages which do not comply +with \code{DESCRPTION} checks. Each name is a package name, +and each element contains specific information about +non-compliance. +} +\description{ +Check R-universe package check results. +} +\details{ +\code{\link[=issues_checks]{issues_checks()}} function scrapes the R-universe check API +to scan all R-multiverse packages for issues that may have +happened during building and testing. +} +\section{Package issues}{ + +Functions like \code{\link[=issues_versions]{issues_versions()}} and \code{\link[=issues_descriptions]{issues_descriptions()}} +perform health checks for all packages in R-multiverse. +Only packages that pass these checks go to the production repository at +\url{https://production.r-multiverse.org}. For a complete list of checks, see +the \verb{issues_*()} functions listed at +\url{https://r-multiverse.org/multiverse.internals/reference.html}. +\code{\link[=record_versions]{record_versions()}} updates the version number history +of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers +together all the issues about R-multiverse packages. +} + +\examples{ + meta <- meta_checks(repo = "https://wlandau.r-universe.dev") + issues <- issues_checks(meta = meta) + str(issues) +} +\seealso{ +Other issues: +\code{\link{issues_descriptions}()}, +\code{\link{issues_versions}()} +} +\concept{issues} diff --git a/man/check_descriptions.Rd b/man/issues_descriptions.Rd similarity index 60% rename from man/check_descriptions.Rd rename to man/issues_descriptions.Rd index 5343165b..722e8aa2 100644 --- a/man/check_descriptions.Rd +++ b/man/issues_descriptions.Rd @@ -1,18 +1,13 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check_descriptions.R -\name{check_descriptions} -\alias{check_descriptions} +% Please edit documentation in R/issues_descriptions.R +\name{issues_descriptions} +\alias{issues_descriptions} \title{Check package \code{DESCRIPTION} files.} \usage{ -check_descriptions(repo = "https://multiverse.r-multiverse.org", mock = NULL) +issues_descriptions(meta) } \arguments{ -\item{repo}{Character of length 1, URL of the repository -of R package candidates for production.} - -\item{mock}{For testing purposes only, -an optional pre-computed data frame with details about packages -for this type of check.} +\item{meta}{A data frame of package metadata returned by \code{\link[=meta_packages]{meta_packages()}}.} } \value{ A named list of information about packages which do not comply @@ -32,13 +27,13 @@ A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may depend on development versions of other packages and so are excluded from the production universe. } -\section{Package checks for production}{ +\section{Package issues}{ -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +Functions like \code{\link[=issues_versions]{issues_versions()}} and \code{\link[=issues_descriptions]{issues_descriptions()}} perform health checks for all packages in R-multiverse. Only packages that pass these checks go to the production repository at \url{https://production.r-multiverse.org}. For a complete list of checks, see -the \verb{check_*()} functions listed at +the \verb{issues_*()} functions listed at \url{https://r-multiverse.org/multiverse.internals/reference.html}. \code{\link[=record_versions]{record_versions()}} updates the version number history of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers @@ -46,15 +41,13 @@ together all the issues about R-multiverse packages. } \examples{ - issues <- check_descriptions( - # R-multiverse uses https://multiverse.r-multiverse.org - repo = "https://wlandau.r-universe.dev" - ) + meta <- meta_packages(repo = "https://wlandau.r-universe.dev") + issues <- issues_descriptions(meta = meta) str(issues) } \seealso{ -Other package checks for production: -\code{\link{check_checks}()}, -\code{\link{check_versions}()} +Other issues: +\code{\link{issues_checks}()}, +\code{\link{issues_versions}()} } -\concept{package checks for production} +\concept{issues} diff --git a/man/check_versions.Rd b/man/issues_versions.Rd similarity index 84% rename from man/check_versions.Rd rename to man/issues_versions.Rd index 2d1dc05d..c6d87964 100644 --- a/man/check_versions.Rd +++ b/man/issues_versions.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/check_versions.R -\name{check_versions} -\alias{check_versions} +% Please edit documentation in R/issues_versions.R +\name{issues_versions} +\alias{issues_versions} \title{Check package versions.} \usage{ -check_versions(versions) +issues_versions(versions) } \arguments{ \item{versions}{Character of length 1, file path to a JSON manifest @@ -30,13 +30,13 @@ in R-multiverse and reports any packages with issues. The current released version of a given package must be unique, and it must be greater than all the versions of all the previous package releases. } -\section{Package checks for production}{ +\section{Package issues}{ -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +Functions like \code{\link[=issues_versions]{issues_versions()}} and \code{\link[=issues_descriptions]{issues_descriptions()}} perform health checks for all packages in R-multiverse. Only packages that pass these checks go to the production repository at \url{https://production.r-multiverse.org}. For a complete list of checks, see -the \verb{check_*()} functions listed at +the \verb{issues_*()} functions listed at \url{https://r-multiverse.org/multiverse.internals/reference.html}. \code{\link[=record_versions]{record_versions()}} updates the version number history of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers @@ -80,12 +80,12 @@ together all the issues about R-multiverse packages. ) versions <- tempfile() writeLines(lines, versions) - out <- check_versions(versions) + out <- issues_versions(versions) str(out) } \seealso{ -Other package checks for production: -\code{\link{check_checks}()}, -\code{\link{check_descriptions}()} +Other issues: +\code{\link{issues_checks}()}, +\code{\link{issues_descriptions}()} } -\concept{package checks for production} +\concept{issues} diff --git a/man/meta_checks.Rd b/man/meta_checks.Rd new file mode 100644 index 00000000..eca16279 --- /dev/null +++ b/man/meta_checks.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/meta_checks.R +\name{meta_checks} +\alias{meta_checks} +\title{List metadata about R-universe package checks} +\usage{ +meta_checks(repo = "https://multiverse.r-multiverse.org") +} +\arguments{ +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} +} +\value{ +A data frame with one row per package and columns with +package check results. +} +\description{ +List package checks results reported by the +R-universe package API. +} +\examples{ +meta_checks(repo = "https://wlandau.r-universe.dev") +} +\concept{list} diff --git a/man/meta_packages.Rd b/man/meta_packages.Rd new file mode 100644 index 00000000..08de1090 --- /dev/null +++ b/man/meta_packages.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/meta_packages.R +\name{meta_packages} +\alias{meta_packages} +\title{List package metadata} +\usage{ +meta_packages(repo = "https://multiverse.r-multiverse.org") +} +\arguments{ +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} +} +\value{ +A data frame with one row per package and columns with package +metadata. +} +\description{ +List package metadata in an R universe. +} +\examples{ +meta_packages(repo = "https://wlandau.r-universe.dev") +} +\concept{meta} diff --git a/man/record_issues.Rd b/man/record_issues.Rd index f35f00a9..31d3d970 100644 --- a/man/record_issues.Rd +++ b/man/record_issues.Rd @@ -12,8 +12,8 @@ record_issues( ) } \arguments{ -\item{repo}{Character of length 1, URL of the repository -of R package candidates for production.} +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} \item{versions}{Character of length 1, file path to a JSON manifest tracking the history of released versions of packages. @@ -26,7 +26,7 @@ new package issues. Each call to \code{record_issues()} overwrites the contents of the repo.} \item{mock}{For testing purposes only, a named list of data frames -for the \code{mock} argument of each type of check.} +for inputs to various intermediate functions.} } \value{ \code{NULL} (invisibly). @@ -35,13 +35,13 @@ for the \code{mock} argument of each type of check.} Record R-multiverse package issues in package-specific JSON files. } -\section{Package checks for production}{ +\section{Package issues}{ -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +Functions like \code{\link[=issues_versions]{issues_versions()}} and \code{\link[=issues_descriptions]{issues_descriptions()}} perform health checks for all packages in R-multiverse. Only packages that pass these checks go to the production repository at \url{https://production.r-multiverse.org}. For a complete list of checks, see -the \verb{check_*()} functions listed at +the \verb{issues_*()} functions listed at \url{https://r-multiverse.org/multiverse.internals/reference.html}. \code{\link[=record_versions]{record_versions()}} updates the version number history of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers @@ -62,8 +62,7 @@ all package are resolved. } \examples{ - # R-multiverse uses https://multiverse.r-multiverse.org as the repo. - repo <- "https://wlandau.r-universe.dev" # just for testing and examples + repo <- "https://wlandau.r-universe.dev" output <- tempfile() versions <- tempfile() record_versions( diff --git a/man/record_versions.Rd b/man/record_versions.Rd index 608723ba..62d1235e 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -34,17 +34,17 @@ and their hashes. This function tracks a manifest containing the current version, the current hash, the highest version ever released, and the hash of the highest version ever released. -\code{\link[=check_versions]{check_versions()}} uses this information +\code{\link[=issues_versions]{issues_versions()}} uses this information to determine whether the package complies with best practices for version numbers. } -\section{Package checks for production}{ +\section{Package issues}{ -Functions like \code{\link[=check_versions]{check_versions()}} and \code{\link[=check_descriptions]{check_descriptions()}} +Functions like \code{\link[=issues_versions]{issues_versions()}} and \code{\link[=issues_descriptions]{issues_descriptions()}} perform health checks for all packages in R-multiverse. Only packages that pass these checks go to the production repository at \url{https://production.r-multiverse.org}. For a complete list of checks, see -the \verb{check_*()} functions listed at +the \verb{issues_*()} functions listed at \url{https://r-multiverse.org/multiverse.internals/reference.html}. \code{\link[=record_versions]{record_versions()}} updates the version number history of releases in R-multiverse, and \code{\link[=record_issues]{record_issues()}} gathers diff --git a/tests/testthat/helper-mock.R b/tests/testthat/helper-mock.R index 4f1742a2..062e116c 100644 --- a/tests/testthat/helper-mock.R +++ b/tests/testthat/helper-mock.R @@ -1,6 +1,6 @@ -mock_checks <- structure( +mock_meta_checks <- structure( list( - Package = c( + package = c( "tinytest", "tidytensor", "secretbase", "multiverse.internals", "SBC", "duckdb", "httpgd", "targetsketch", "stantargets", "zstdlite", "INLA", "audio.whisper", "tidypolars", @@ -102,20 +102,20 @@ mock_checks <- structure( row.names = c(NA, 19L) ) -mock_descriptions <- structure( +mock_meta_packages <- structure( list( - Package = c( + package = c( "SBC", "audio.vadwebrtc", "audio.whisper", "cmdstanr", "duckdb", "httpgd", "multitools", "multiverse.internals", "nanonext", "polars", "secretbase", "stantargets", "string2path", "targetsketch", "tidypolars", "tidytensor", "tinytest", "zstdlite" ), - Version = c( + version = c( "0.3.0.9000", "0.2", "0.4.1", "0.8.0", "0.10.1", "2.0.1", "0.1.0", "0.1.4", "1.0.0", "0.16.4", "0.5.0", "0.1.1", "0.1.6", "0.0.1", "0.7.0", "1.0.0", "1.4.1.1", "0.2.6" ), - Remotes = list( + remotes = list( NULL, NULL, "bnosac/audio.vadwebrtc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, c("hyunjimoon/SBC", "stan-dev/cmdstanr", ""), diff --git a/tests/testthat/test-check_descriptions.R b/tests/testthat/test-check_descriptions.R deleted file mode 100644 index f906e919..00000000 --- a/tests/testthat/test-check_descriptions.R +++ /dev/null @@ -1,17 +0,0 @@ -test_that("check_descriptions() mocked", { - issues <- check_descriptions(mock = mock_descriptions) - expected <- list( - audio.whisper = list(remotes = list("bnosac/audio.vadwebrtc")), - stantargets = list( - remotes = list(c("hyunjimoon/SBC", "stan-dev/cmdstanr")) - ), - tidypolars = list(remotes = list("markvanderloo/tinytest/pkg")) - ) - expect_equal(issues, expected) -}) - -test_that("check_descriptions() on a small repo", { - issues <- check_descriptions(repo = "https://wlandau.r-universe.dev") - expect_true(is.list(issues)) - expect_named(issues) -}) diff --git a/tests/testthat/test-check_checks.R b/tests/testthat/test-issues_checks.R similarity index 88% rename from tests/testthat/test-check_checks.R rename to tests/testthat/test-issues_checks.R index 6ff5467c..862a994d 100644 --- a/tests/testthat/test-check_checks.R +++ b/tests/testthat/test-issues_checks.R @@ -1,5 +1,5 @@ -test_that("check_checks() mocked", { - issues <- check_checks(mock = mock_checks) +test_that("issues_checks() mocked", { + issues <- issues_checks(meta = mock_meta_checks) url <- "https://github.com/r-universe/r-multiverse/actions/runs" expected <- list( httpgd = list( @@ -45,8 +45,9 @@ test_that("check_checks() mocked", { expect_equal(issues[order(names(issues))], expected[order(names(expected))]) }) -test_that("check_checks() on a small repo", { - issues <- check_checks(repo = "https://wlandau.r-universe.dev") +test_that("issues_checks() on a small repo", { + meta <- meta_checks(repo = "https://wlandau.r-universe.dev") + issues <- issues_checks(meta = meta) expect_true(is.list(issues)) expect_named(issues) }) diff --git a/tests/testthat/test-issues_descriptions.R b/tests/testthat/test-issues_descriptions.R new file mode 100644 index 00000000..706f9de0 --- /dev/null +++ b/tests/testthat/test-issues_descriptions.R @@ -0,0 +1,18 @@ +test_that("issues_descriptions() mocked", { + issues <- issues_descriptions(meta = mock_meta_packages) + expected <- list( + audio.whisper = list(remotes = "bnosac/audio.vadwebrtc"), + stantargets = list( + remotes = c("hyunjimoon/SBC", "stan-dev/cmdstanr") + ), + tidypolars = list(remotes = "markvanderloo/tinytest/pkg") + ) + expect_equal(issues, expected) +}) + +test_that("issues_descriptions() on a small repo", { + meta <- meta_packages(repo = "https://wlandau.r-universe.dev") + issues <- issues_descriptions(meta = meta) + expect_true(is.list(issues)) + expect_named(issues) +}) diff --git a/tests/testthat/test-check_versions.R b/tests/testthat/test-issues_versions.R similarity index 89% rename from tests/testthat/test-check_versions.R rename to tests/testthat/test-issues_versions.R index 6aa29c82..12816c84 100644 --- a/tests/testthat/test-check_versions.R +++ b/tests/testthat/test-issues_versions.R @@ -1,4 +1,4 @@ -test_that("check_versions() mocked", { +test_that("issues_versions() mocked", { # Temporary files used in the mock test. versions <- tempfile() # First update to the manifest. @@ -13,12 +13,12 @@ test_that("check_versions() mocked", { hash_current = rep("hash_1.0.0", 4L) ) record_versions(versions = versions, current = contents) - expect_equal(unname(check_versions(versions)), list()) + expect_equal(unname(issues_versions(versions)), list()) # Update the manifest after no changes to packages or versions. suppressMessages( record_versions(versions = versions, current = contents) ) - expect_equal(unname(check_versions(versions)), list()) + expect_equal(unname(issues_versions(versions)), list()) # Update the packages in all the ways indicated above. index <- contents$package == "version_decremented" contents$version_current[index] <- "0.0.1" @@ -34,7 +34,7 @@ test_that("check_versions() mocked", { versions = versions, current = contents ) - out <- check_versions(versions) + out <- issues_versions(versions) expect_equal( out, list( diff --git a/tests/testthat/test-meta_checks.R b/tests/testthat/test-meta_checks.R new file mode 100644 index 00000000..5720e153 --- /dev/null +++ b/tests/testthat/test-meta_checks.R @@ -0,0 +1,14 @@ +test_that("meta_checks()", { + out <- meta_checks(repo = "https://wlandau.r-universe.dev") + expect_true(is.data.frame(out)) + expect_gt(nrow(out), 1L) + fields <- c( + "_status", + "_winbinary", + "_macbinary", + "_wasmbinary", + "_linuxdevel", + "_buildurl" + ) + expect_true(all(fields %in% colnames(out))) +}) diff --git a/tests/testthat/test-meta_packages.R b/tests/testthat/test-meta_packages.R new file mode 100644 index 00000000..712844f5 --- /dev/null +++ b/tests/testthat/test-meta_packages.R @@ -0,0 +1,11 @@ +test_that("meta_packages()", { + out <- meta_packages(repo = "https://wlandau.r-universe.dev") + expect_true(is.data.frame(out)) + expect_gt(nrow(out), 1L) + fields <- c( + "package", + "version", + "remotesha" + ) + expect_true(all(fields %in% colnames(out))) +}) diff --git a/tests/testthat/test-record_issues.R b/tests/testthat/test-record_issues.R index ad97cd4d..ff2db97f 100644 --- a/tests/testthat/test-record_issues.R +++ b/tests/testthat/test-record_issues.R @@ -3,8 +3,8 @@ test_that("record_issues() mocked", { record_issues( versions = mock_versions(), mock = list( - checks = mock_checks, - descriptions = mock_descriptions, + checks = mock_meta_checks, + packages = mock_meta_packages, today = "2024-01-01" ), output = output @@ -57,7 +57,7 @@ test_that("record_issues() mocked", { "_buildurl" = file.path(runs, "8998732490") ), descriptions = list( - remotes = matrix(c("hyunjimoon/SBC", "stan-dev/cmdstanr"), nrow = 1) + remotes = c("hyunjimoon/SBC", "stan-dev/cmdstanr") ), date = "2024-01-01" ) @@ -99,8 +99,8 @@ test_that("record_issues() date works", { record_issues( versions = mock_versions(), mock = list( - checks = mock_checks, - descriptions = mock_descriptions, + checks = mock_meta_checks, + packages = mock_meta_packages, today = "2024-01-01" ), output = output @@ -108,8 +108,8 @@ test_that("record_issues() date works", { record_issues( versions = mock_versions(), mock = list( - checks = mock_checks, - descriptions = mock_descriptions + checks = mock_meta_checks, + packages = mock_meta_packages ), output = output ) @@ -136,8 +136,8 @@ test_that("record_issues() date works", { record_issues( versions = mock_versions(), mock = list( - checks = mock_checks, - descriptions = mock_descriptions + checks = mock_meta_checks, + packages = mock_meta_packages ), output = output ) From 189e9e2dae364c875280fe7f8472a57d6817f262 Mon Sep 17 00:00:00 2001 From: wlandau Date: Fri, 24 May 2024 10:46:24 -0400 Subject: [PATCH 15/17] Add file --- R/issues_checks.R | 3 ++- R/issues_descriptions.R | 20 +++++++++----------- man/issues_checks.Rd | 3 ++- man/issues_descriptions.Rd | 18 ++++++++---------- tests/testthat/test-issues_descriptions.R | 1 - 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/R/issues_checks.R b/R/issues_checks.R index 03fbc6db..d753a3f3 100644 --- a/R/issues_checks.R +++ b/R/issues_checks.R @@ -2,7 +2,8 @@ #' @export #' @family issues #' @description Check R-universe package check results. -#' @details [issues_checks()] function scrapes the R-universe check API +#' @details [issues_checks()] reads output from +#' the R-universe check API #' to scan all R-multiverse packages for issues that may have #' happened during building and testing. #' @inheritSection record_issues Package issues diff --git a/R/issues_descriptions.R b/R/issues_descriptions.R index b77c0e0f..fff9eadd 100644 --- a/R/issues_descriptions.R +++ b/R/issues_descriptions.R @@ -1,20 +1,18 @@ -#' @title Check package `DESCRIPTION` files. +#' @title Report `DESCRIPTION` file issues. #' @export #' @family issues -#' @description Check the `DESCRIPTION` files of packages for specific -#' issues. -#' @details This function scrapes the `src/contrib/PACKAGES.json` file -#' of the universe to check the data in the `DESCRIPTION` files of packages -#' for compliance. Right now, the only field checked is `Remotes:`. -#' A packages with a `Remotes:` field in the `DESCRIPTION` file may -#' depend on development versions of other packages and so are -#' excluded from the production universe. +#' @description Report issues with the `DESCRIPTION` files of packages. +#' @details [issues_descriptions()] scans downloaded metadata from the +#' `PACKAGES.json` file of an R universe and reports issues with a +#' package's description file, such as the presence of a +#' `"Remotes"` field. #' @inheritSection record_issues Package issues #' @return A named list of information about packages which do not comply #' with `DESCRPTION` checks. Each name is a package name, #' and each element contains specific information about #' non-compliance. -#' @param meta A data frame of package metadata returned by [meta_packages()]. +#' @param meta A data frame with R-universe package check results +#' returned by [meta_checks()]. #' @examples #' meta <- meta_packages(repo = "https://wlandau.r-universe.dev") #' issues <- issues_descriptions(meta = meta) @@ -27,7 +25,7 @@ issues_descriptions <- function(meta) { } issues_descriptions_remotes <- function(meta) { - meta$remotes <- meta$remotes %|||% replicate(nrow(meta), NULL) + meta[["remotes"]] <- meta[["remotes"]] %|||% replicate(nrow(meta), NULL) meta$remotes <- lapply(meta$remotes, function(x) x[nzchar(x)]) meta[vapply(meta$remotes, length, integer(1L)) > 0L, ] } diff --git a/man/issues_checks.Rd b/man/issues_checks.Rd index 560502cc..8197040e 100644 --- a/man/issues_checks.Rd +++ b/man/issues_checks.Rd @@ -20,7 +20,8 @@ non-compliance. Check R-universe package check results. } \details{ -\code{\link[=issues_checks]{issues_checks()}} function scrapes the R-universe check API +\code{\link[=issues_checks]{issues_checks()}} reads output from +the R-universe check API to scan all R-multiverse packages for issues that may have happened during building and testing. } diff --git a/man/issues_descriptions.Rd b/man/issues_descriptions.Rd index 722e8aa2..3441404b 100644 --- a/man/issues_descriptions.Rd +++ b/man/issues_descriptions.Rd @@ -2,12 +2,13 @@ % Please edit documentation in R/issues_descriptions.R \name{issues_descriptions} \alias{issues_descriptions} -\title{Check package \code{DESCRIPTION} files.} +\title{Report \code{DESCRIPTION} file issues.} \usage{ issues_descriptions(meta) } \arguments{ -\item{meta}{A data frame of package metadata returned by \code{\link[=meta_packages]{meta_packages()}}.} +\item{meta}{A data frame with R-universe package check results +returned by \code{\link[=meta_checks]{meta_checks()}}.} } \value{ A named list of information about packages which do not comply @@ -16,16 +17,13 @@ and each element contains specific information about non-compliance. } \description{ -Check the \code{DESCRIPTION} files of packages for specific -issues. +Report issues with the \code{DESCRIPTION} files of packages. } \details{ -This function scrapes the \code{src/contrib/PACKAGES.json} file -of the universe to check the data in the \code{DESCRIPTION} files of packages -for compliance. Right now, the only field checked is \verb{Remotes:}. -A packages with a \verb{Remotes:} field in the \code{DESCRIPTION} file may -depend on development versions of other packages and so are -excluded from the production universe. +\code{\link[=issues_descriptions]{issues_descriptions()}} scans downloaded metadata from the +\code{PACKAGES.json} file of an R universe and reports issues with a +package's description file, such as the presence of a +\code{"Remotes"} field. } \section{Package issues}{ diff --git a/tests/testthat/test-issues_descriptions.R b/tests/testthat/test-issues_descriptions.R index 706f9de0..1ccd4a23 100644 --- a/tests/testthat/test-issues_descriptions.R +++ b/tests/testthat/test-issues_descriptions.R @@ -14,5 +14,4 @@ test_that("issues_descriptions() on a small repo", { meta <- meta_packages(repo = "https://wlandau.r-universe.dev") issues <- issues_descriptions(meta = meta) expect_true(is.list(issues)) - expect_named(issues) }) From 9ae0d60a28f78659b345a70868026441203d14e1 Mon Sep 17 00:00:00 2001 From: wlandau Date: Thu, 6 Jun 2024 13:54:38 -0400 Subject: [PATCH 16/17] operators --- R/issues_descriptions.R | 2 +- R/record_issues.R | 10 +++++----- R/record_versions.R | 2 +- R/review_pull_request.R | 4 ++-- R/utils_logic.R | 15 --------------- man/get_current_versions.Rd | 3 ++- man/record_versions.Rd | 3 ++- man/review_pull_request.Rd | 5 +++-- man/review_pull_requests.Rd | 5 +++-- tests/testthat/test-issues_checks.R | 1 - tests/testthat/test-utils_logic.R | 11 ----------- 11 files changed, 19 insertions(+), 42 deletions(-) delete mode 100644 R/utils_logic.R delete mode 100644 tests/testthat/test-utils_logic.R diff --git a/R/issues_descriptions.R b/R/issues_descriptions.R index fff9eadd..950bf918 100644 --- a/R/issues_descriptions.R +++ b/R/issues_descriptions.R @@ -25,7 +25,7 @@ issues_descriptions <- function(meta) { } issues_descriptions_remotes <- function(meta) { - meta[["remotes"]] <- meta[["remotes"]] %|||% replicate(nrow(meta), NULL) + meta[["remotes"]] <- meta[["remotes"]] %||% replicate(nrow(meta), NULL) meta$remotes <- lapply(meta$remotes, function(x) x[nzchar(x)]) meta[vapply(meta$remotes, length, integer(1L)) > 0L, ] } diff --git a/R/record_issues.R b/R/record_issues.R index 3a2ca96a..be17eb91 100644 --- a/R/record_issues.R +++ b/R/record_issues.R @@ -24,9 +24,9 @@ #' an issue was first noticed. It automatically resets the next time #' all package are resolved. #' @return `NULL` (invisibly). -#' @inheritParams meta_checks #' @inheritParams issues_checks #' @inheritParams issues_versions +#' @inheritParams meta_checks #' @param output Character of length 1, file path to the folder to record #' new package issues. Each call to `record_issues()` overwrites the #' contents of the repo. @@ -60,9 +60,9 @@ record_issues <- function( output = "issues", mock = NULL ) { - today <- mock$today %|||% format(Sys.Date(), fmt = "yyyy-mm-dd") - checks <- mock$checks %|||% meta_checks(repo = repo) - packages <- mock$packages %|||% meta_packages(repo = repo) + today <- mock$today %||% format(Sys.Date(), fmt = "yyyy-mm-dd") + checks <- mock$checks %||% meta_checks(repo = repo) + packages <- mock$packages %||% meta_packages(repo = repo) issues <- list() |> add_issues(issues_checks(meta = checks), "checks") |> add_issues(issues_descriptions(meta = packages), "descriptions") |> @@ -107,7 +107,7 @@ overwrite_package_issues <- function( dates ) { path <- file.path(output, package) - issues[[package]]$date <- dates[[package]] %|||% today + issues[[package]]$date <- dates[[package]] %||% today jsonlite::write_json( x = issues[[package]], path = file.path(output, package), diff --git a/R/record_versions.R b/R/record_versions.R index 1504846f..1b821861 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -12,12 +12,12 @@ #' @inheritSection record_issues Package issues #' @return `NULL` (invisibly). Writes a package version manifest #' and a manifest of version issues as JSON files. +#' @inheritParams meta_checks #' @param versions Character of length 1, file path to a JSON manifest #' tracking the history of released versions of packages. #' The official versions file for R-multiverse is maintained and #' updated periodically at #' . -#' @param repo Character string of package repositories to track. #' @param current A data frame of current versions and hashes of packages #' in `repo`. This argument is exposed for testing only. #' @examples diff --git a/R/review_pull_request.R b/R/review_pull_request.R index 5188e704..bdbc003c 100644 --- a/R/review_pull_request.R +++ b/R/review_pull_request.R @@ -10,8 +10,8 @@ #' 4. Add a file in a forbidden place (close). #' 5. Add a custom JSON file which can be parsed (manual review). #' @return `NULL` (invisibly). -#' @param owner Character of length 1, name of the universe repository owner. -#' @param repo Character of length 1, name of the universe repository. +#' @inheritParams meta_checks +#' @param owner Character of length 1, name of the package repository owner. #' @param number Positive integer of length 1, index of the pull request #' in the repo. review_pull_request <- function( diff --git a/R/utils_logic.R b/R/utils_logic.R deleted file mode 100644 index b8794e2f..00000000 --- a/R/utils_logic.R +++ /dev/null @@ -1,15 +0,0 @@ -`%||%` <- function(x, y) { - if (length(x) > 0L) { - x - } else { - y - } -} - -`%|||%` <- function(x, y) { - if (is.null(x)) { - y - } else { - x - } -} diff --git a/man/get_current_versions.Rd b/man/get_current_versions.Rd index 2821199b..cdba07ca 100644 --- a/man/get_current_versions.Rd +++ b/man/get_current_versions.Rd @@ -7,7 +7,8 @@ get_current_versions(repo = "https://multiverse.r-multiverse.org") } \arguments{ -\item{repo}{Character string of package repositories to track.} +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} } \value{ A data frame of packages with their current versions and hashes. diff --git a/man/record_versions.Rd b/man/record_versions.Rd index 62d1235e..2648fa03 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -17,7 +17,8 @@ The official versions file for R-multiverse is maintained and updated periodically at \url{https://github.com/r-multiverse/checks/blob/main/versions.json}.} -\item{repo}{Character string of package repositories to track.} +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} \item{current}{A data frame of current versions and hashes of packages in \code{repo}. This argument is exposed for testing only.} diff --git a/man/review_pull_request.Rd b/man/review_pull_request.Rd index 59fca487..036a8bf6 100644 --- a/man/review_pull_request.Rd +++ b/man/review_pull_request.Rd @@ -7,9 +7,10 @@ review_pull_request(owner = "r-multiverse", repo = "contributions", number) } \arguments{ -\item{owner}{Character of length 1, name of the universe repository owner.} +\item{owner}{Character of length 1, name of the package repository owner.} -\item{repo}{Character of length 1, name of the universe repository.} +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} \item{number}{Positive integer of length 1, index of the pull request in the repo.} diff --git a/man/review_pull_requests.Rd b/man/review_pull_requests.Rd index f4bde691..34996425 100644 --- a/man/review_pull_requests.Rd +++ b/man/review_pull_requests.Rd @@ -7,9 +7,10 @@ review_pull_requests(owner = "r-multiverse", repo = "contributions") } \arguments{ -\item{owner}{Character of length 1, name of the universe repository owner.} +\item{owner}{Character of length 1, name of the package repository owner.} -\item{repo}{Character of length 1, name of the universe repository.} +\item{repo}{Character of length 1, URL of the package repository. +R-multiverse uses \code{"https://multiverse.r-multiverse.org"}.} } \value{ \code{NULL} (invisibly). diff --git a/tests/testthat/test-issues_checks.R b/tests/testthat/test-issues_checks.R index 862a994d..5babb1ee 100644 --- a/tests/testthat/test-issues_checks.R +++ b/tests/testthat/test-issues_checks.R @@ -49,5 +49,4 @@ test_that("issues_checks() on a small repo", { meta <- meta_checks(repo = "https://wlandau.r-universe.dev") issues <- issues_checks(meta = meta) expect_true(is.list(issues)) - expect_named(issues) }) diff --git a/tests/testthat/test-utils_logic.R b/tests/testthat/test-utils_logic.R deleted file mode 100644 index efc9611a..00000000 --- a/tests/testthat/test-utils_logic.R +++ /dev/null @@ -1,11 +0,0 @@ -test_that("%||%", { - expect_equal("a" %||% "b", "a") - expect_equal(list() %||% "b", "b") - expect_equal(NULL %||% "b", "b") -}) - -test_that("%|||%", { - expect_equal("a" %|||% "b", "a") - expect_equal(list() %|||% "b", list()) - expect_equal(NULL %|||% "b", "b") -}) From 8f0587cb94e8e36aa97eb8a9c668620160fbed69 Mon Sep 17 00:00:00 2001 From: wlandau Date: Thu, 6 Jun 2024 14:34:58 -0400 Subject: [PATCH 17/17] suppress oldrel --- .github/workflows/check.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 95234b6e..6f8f4b86 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -16,7 +16,6 @@ jobs: - {os: windows-latest, r: 'release'} - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} - - {os: ubuntu-latest, r: 'oldrel-1'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}