### Task A2: Platform matching and version-constraint satisfaction **Files:** - Modify: `R/patches.R` - Test: `tests/testthat/test-patches.R` **Interfaces:** - Consumes: normalized entries from Task A1. - Produces: `build_platform_tokens(platform, arch)` → character vector; `entry_matches_platform(entry, tokens)` → logical; `match_patch_entries(registry, platform, arch)` → filtered list; `version_satisfies(version, constraint)` → logical (constraint forms: `"*"` handled by caller, `"x.y.z"` exact, `">=x"`, `"<=x"`, `">x"`, `"=5.1.0")) expect_false(version_satisfies("5.0.0", ">=5.1.0")) expect_true(version_satisfies("5.1.11-2", "<=5.1.11-2")) expect_false(version_satisfies("5.1.12", "<=5.1.11-2")) }) ``` - [ ] **Step 2: Run test to verify it fails** Run: `Rscript -e 'devtools::load_all("."); testthat::test_file("tests/testthat/test-patches.R")'` Expected: FAIL with "could not find function build_platform_tokens". - [ ] **Step 3: Write minimal implementation (append to `R/patches.R`)** ```r #' Build platform tokens for patch matching #' @keywords internal build_platform_tokens <- function(platform, arch) { family <- sub("-.*$", "", platform) unique(c(platform, family, arch)) } #' Does a patch entry apply to the current platform tokens? #' @keywords internal entry_matches_platform <- function(entry, tokens) { any(entry$platforms == "*") || length(intersect(entry$platforms, tokens)) > 0L } #' Filter registry entries applicable to the current build #' @keywords internal match_patch_entries <- function(registry, platform, arch) { if (length(registry) == 0L) { return(list()) } tokens <- build_platform_tokens(platform, arch) Filter(function(e) entry_matches_platform(e, tokens), registry) } #' Test whether a version satisfies a single constraint #' #' @param version A version string (CRAN style, may contain `-`). #' @param constraint One of `"x.y.z"`, `"==x"`, `">=x"`, `"<=x"`, `">x"`, `"=|<=|==|>|<)?\\s*(.+)$", constraint) )[[1L]] op <- parts[2L] target <- parts[3L] v <- package_version(version) t <- package_version(target) if (op == "" || op == "==") { return(v == t) } switch( op, ">=" = v >= t, "<=" = v <= t, ">" = v > t, "<" = v < t, FALSE ) } ``` - [ ] **Step 4: Run test to verify it passes** Run: `Rscript -e 'devtools::load_all("."); testthat::test_file("tests/testthat/test-patches.R")'` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add R/patches.R tests/testthat/test-patches.R git commit -m "feat(patches): platform matching and version-constraint checks" ``` ---