From 81bdb65cb50c3e5426b3a2b67a0e1ce5c9508991 Mon Sep 17 00:00:00 2001 From: wlandau Date: Tue, 5 Mar 2024 08:40:42 -0500 Subject: [PATCH] Add check_hash argument --- R/record_versions.R | 31 ++++++++-------- man/record_versions.Rd | 19 +++++----- tests/test-record_versions.R | 70 +++++++++++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 33 deletions(-) diff --git a/R/record_versions.R b/R/record_versions.R index fdeeaa9..ab19547 100644 --- a/R/record_versions.R +++ b/R/record_versions.R @@ -4,15 +4,9 @@ #' 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. Each time it runs, -#' it reads scrapes the package repository for the current releases, -#' reads the old manifest, and updates recorded highest version and hash -#' for all packages which incremented their version numbers. -#' After recording these incremented versions, the current version should -#' be the highest version, and the current and highest-version -#' hashes should agree. Packages -#' that fall out of alignment are recorded in a small JSON with only -#' the packages with version issues. +#' the hash of the highest version ever released. It uses this information +#' to determine whether the package complies with best +#' 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. @@ -21,11 +15,15 @@ #' @param repos Character string of package repositories to track. #' @param current A data frame of current versions and hashes of packages #' in `repos`. This argument is exposed for testing only. +#' @param check_hash Logical of length 1, check hashes when judging package +#' version compliance. This allows [record_versions()] to flag packages +#' that create new releases but keep the same version number. record_versions <- function( manifest = "versions.json", issues = "version_issues.json", repos = "https://r-releases.r-universe.dev", - current = r.releases.utils::get_current_versions(repos = repos) + current = r.releases.utils::get_current_versions(repos = repos), + check_hash = TRUE ) { if (!file.exists(manifest)) { jsonlite::write_json(x = current, path = manifest, pretty = TRUE) @@ -34,7 +32,8 @@ record_versions <- function( previous <- read_versions_previous(manifest = manifest) new <- update_version_manifest(current = current, previous = previous) jsonlite::write_json(x = new, path = manifest, pretty = TRUE) - new_issues <- new[!versions_aligned(manifest = new),, drop = FALSE] # nolint + aligned <- versions_aligned(manifest = new, check_hash = check_hash) + new_issues <- new[!aligned,, drop = FALSE] # nolint jsonlite::write_json(x = new_issues, path = issues, pretty = TRUE) invisible() } @@ -94,8 +93,10 @@ manifest_compare_versions <- function(manifest) { ) } -versions_aligned <- function(manifest) { - versions_agree <- manifest$version_current == manifest$version_highest - hashes_agree <- manifest$hash_current == manifest$hash_highest - versions_agree & hashes_agree +versions_aligned <- function(manifest, check_hash) { + aligned <- manifest$version_current == manifest$version_highest + if (check_hash) { + aligned <- aligned & (manifest$hash_current == manifest$hash_highest) + } + aligned } diff --git a/man/record_versions.Rd b/man/record_versions.Rd index 186af74..8eed436 100644 --- a/man/record_versions.Rd +++ b/man/record_versions.Rd @@ -8,7 +8,8 @@ record_versions( manifest = "versions.json", issues = "version_issues.json", repos = "https://r-releases.r-universe.dev", - current = r.releases.utils::get_current_versions(repos = repos) + current = r.releases.utils::get_current_versions(repos = repos), + check_hash = TRUE ) } \arguments{ @@ -21,6 +22,10 @@ which records packages with version issues.} \item{current}{A data frame of current versions and hashes of packages in \code{repos}. This argument is exposed for testing only.} + +\item{check_hash}{Logical of length 1, check hashes when judging package +version compliance. This allows \code{\link[=record_versions]{record_versions()}} to flag packages +that create new releases but keep the same version number.} } \value{ \code{NULL} (invisibly). Writes a package version manifest @@ -33,13 +38,7 @@ 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. Each time it runs, -it reads scrapes the package repository for the current releases, -reads the old manifest, and updates recorded highest version and hash -for all packages which incremented their version numbers. -After recording these incremented versions, the current version should -be the highest version, and the current and highest-version -hashes should agree. Packages -that fall out of alignment are recorded in a small JSON with only -the packages with version issues. +the hash of the highest version ever released. It uses this information +to determine whether the package complies with best +practices for version numbers. } diff --git a/tests/test-record_versions.R b/tests/test-record_versions.R index c74447e..c845392 100644 --- a/tests/test-record_versions.R +++ b/tests/test-record_versions.R @@ -95,10 +95,71 @@ 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)) { + r.releases.utils::record_versions( + manifest = manifest, + issues = issues, + current = contents + ) + written <- jsonlite::read_json(manifest) + expected <- list( + list( + 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" + ), + list( + 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" + ), + list( + 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" + ), + list( + 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" + ) + ) + stopifnot(identical(written, expected)) + stopifnot(file.exists(issues)) + written_issues <- jsonlite::read_json(issues) + expected_issues <- list( + list( + 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" + ), + list( + 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" + ) + ) + stopifnot(identical(written_issues, expected_issues)) +} + +# Same, but do not check the hash. r.releases.utils::record_versions( manifest = manifest, issues = issues, - current = contents + current = contents, + check_hash = FALSE ) written <- jsonlite::read_json(manifest) expected <- list( @@ -141,13 +202,6 @@ expected_issues <- list( hash_current = "hash_0.0.1", version_highest = "1.0.0", hash_highest = "hash_1.0.0" - ), - list( - 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" ) ) stopifnot(identical(written_issues, expected_issues))