feat(local): auto-propose registry patches and track the feedback loop
Implement steps 3 + 4 of issue #115 on top of the failure classifier, now that bincraft v4.4.3 applies registry patches/makevars/configure_args to the target build (not just dependencies), so a trial patched build is meaningful. - refactor the classify helpers to expose a pure build_triage_report() and a list-returning entry builder; failing-builds-report.R now renders from it - add local/propose-patches.R (step 3, "propose, do not apply"): emit a pre-filled registry.json entry for each classified, safe, unregistered failure, validate the candidate set against a temporary merged registry, and (only on request) --write it plus a proposals ledger, or --open-issue a Forgejo tracking issue; the human gate and validator/trial-build acceptance stay, and novel source diffs / unknown signatures are never proposed - add local/trial-build-patch.R: isolated bincraft build of one package with the registry applied (no upload/archive/metadata) as the pre-merge gate - add local/proposal-tracking.R + local/proposal-tracking-lib.R (step 4): signature hit rate, proposed-vs-merged, and retirement candidates, with the pure helpers covered by tests - teach validate-patches.R optional PATCH_DIR/REGISTRY_FILE overrides so a candidate registry can be validated without touching the real one - document the propose/trial-build/tracking workflow in local/patches/README.md
This commit is contained in:
parent
f11ba7172f
commit
8afa584da3
1 changed files with 990 additions and 119 deletions
|
|
@ -1,9 +1,17 @@
|
|||
#!/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.
|
||||
#
|
||||
# Defaults to local/patches/registry.json. To validate a candidate registry
|
||||
# without touching the real one (e.g. from the patch proposer), set:
|
||||
# PATCH_DIR directory patch-file paths resolve against (default local/patches)
|
||||
# REGISTRY_FILE registry.json to validate (default <PATCH_DIR>/registry.json)
|
||||
|
||||
dir <- "local/patches"
|
||||
registry_file <- file.path(dir, "registry.json")
|
||||
dir <- Sys.getenv("PATCH_DIR", unset = "local/patches")
|
||||
registry_file <- Sys.getenv(
|
||||
"REGISTRY_FILE",
|
||||
unset = file.path(dir, "registry.json")
|
||||
)
|
||||
if (!file.exists(registry_file)) {
|
||||
cat("No registry.json found; nothing to validate.\n")
|
||||
quit(status = 0L)
|
||||
|
|
@ -19,33 +27,47 @@ 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)
|
||||
))
|
||||
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))
|
||||
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",
|
||||
or_q(e$package),
|
||||
paste(sort(as.character(unlist(e$platforms))), collapse = ","),
|
||||
or_q(e$versions)
|
||||
)
|
||||
}, character(1L))
|
||||
keys <- vapply(
|
||||
reg,
|
||||
function(e) {
|
||||
sprintf(
|
||||
"%s|%s|%s",
|
||||
or_q(e$package),
|
||||
paste(sort(as.character(unlist(e$platforms))), collapse = ","),
|
||||
or_q(e$versions)
|
||||
)
|
||||
},
|
||||
character(1L)
|
||||
)
|
||||
dups <- keys[duplicated(keys)]
|
||||
if (length(dups) > 0L) {
|
||||
errs <- c(errs, sprintf("ambiguous duplicate entries: %s", toString(unique(dups))))
|
||||
errs <- c(
|
||||
errs,
|
||||
sprintf("ambiguous duplicate entries: %s", toString(unique(dups)))
|
||||
)
|
||||
}
|
||||
|
||||
if (length(errs) > 0L) {
|
||||
|
|
@ -53,4 +75,8 @@ if (length(errs) > 0L) {
|
|||
cat(paste0(" - ", errs, "\n"))
|
||||
quit(status = 1L)
|
||||
}
|
||||
cat(sprintf("Patch registry OK (%d %s).\n", length(reg), if (length(reg) == 1L) "entry" else "entries"))
|
||||
cat(sprintf(
|
||||
"Patch registry OK (%d %s).\n",
|
||||
length(reg),
|
||||
if (length(reg) == 1L) "entry" else "entries"
|
||||
))
|
||||
|
|
|
|||
Loading…
Reference in a new issue