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

3.4 KiB

Task A7: Thread patches through the public build API

Files:

  • Modify: R/build_binaries.R (build_binary_package, execute_package_builds, build_single_tag, handle_system_dependencies)
  • Create: man-roxygen/param-patches.R
  • Test: tests/testthat/test-patches.R

Interfaces:

  • Produces: build_binary_package(..., patches = NULL) and the internal chain each carry patches down to install_pkg_sys_deps(). handle_system_dependencies(..., patches = NULL) passes patches and arch through.

  • Step 1: Write the failing test

test_that("handle_system_dependencies forwards patches and arch", {
  captured <- list()
  local_mocked_bindings(
    install_pkg_sys_deps = function(package_name, tag, local_clone_dir_single,
                                    platform, patches = NULL, arch = NULL) {
      captured <<- list(patches = patches, arch = arch)
      invisible(TRUE)
    }
  )
  handle_system_dependencies(
    "RcppParallel", "5.1.11-2", "ubuntu-2604", tempfile(), "amd64",
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    patches = "local/patches"
  )
  expect_identical(captured$patches, "local/patches")
  expect_identical(captured$arch, "amd64")
})
  • Step 2: Run test to verify it fails

Run: Rscript -e 'devtools::load_all("."); testthat::test_file("tests/testthat/test-patches.R")' Expected: FAIL — handle_system_dependencies has no patches argument.

  • Step 3: Create the roxygen template
# man-roxygen/param-patches.R
#' @param patches Optional path to a patch registry directory containing a
#'   `registry.json` (and any referenced diff files). When set, matching
#'   packages are pre-built as patched binaries and served to `pak` during
#'   dependency installation. Defaults to `NULL` (no patching).
  • Step 4: Edit the four functions in R/build_binaries.R

In build_single_tag()'s call to handle_system_dependencies(...), add patches = patches as the final argument, and add patches = NULL to build_single_tag's own signature plus #' @template param-patches to its roxygen block.

Change handle_system_dependencies signature to end with metadata_db_sslmode, then add patches = NULL, and change its inner install_pkg_sys_deps(...) call from:

      install_pkg_sys_deps(
        package_name,
        tag,
        local_clone_dir_single,
        platform
      )

to:

      install_pkg_sys_deps(
        package_name,
        tag,
        local_clone_dir_single,
        platform,
        patches = patches,
        arch = arch
      )

In execute_package_builds(), add patches = NULL to the signature and pass patches = patches into its build_single_tag(...) call inside worker_function.

In build_binary_package(), add patches = NULL to the signature (after s3_package_cache), add #' @template param-patches to its roxygen, and pass patches = patches into the execute_package_builds(...) call.

  • Step 5: Document, test, and run package check

Run:

Rscript -e 'devtools::document()'
Rscript -e 'devtools::load_all("."); testthat::test_file("tests/testthat/test-patches.R")'

Expected: PASS for the new test; man/build_binary_package.Rd etc. regenerated.

  • Step 6: Commit
git add R/build_binaries.R man-roxygen/param-patches.R man NAMESPACE tests/testthat/test-patches.R
git commit -m "feat(patches): thread patches argument through build_binary_package"