build-cran-binaries/.superpowers/handoff/task-B2-brief.md

2.5 KiB

Task B2: Registry validator script

Files:

  • Create: local/validate-patches.R

Interfaces:

  • Consumes: local/patches/registry.json.

  • Produces: a script that exits non-zero on schema violations, missing patch files, or ambiguous overlapping entries.

  • Step 1: Write the validator

#!/usr/bin/env Rscript
# Validate local/patches/registry.json: schema, referenced patch files, and
# ambiguous overlaps. Exits 1 on any problem. Used by pre-commit and CI.

dir <- "local/patches"
registry_file <- file.path(dir, "registry.json")
if (!file.exists(registry_file)) {
  cat("No registry.json found; nothing to validate.\n")
  quit(status = 0L)
}

reg <- jsonlite::fromJSON(registry_file, simplifyVector = FALSE)
required <- c("package", "versions", "platforms", "reason")
errs <- character(0L)

for (i in seq_along(reg)) {
  e <- reg[[i]]
  missing <- setdiff(required, names(e))
  if (length(missing) > 0L) {
    errs <- c(errs, sprintf(
      "entry %d (%s): missing %s", i,
      if (is.null(e$package)) "?" else e$package, toString(missing)
    ))
  }
  if (!is.null(e$patch)) {
    p <- file.path(dir, e$patch)
    if (!file.exists(p)) {
      errs <- c(errs, sprintf("entry %d (%s): patch file '%s' missing",
                              i, e$package, p))
    }
  }
}

# Ambiguous overlap: two entries for the same package with identical platforms
# and versions.
keys <- vapply(reg, function(e) {
  sprintf("%s|%s|%s", e$package,
          paste(sort(as.character(unlist(e$platforms))), collapse = ","),
          e$versions)
}, character(1L))
dups <- keys[duplicated(keys)]
if (length(dups) > 0L) {
  errs <- c(errs, sprintf("ambiguous duplicate entries: %s", toString(unique(dups))))
}

if (length(errs) > 0L) {
  cat("Patch registry validation FAILED:\n")
  cat(paste0("  - ", errs, "\n"))
  quit(status = 1L)
}
cat(sprintf("Patch registry OK (%d entrie(s)).\n", length(reg)))
  • Step 2: Run it (expect success on the B1 registry)

Run: Rscript local/validate-patches.R Expected: Patch registry OK (1 entrie(s)). and exit 0.

  • Step 3: Run it against a broken registry (expect failure)

Run:

cp local/patches/registry.json /tmp/reg.bak
Rscript -e 'writeLines("[{\"package\":\"X\"}]", "local/patches/registry.json")'
Rscript local/validate-patches.R; echo "exit=$?"
cp /tmp/reg.bak local/patches/registry.json

Expected: prints validation FAILED with a missing-field message and exit=1.

  • Step 4: Commit
git add local/validate-patches.R
git commit -m "feat(patches): add registry validator script"