R/provenance.R

Defines functions mdsums

Documented in mdsums

# SPDX-License-Identifier: AGPL-3.0-or-later

#' SHA256 checksums of bundled rmoriedata files
#'
#' Computes the SHA256 digest of every file rmoriedata bundles in
#' \code{inst/extdata}, using the shared provenance layer
#' (\code{rmoriebricklayer::sha256file()}), and compares each with
#' the digest the signed manifest records for it (\code{in_manifest}).
#' For the full check, signature included, use [mdverify()]; this
#' function is the per-file record an analysis can pin and compare later.
#'
#' @return A data frame with one row per bundled file and columns
#'   \code{path} (relative to the extdata root, forward slashes, unique),
#'   \code{file} (the bare basename), \code{bytes}, \code{sha256}, and
#'   \code{in_manifest} (TRUE when the signed manifest lists the file with
#'   this digest; NA for the manifest's own files).
#'   Use \code{path} to locate a file; several basenames recur in more
#'   than one directory.
#' @examples
#' # One row per bundled file: name, size in bytes, SHA256 digest.
#' ck <- mdsums()
#' str(ck)
#' head(ck)
#'
#' # Total bundled payload and the largest few files.
#' sum(ck$bytes)
#' head(ck[order(-ck$bytes), c("file", "bytes")], 3)
#'
#' # Provenance workflow: pin the digest of a file you depend on, then
#' # assert it hasn't changed under you in a later session / reinstall.
#' if (nrow(ck)) {
#'   pinned <- ck$sha256[1]
#'   again <- mdsums()
#'   stopifnot(again$sha256[again$path == ck$path[1]] == pinned)
#' }
#' @export
mdsums <- function() {
  dir <- system.file("extdata", package = "rmoriedata")
  empty <- data.frame(
    path = character(), file = character(), bytes = numeric(),
    sha256 = character(), in_manifest = logical(), stringsAsFactors = FALSE
  )
  if (!nzchar(dir) || !dir.exists(dir)) {
    return(empty)
  }
  files <- list.files(dir, full.names = TRUE, recursive = TRUE)
  if (length(files) == 0L) {
    return(empty)
  }
  out <- data.frame(
    path = substring(files, nchar(dir) + 2L),
    file = basename(files),
    bytes = file.size(files),
    sha256 = vapply(files, .rmd_bl("sha256file"), character(1)),
    row.names = NULL,
    stringsAsFactors = FALSE
  )
  man <- tryCatch(.rmoriedata_manifest(), error = function(e) NULL)
  trust <- c("_checksums.csv", "_checksums.sig", "_signing_key.json")
  out$in_manifest <- if (is.null(man)) NA else
    ifelse(out$path %in% trust, NA,
           (out$sha256 == man$sha256[match(out$path, man$path)]) %in% TRUE)
  out
}

Try the rmoriedata package in your browser

Any scripts or data that you put into this service are public.

rmoriedata documentation built on Nov. 12, 2026, 9:06 a.m.