123 lines
3.8 KiB
Markdown
123 lines
3.8 KiB
Markdown
### 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"`, `"<x"`, `"==x"`).
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
```r
|
|
test_that("build_platform_tokens expands family and arch", {
|
|
expect_setequal(
|
|
build_platform_tokens("ubuntu-2604", "amd64"),
|
|
c("ubuntu-2604", "ubuntu", "amd64")
|
|
)
|
|
expect_setequal(
|
|
build_platform_tokens("alpine-324", "arm64"),
|
|
c("alpine-324", "alpine", "arm64")
|
|
)
|
|
})
|
|
|
|
test_that("match_patch_entries matches family, codename, arch, and wildcard", {
|
|
reg <- list(
|
|
list(package = "A", versions = "*", platforms = "alpine", reason = "r"),
|
|
list(package = "B", versions = "*", platforms = "ubuntu-2604", reason = "r"),
|
|
list(package = "C", versions = "*", platforms = "*", reason = "r"),
|
|
list(package = "D", versions = "*", platforms = "redhat", reason = "r")
|
|
)
|
|
got <- vapply(
|
|
match_patch_entries(reg, "ubuntu-2604", "amd64"),
|
|
function(e) e$package, character(1L)
|
|
)
|
|
expect_setequal(got, c("B", "C"))
|
|
})
|
|
|
|
test_that("version_satisfies handles operators and hyphenated versions", {
|
|
expect_true(version_satisfies("5.1.11-2", "5.1.11-2"))
|
|
expect_true(version_satisfies("5.1.11-2", "==5.1.11-2"))
|
|
expect_true(version_satisfies("5.1.12", ">=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"`, `"<x"`.
|
|
#' @keywords internal
|
|
version_satisfies <- function(version, constraint) {
|
|
constraint <- trimws(constraint)
|
|
parts <- regmatches(
|
|
constraint,
|
|
regexec("^(>=|<=|==|>|<)?\\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"
|
|
```
|
|
|
|
---
|
|
|