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

3.8 KiB

Task A0: Proof of mechanism — pak installs a patched binary from a prepended file:// repo

This de-risks the core assumption before building anything on top: that pak installs a binary from a local file:// repo in preference to CRAN for an equal version, and does so without recompiling. If this fails, the contingency (documented in Step 4) is to serve patched source and rely on pkgcache build-caching — the rest of the plan changes only inside build_patched_binary().

Files:

  • Create: tools/verify-patch-mechanism.R

Interfaces:

  • Produces: a runnable script proving pak::pkg_install() resolves a local patched binary over CRAN. No package API.

  • Step 1: Write the verification script

# tools/verify-patch-mechanism.R
# Proves pak installs a patched binary from a prepended file:// repo instead of
# CRAN's, without recompiling. Run inside a Linux build-env container:
#   Rscript tools/verify-patch-mechanism.R
# Exits 0 on success, 1 on failure.

pkg <- "glue" # small, pure-R CRAN package
sentinel <- "PatchMechanismProof"

work <- tempfile("verify_")
repo <- file.path(work, "repo", "src", "contrib")
lib <- file.path(work, "lib")
dir.create(repo, recursive = TRUE)
dir.create(lib, recursive = TRUE)

# 1. Download CRAN source for the current version.
ap <- available.packages(repos = "https://cloud.r-project.org")
ver <- ap[pkg, "Version"]
src <- file.path(work, sprintf("%s_%s.tar.gz", pkg, ver))
download.file(
  sprintf("https://cloud.r-project.org/src/contrib/%s_%s.tar.gz", pkg, ver),
  src, mode = "wb"
)

# 2. Unpack, inject a sentinel field into DESCRIPTION, build a binary.
untar(src, exdir = work)
desc <- file.path(work, pkg, "DESCRIPTION")
writeLines(c(readLines(desc), sprintf("%s: yes", sentinel)), desc)
pkgbuild::build(
  file.path(work, pkg), binary = TRUE, vignettes = FALSE,
  dest_path = repo, quiet = TRUE
)
built <- list.files(repo, pattern = sprintf("^%s_.*\\.tar\\.gz$", pkg), full.names = TRUE)
file.rename(built[1L], file.path(repo, sprintf("%s_%s.tar.gz", pkg, ver)))
cranlike::add_PACKAGES(sprintf("%s_%s.tar.gz", pkg, ver), repo)

# 3. Install with the local repo prepended; assert our patched build won.
withr::with_options(
  list(repos = c(patched = sprintf("file://%s", dirname(dirname(repo))),
                 CRAN = "https://cloud.r-project.org")),
  pak::pkg_install(pkg, lib = lib, ask = FALSE, upgrade = FALSE)
)

installed_desc <- file.path(lib, pkg, "DESCRIPTION")
ok <- file.exists(installed_desc) &&
  any(grepl(sentinel, readLines(installed_desc)))

if (ok) {
  cat("PROOF PASSED: pak installed the patched local binary.\n")
  quit(status = 0L)
} else {
  cat("PROOF FAILED: pak did not install the patched local binary.\n")
  quit(status = 1L)
}
  • Step 2: Run the proof in a build-env container

Run (amd64 example; use any supported build-env image):

just build-single ubuntu 2604 amd64 4.5.0 glue 1.0.0 1 || true   # warms the env
docker run --rm -v "$PWD":/work -w /work reg.devxy.io/rpkgs/build-env-ubuntu:2604 \
  Rscript tools/verify-patch-mechanism.R

Expected: final line PROOF PASSED: pak installed the patched local binary. and exit status 0.

  • Step 3: Commit
git add tools/verify-patch-mechanism.R
git commit -m "test(patches): prove pak installs a patched binary from a local file:// repo"
  • Step 4: Record the outcome / contingency

If the proof PASSED, proceed to Task A1 unchanged. If it FAILED (pak recompiled or picked CRAN's), the mechanism switches to serving patched source: in Task A4 build_patched_binary() skips pkgbuild::build() and instead repackages the patched source tree with pkgbuild::build(binary = FALSE); everything else (registry, matching, cache, repo prepend) is unchanged because pak build-caches the compiled result via pkgcache. Note the chosen path in the commit message and continue.