Skip to content

Commit 1c58a2a

Browse files
authored
Merge pull request #24 from r-multiverse/record-issues
Refactor the recording of package version/check issues
2 parents bd85d00 + a95d837 commit 1c58a2a

File tree

10 files changed

+218
-50
lines changed

10 files changed

+218
-50
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: multiverse.internals
22
Title: Internal Infrastructure for R-multiverse
33
Description: R-multiverse requires this internal internal infrastructure
44
package to automate contribution reviews and populate universes.
5-
Version: 0.1.3
5+
Version: 0.1.4
66
License: MIT + file LICENSE
77
URL: https://github.com/r-multiverse/multiverse.internals
88
BugReports: https://github.com/r-multiverse/multiverse.internals/issues

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export(assert_cran_url)
55
export(assert_package)
66
export(assert_release_exists)
77
export(get_current_versions)
8+
export(record_issues)
89
export(record_versions)
910
export(review_pull_request)
1011
export(review_pull_requests)
@@ -22,3 +23,4 @@ importFrom(utils,available.packages)
2223
importFrom(utils,compareVersion)
2324
importFrom(utils,contrib.url)
2425
importFrom(vctrs,vec_rbind)
26+
importFrom(vctrs,vec_slice)

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# multiverse.internals 0.1.4
2+
3+
* Do not write `version_issues.json` from `record_versions()`.
4+
* Record version issues in separate JSON files in a new `record_issues()` function. Going forward, this function will also write R-universe check results in those individual package-specific files.
5+
16
# multiverse.internals 0.1.3
27

38
* In `record_versions()`, left-join old versions into new versions to avoid spamming `versions.json` with an unbounded list of renamed or abandoned packages.

R/package.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
#' @importFrom nanonext ncurl parse_url status_code
88
#' @importFrom pkgsearch cran_package
99
#' @importFrom utils available.packages compareVersion contrib.url
10-
#' @importFrom vctrs vec_rbind
10+
#' @importFrom vctrs vec_rbind vec_slice
1111
NULL

R/record_issues.R

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#' @title Record package issues.
2+
#' @export
3+
#' @description Record package check and version issues in individual JSON
4+
#' files.
5+
#' @return `NULL` (invisibly).
6+
#' @param manifest Character of length 1, file path to a JSON manifest
7+
#' tracking release versions of packages.
8+
#' @param output Character of length 1, file path to the folder to record
9+
#' new package issues. Each call to `record_issues()` overwrites the
10+
#' contents of the repo.
11+
record_issues <- function(
12+
manifest = "versions.json",
13+
output = "issues"
14+
) {
15+
issues_version <- version_issues(manifest)
16+
issues <- issues_version # Will include check issues too later.
17+
overwrite_issues(issues, output)
18+
invisible()
19+
}
20+
21+
overwrite_issues <- function(issues, output) {
22+
unlink(output, recursive = TRUE)
23+
dir.create(output)
24+
for (index in seq_len(nrow(issues))) {
25+
row <- vctrs::vec_slice(x = issues, i = index)
26+
jsonlite::write_json(row, file.path(output, row$package))
27+
}
28+
}
29+
30+
version_issues <- function(manifest) {
31+
manifest <- jsonlite::read_json(path = manifest, simplifyVector = TRUE)
32+
aligned <- (manifest$version_current == manifest$version_highest) &
33+
(manifest$hash_current == manifest$hash_highest)
34+
aligned[is.na(aligned)] <- TRUE
35+
out <- manifest[!aligned,, drop = FALSE] # nolint
36+
if (nrow(out)) {
37+
out$version_okay <- FALSE
38+
}
39+
out
40+
}

R/record_versions.R

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010
#' @return `NULL` (invisibly). Writes a package version manifest
1111
#' and a manifest of version issues as JSON files.
1212
#' @param manifest Character of length 1, file path to the JSON manifest.
13-
#' @param issues Character of length 1, file path to a JSON file
14-
#' which records packages with version issues.
1513
#' @param repo Character string of package repositories to track.
1614
#' @param current A data frame of current versions and hashes of packages
1715
#' in `repo`. This argument is exposed for testing only.
1816
record_versions <- function(
1917
manifest = "versions.json",
20-
issues = "version_issues.json",
2118
repo = "https://r-multiverse.r-universe.dev",
2219
current = multiverse.internals::get_current_versions(repo = repo)
2320
) {
@@ -28,11 +25,6 @@ record_versions <- function(
2825
previous <- read_versions_previous(manifest = manifest)
2926
new <- update_version_manifest(current = current, previous = previous)
3027
jsonlite::write_json(x = new, path = manifest, pretty = TRUE)
31-
aligned <- (new$version_current == new$version_highest) &
32-
(new$hash_current == new$hash_highest)
33-
aligned[is.na(aligned)] <- TRUE
34-
new_issues <- new[!aligned,, drop = FALSE] # nolint
35-
jsonlite::write_json(x = new_issues, path = issues, pretty = TRUE)
3628
invisible()
3729
}
3830

@@ -63,9 +55,7 @@ get_current_versions <- function(
6355
}
6456

6557
read_versions_previous <- function(manifest) {
66-
out <- jsonlite::read_json(path = manifest)
67-
out <- do.call(what = vctrs::vec_rbind, args = out)
68-
out <- lapply(out, as.character)
58+
out <- jsonlite::read_json(path = manifest, simplifyVector = TRUE)
6959
if (is.null(out$version_highest)) {
7060
out$version_highest <- out$version_current
7161
}

man/record_issues.Rd

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/record_versions.Rd

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-record_issues.R

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
test_that("version_issues() in a mock repo", {
2+
# Temporary files used in the mock test.
3+
manifest <- tempfile()
4+
# First update to the manifest.
5+
contents <- data.frame(
6+
package = c(
7+
"package_unmodified",
8+
"version_decremented",
9+
"version_incremented",
10+
"version_unmodified"
11+
),
12+
version_current = rep("1.0.0", 4L),
13+
hash_current = rep("hash_1.0.0", 4L)
14+
)
15+
record_versions(manifest = manifest, current = contents)
16+
expect_equal(
17+
version_issues(manifest),
18+
data.frame(
19+
package = character(0L),
20+
version_current = character(0L),
21+
hash_current = character(0L)
22+
)
23+
)
24+
# Update the manifest after no changes to packages or versions.
25+
suppressMessages(
26+
record_versions(manifest = manifest, current = contents)
27+
)
28+
expect_equal(
29+
version_issues(manifest),
30+
data.frame(
31+
package = character(0L),
32+
version_current = character(0L),
33+
hash_current = character(0L),
34+
version_highest = character(0L),
35+
hash_highest = character(0L)
36+
)
37+
)
38+
# Update the packages in all the ways indicated above.
39+
index <- contents$package == "version_decremented"
40+
contents$version_current[index] <- "0.0.1"
41+
contents$hash_current[index] <- "hash_0.0.1"
42+
index <- contents$package == "version_incremented"
43+
contents$version_current[index] <- "2.0.0"
44+
contents$hash_current[index] <- "hash_2.0.0"
45+
index <- contents$package == "version_unmodified"
46+
contents$version_current[index] <- "1.0.0"
47+
contents$hash_current[index] <- "hash_1.0.0-modified"
48+
for (index in seq_len(2L)) {
49+
record_versions(
50+
manifest = manifest,
51+
current = contents
52+
)
53+
out <- version_issues(manifest)
54+
rownames(out) <- NULL
55+
expect_equal(
56+
out,
57+
data.frame(
58+
package = c("version_decremented", "version_unmodified"),
59+
version_current = c("0.0.1", "1.0.0"),
60+
hash_current = c("hash_0.0.1", "hash_1.0.0-modified"),
61+
version_highest = c("1.0.0", "1.0.0"),
62+
hash_highest = c("hash_1.0.0", "hash_1.0.0"),
63+
version_okay = c(FALSE, FALSE)
64+
)
65+
)
66+
}
67+
# Remove temporary files
68+
unlink(manifest)
69+
})
70+
71+
test_that("record_issues() in a mock repo", {
72+
# Temporary files used in the mock test.
73+
manifest <- tempfile()
74+
output <- tempfile()
75+
# First update to the manifest.
76+
contents <- data.frame(
77+
package = c(
78+
"package_unmodified",
79+
"version_decremented",
80+
"version_incremented",
81+
"version_unmodified"
82+
),
83+
version_current = rep("1.0.0", 4L),
84+
hash_current = rep("hash_1.0.0", 4L)
85+
)
86+
record_versions(manifest = manifest, current = contents)
87+
record_issues(manifest = manifest, output = output)
88+
expect_equal(list.files(output), character(0L))
89+
# Update the manifest after no changes to packages or versions.
90+
suppressMessages(
91+
record_versions(manifest = manifest, current = contents)
92+
)
93+
record_issues(manifest = manifest, output = output)
94+
expect_equal(list.files(output), character(0L))
95+
# Update the packages in all the ways indicated above.
96+
index <- contents$package == "version_decremented"
97+
contents$version_current[index] <- "0.0.1"
98+
contents$hash_current[index] <- "hash_0.0.1"
99+
index <- contents$package == "version_incremented"
100+
contents$version_current[index] <- "2.0.0"
101+
contents$hash_current[index] <- "hash_2.0.0"
102+
index <- contents$package == "version_unmodified"
103+
contents$version_current[index] <- "1.0.0"
104+
contents$hash_current[index] <- "hash_1.0.0-modified"
105+
for (index in seq_len(2L)) {
106+
record_versions(
107+
manifest = manifest,
108+
current = contents
109+
)
110+
record_issues(manifest = manifest, output = output)
111+
expect_equal(
112+
sort(list.files(output)),
113+
sort(c("version_decremented", "version_unmodified"))
114+
)
115+
out <- jsonlite::read_json(file.path(output, "version_decremented"))
116+
expect_equal(
117+
unlist(out, recursive = TRUE),
118+
c(
119+
package = "version_decremented",
120+
version_current = "0.0.1",
121+
hash_current = "hash_0.0.1",
122+
version_highest = "1.0.0",
123+
hash_highest = "hash_1.0.0",
124+
version_okay = FALSE
125+
)
126+
)
127+
out <- jsonlite::read_json(file.path(output, "version_unmodified"))
128+
expect_equal(
129+
unlist(out, recursive = TRUE),
130+
c(
131+
package = "version_unmodified",
132+
version_current = "1.0.0",
133+
hash_current = "hash_1.0.0-modified",
134+
version_highest = "1.0.0",
135+
hash_highest = "hash_1.0.0",
136+
version_okay = FALSE
137+
)
138+
)
139+
}
140+
# Remove temporary files
141+
unlink(manifest)
142+
})

0 commit comments

Comments
 (0)