diff --git a/DESCRIPTION b/DESCRIPTION index b52ce12..a7efcd4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: r.releases.utils Title: Utilities for An R Universe of Package Releases Description: Utilities for an R universe of package releases. -Version: 0.0.7.9000 +Version: 0.0.8 License: MIT + file LICENSE URL: https://r-releases.github.io/r.releases.utils/, diff --git a/NAMESPACE b/NAMESPACE index d11de82..4f22f63 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,12 +4,14 @@ export(assert_cran_url) export(assert_package) export(assert_release_exists) export(build_universe) +export(record_versions) export(review_pull_request) export(review_pull_requests) export(try_message) importFrom(gh,gh) importFrom(jsonlite,parse_json) importFrom(jsonlite,read_json) +importFrom(jsonlite,write_json) importFrom(nanonext,ncurl) importFrom(nanonext,parse_url) importFrom(nanonext,status_code) diff --git a/NEWS.md b/NEWS.md index 0ff4ff0..8b9f519 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,8 @@ -# r.releases.utils 0.0.7.9000 (development) +# r.releases.utils 0.0.8 * Use R-releases and not `r-releases` to refer to the project. * Edit bot messages. +* Add `record_versions()`. # r.releases.utils 0.0.7 diff --git a/R/package.R b/R/package.R index f73f627..edd0f84 100644 --- a/R/package.R +++ b/R/package.R @@ -3,7 +3,7 @@ #' @name r.releases.utils-package #' @family help #' @importFrom gh gh -#' @importFrom jsonlite parse_json read_json +#' @importFrom jsonlite parse_json read_json write_json #' @importFrom nanonext ncurl parse_url status_code #' @importFrom pkgsearch cran_package #' @importFrom vctrs vec_rbind diff --git a/R/record_versions.R b/R/record_versions.R new file mode 100644 index 0000000..9cac95f --- /dev/null +++ b/R/record_versions.R @@ -0,0 +1,71 @@ +#' @title Record the manifest of package versions. +#' @export +#' @keywords internal +#' @description Record the manifest of versions of packages +#' and their MD5 hashes. +#' @details As well as their versions and MD5 hashes, this function +#' records the highest version ever recorded and the MD5 of that +#' version. This information helps check if a package complies with +#' best practices for version numbers: the version number should increment +#' on each new release. +#' @return `NULL` (invisibly). Writes a package manifest as a JSON file. +#' @param manifest Character of length 1, file path to the JSON manifest. +#' @param repos Character string of package repositories to track. +record_versions <- function( + manifest = "versions.json", + repos = "https://r-releases.r-universe.dev" +) { + current <- get_versions(repos = repos) + if (!file.exists(manifest)) { + jsonlite::write_json(x = current, path = manifest, pretty = TRUE) + return(invisible()) + } + previous <- read_previous(manifest = manifest) + new <- update_manifest(current = current, previous = previous) + jsonlite::write_json(x = new, path = manifest, pretty = TRUE) +} + +get_versions <- function(repos) { + out <- available.packages(repos = "https://r-releases.r-universe.dev") + out <- as.data.frame(out) + out <- out[, c("Package", "Version", "MD5sum")] + colnames(out) <- c("package", "version_current", "md5_current") + rownames(out) <- NULL + out +} + +read_previous <- function(manifest) { + out <- jsonlite::read_json(path = manifest) + out <- do.call(what = vctrs::vec_rbind, args = out) + for (field in colnames(out)) { + out[[field]] <- as.character(out[[field]]) + } + if (is.null(out$version_highest)) { + out$version_highest <- out$version_current + } + if (is.null(out$md5_highest)) { + out$md5_highest <- out$md5_current + } + out$version_current <- NULL + out$md5_current <- NULL + out +} + +update_manifest <- function(current, previous) { + new <- merge(x = current, y = previous, all = TRUE) + incremented <- apply( + X = new, + MARGIN = 1L, + FUN = function(row) { + print(.subset2(row, "version_current")) + print(.subset2(row, "version_highest")) + utils::compareVersion( + a = .subset2(row, "version_current"), + b = .subset2(row, "version_highest") + ) > 0.5 + } + ) + new$version_highest[incremented] <- new$version_current[incremented] + new$md5_highest[incremented] <- new$md5_current[incremented] + new +} diff --git a/man/record_versions.Rd b/man/record_versions.Rd new file mode 100644 index 0000000..179ac55 --- /dev/null +++ b/man/record_versions.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/record_versions.R +\name{record_versions} +\alias{record_versions} +\title{Record the manifest of package versions.} +\usage{ +record_versions( + manifest = "versions.json", + repos = "https://r-releases.r-universe.dev" +) +} +\arguments{ +\item{manifest}{Character of length 1, file path to the JSON manifest.} + +\item{repos}{Character string of package repositories to track.} +} +\value{ +\code{NULL} (invisibly). Writes a package manifest as a JSON file. +} +\description{ +Record the manifest of versions of packages +and their MD5 hashes. +} +\details{ +As well as their versions and MD5 hashes, this function +records the highest version ever recorded and the MD5 of that +version. This information helps check if a package complies with +best practices for version numbers: the version number should increment +on each new release. +} +\keyword{internal}