Skip to content

Commit

Permalink
feat: add generator for CRAN semantic fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Nov 9, 2023
1 parent 4f305b9 commit ce55b26
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/semantic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ jobs:
name: generated-versions
path: pkg/semantic/fixtures/maven-versions-generated.txt

generate-cran-versions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: r-lib/actions/setup-r@v2
with:
r-version: '3.5.3'
- run: Rscript -e 'print("hello")'
# - run: java -cp 'generators/lib/*' generators/GenerateMavenVersions.java
- run: git status
- uses: actions/upload-artifact@v3
with:
name: generated-versions
path: pkg/semantic/fixtures/maven-versions-generated.txt

generate-e2e-fixtures:
runs-on: ubuntu-latest
steps:
Expand Down
145 changes: 145 additions & 0 deletions generators/generate-cran-versions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
library(utils)

# An array of version comparisons that are known to be unsupported and so
# should be commented out in the generated fixture.
#
# Generally this is because the native implementation has a suspected bug
# that causes the comparison to return incorrect results, and so supporting
# such comparisons in the detector would in fact be wrong.
UNSUPPORTED_COMPARISONS <- c()

download_cran_db <- function() {
url <- "https://osv-vulnerabilities.storage.googleapis.com/CRAN/all.zip"
dest <- "cran-db.zip"
download.file(url, dest, method = "auto")
}

is_unsupported_comparison <- function(line) {
line %in% UNSUPPORTED_COMPARISONS
}

uncomment <- function(line) {
if (startsWith(line, "#")) {
return(substr(line, 2, nchar(line)))
}
if (startsWith(line, "//")) {
return(substr(line, 3, nchar(line)))
}
return(line)
}

compare <- function(v1, relate, v2) {
ops <- list('<' = function(result) result < 0,
'=' = function(result) result == 0,
'>' = function(result) result > 0)

return(ops[[relate]](compareVersion(v1, v2)))
}

compare_versions <- function(lines, select="all") {
has_any_failed <- FALSE

for (line in lines) {
line <- trimws(line)

if (line == "" || grepl("^#", line) || grepl("^//", line)) {
maybe_unsupported <- trimws(uncomment(line))

if (is_unsupported_comparison(maybe_unsupported)) {
cat(sprintf("\033[96mS\033[0m: \033[93m%s\033[0m\n", maybe_unsupported))
}
next
}

parts <- strsplit(trimws(line), " ")[[1]]
v1 <- parts[1]
op <- parts[2]
v2 <- parts[3]

r <- compare(v1, op, v2)

if (!r) {
has_any_failed <- TRUE
}

if (select == "failures" && r) {
next
}

if (select == "successes" && !r) {
next
}

color <- ifelse(r, '\033[92m', '\033[91m')
rs <- ifelse(r, "T", "F")
cat(sprintf("%s%s\033[0m: \033[93m%s\033[0m\n", color, rs, line))
}
return(has_any_failed)
}

compare_versions_in_file <- function(filepath, select="all") {
lines <- readLines(filepath)
return(compare_versions(lines, select))
}

generate_version_compares <- function(versions) {
comparisons <- character()

for (i in seq_along(versions)) {
if (i == 1) {
next
}

comparison <- sprintf("%s < %s\n", versions[i - 1], versions[i])

if (is_unsupported_comparison(trimws(comparison))) {
comparison <- paste("#", comparison)
}

comparisons <- c(comparisons, comparison)
}

return(comparisons)
}

generate_package_compares <- function(packages) {
comparisons <- character()

for (package in names(packages)) {
versions <- packages[[package]]
comparisons <- c(comparisons, generate_version_compares(versions))
}

# return unique comparisons
return(unique(comparisons))
}

fetch_packages_versions <- function() {
download_cran_db()
osvs <- list()

with_zip <- unzip("cran-db.zip", list = TRUE)

for (fname in with_zip$Name) {
osv <- jsonlite::fromJSON(unzip("cran-db.zip", files = fname, exdir = tempdir()))
osvs <- c(osvs, list(osv))
}

return(extract_packages_with_versions(osvs))
}

outfile <- "pkg/semantic/fixtures/cran-versions-generated.txt"

packs <- fetch_packages_versions()
writeLines(generate_package_compares(packs), outfile, sep = "\n")
cat("\n")

# set this to either "failures" or "successes" to only have those comparison results
# printed; setting it to anything else will have all comparison results printed
show <- Sys.getenv("VERSION_GENERATOR_PRINT", "failures")

did_any_fail <- compare_versions_in_file(outfile, show)

if (did_any_fail) {
q(status = 1)
}

0 comments on commit ce55b26

Please sign in to comment.