142 lines
3.9 KiB
Markdown
142 lines
3.9 KiB
Markdown
# Task A6 Report: Wire patched repo into the pak install path
|
|
|
|
## Status: COMPLETE
|
|
|
|
## TDD Evidence
|
|
|
|
### RED (failing test)
|
|
Added the new test to `tests/testthat/test-patches.R` (before the `prepare_patched_repo serves a cached binary` test).
|
|
Run output:
|
|
```
|
|
ERROR: 'test-patches.R:184:3' ---------------------
|
|
Error in `run_pak_install_with_mutex(tempfile(), list(), patched_repo = "/tmp/patched")`: unused argument (patched_repo = "/tmp/patched")
|
|
[ FAIL 1 | WARN 0 | SKIP 0 | PASS 35 ]
|
|
```
|
|
|
|
### GREEN (all pass)
|
|
After applying the two file edits:
|
|
```
|
|
[ FAIL 0 | WARN 0 | SKIP 0 | PASS 36 ]
|
|
```
|
|
|
|
## Commit
|
|
|
|
SHA: `e2c74c9`
|
|
Subject: `feat(patches): serve patched binaries to pak during dep install`
|
|
Branch: `feat/package-patching`
|
|
Files changed: 3 (60 insertions, 8 deletions)
|
|
|
|
## Diff Hunks Applied
|
|
|
|
### `R/install_helpers.R` — signature expansion + repos-prepend wrapper
|
|
|
|
```diff
|
|
-run_pak_install_with_mutex <- function(local_clone_dir_single, env_vars) {
|
|
+run_pak_install_with_mutex <- function(
|
|
+ local_clone_dir_single,
|
|
+ env_vars,
|
|
+ patched_repo = NULL
|
|
+) {
|
|
```
|
|
|
|
```diff
|
|
- retry_with_backoff(function() {
|
|
- withr::with_envvar(env_vars, {
|
|
- # Default to non-verbose (suppressed messages)
|
|
- suppressMessages(pak::local_install_deps(sprintf(
|
|
- "%s",
|
|
- local_clone_dir_single
|
|
- )))
|
|
- })
|
|
- })
|
|
+ retry_with_backoff(function() {
|
|
+ withr::with_envvar(env_vars, {
|
|
+ repos <- getOption("repos")
|
|
+ if (!is.null(patched_repo)) {
|
|
+ repos <- c(
|
|
+ patched = sprintf("file://%s", patched_repo),
|
|
+ repos
|
|
+ )
|
|
+ }
|
|
+ withr::with_options(list(repos = repos), {
|
|
+ # Default to non-verbose (suppressed messages)
|
|
+ suppressMessages(pak::local_install_deps(sprintf(
|
|
+ "%s",
|
|
+ local_clone_dir_single
|
|
+ )))
|
|
+ })
|
|
+ })
|
|
+ })
|
|
```
|
|
|
|
### `R/install-deps.R` — signature expansion + patched_repo block
|
|
|
|
```diff
|
|
install_pkg_sys_deps <- function(
|
|
package_name,
|
|
tag,
|
|
local_clone_dir,
|
|
platform = platform,
|
|
- aggressive_cleanup = FALSE
|
|
+ aggressive_cleanup = FALSE,
|
|
+ patches = NULL,
|
|
+ arch = NULL
|
|
) {
|
|
```
|
|
|
|
```diff
|
|
+ # Build a local repo of patched binaries (if any apply) and serve it to pak.
|
|
+ r_minor <- paste(
|
|
+ R.version$major,
|
|
+ strsplit(R.version$minor, ".", fixed = TRUE)[[1L]][1L],
|
|
+ sep = "."
|
|
+ )
|
|
+ patched_repo <- tryCatch(
|
|
+ prepare_patched_repo(patches, platform, arch, r_minor),
|
|
+ error = function(e) {
|
|
+ log_warn(sprintf("Patch preparation failed: %s", conditionMessage(e)))
|
|
+ NULL
|
|
+ }
|
|
+ )
|
|
+
|
|
# Run installation with mutex protection
|
|
run_pak_install_with_mutex(
|
|
local_clone_dir_single,
|
|
- env_vars
|
|
+ env_vars,
|
|
+ patched_repo = patched_repo
|
|
)
|
|
```
|
|
|
|
### `tests/testthat/test-patches.R` — new test appended before the cached-binary test
|
|
|
|
```r
|
|
test_that("run_pak_install_with_mutex prepends the patched repo to repos", {
|
|
seen <- NULL
|
|
local_mocked_bindings(
|
|
acquire_pak_mutex = function(...) tempfile(),
|
|
release_pak_mutex = function(...) invisible(NULL),
|
|
retry_with_backoff = function(func, ...) func()
|
|
)
|
|
local_mocked_bindings(
|
|
local_install_deps = function(...) {
|
|
seen <<- getOption("repos")
|
|
invisible(TRUE)
|
|
},
|
|
.package = "pak"
|
|
)
|
|
|
|
run_pak_install_with_mutex(
|
|
tempfile(), list(), patched_repo = "/tmp/patched"
|
|
)
|
|
|
|
expect_true(any(grepl("file:///tmp/patched", seen)))
|
|
})
|
|
```
|
|
|
|
## Concerns
|
|
|
|
None.
|
|
The existing brace-escaping patterns in the error handler of `run_pak_install_with_mutex` were left untouched.
|
|
No refactoring was done beyond the specified additions.
|
|
`prepare_patched_repo` errors are caught and logged via `log_warn` with `NULL` fallback, so a missing/empty patch registry causes no disruption to existing install flows.
|