|
1 | | -library(withr) |
2 | | -library(xml2) |
3 | | - |
4 | | -rev_dep_span = "https://cran.r-project.org/web/packages/bit64/index.html" |> |
5 | | - read_html() |> |
6 | | - xml_find_all(" |
7 | | - //h4[contains(text(), 'Reverse dependencies')] |
8 | | - /following-sibling::table[1] |
9 | | - /tr[not(td[contains(text(), 'enhances')])] |
10 | | - /td |
11 | | - /a |
12 | | - /span |
13 | | - ") |
14 | | - |
15 | | -rev_df = data.frame( |
16 | | - package = xml_text(rev_dep_span), |
17 | | - source = xml_attr(rev_dep_span, "class") |
| 1 | +library(BiocManager) |
| 2 | + |
| 3 | +db = available.packages(repos = BiocManager::repositories()) |
| 4 | + |
| 5 | +rev_deps = unlist(tools::package_dependencies("bit64", reverse=TRUE, recursive=FALSE, db=db, which='all'), use.names=FALSE) |
| 6 | + |
| 7 | +cat(sprintf( |
| 8 | + "Found %d reverse dependencies, %d of which are on CRAN\n", |
| 9 | + length(rev_deps), sum(grepl("cloud.r-project.org", db[rev_deps, "Repository"])) |
| 10 | +)) |
| 11 | + |
| 12 | +apt_packages = c( |
| 13 | + "cmake", |
| 14 | + NULL |
| 15 | +) |
| 16 | +apt_get_packages = c( |
| 17 | + "libcurl4-openssl-dev", |
| 18 | + "libssl-dev", |
| 19 | + "libfontconfig1-dev", |
| 20 | + "libharfbuzz-dev", |
| 21 | + "libfribidi-dev", |
| 22 | + "libxml2-dev", |
| 23 | + "libnetcdf-dev", |
| 24 | + "libgrpc++-dev", |
| 25 | + "libprotobuf-dev", |
| 26 | + "protobuf-compiler-grpc", |
| 27 | + "pkg-config", |
| 28 | + "libgdal-dev", |
| 29 | + "libgeos-dev", |
| 30 | + "libproj-dev", |
| 31 | + "openjdk-21-jdk", |
| 32 | + "libmpfr-dev", |
| 33 | + "libgmp-dev", |
| 34 | + "libudunits2-dev", |
| 35 | + "libgsl-dev", |
| 36 | + "libv8-dev", |
| 37 | + "libfftw3-dev", |
| 38 | + "libmagick++-dev", |
| 39 | + NULL |
18 | 40 | ) |
19 | 41 |
|
20 | | -message(sprintf( |
21 | | - "Found %d reverse dependencies, %d of which are on CRAN", |
22 | | - nrow(rev_df), sum(rev_df$source == "CRAN") |
| 42 | +cat(sprintf( |
| 43 | + "Installing %d system requirements...\n", |
| 44 | + length(apt_packages) + length(apt_get_packages) |
23 | 45 | )) |
24 | 46 |
|
25 | | -system(" |
26 | | - sudo apt update && sudo apt-get update && \ |
27 | | - sudo apt install libgsl-dev mpich libopenmpi-dev && \ |
28 | | - sudo apt-get install \ |
29 | | - libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc pkg-config libssh-dev libarchive-dev |
30 | | -") |
31 | | -# install rust in the most insane way possible |
32 | | -system("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh") |
33 | | - |
34 | | -if (!require("BiocManager")) { install.packages("BiocManager"); require("BiocManager") } |
35 | | - |
36 | | -cran_reqs = rev_df$package[rev_df$source == "CRAN"] |
37 | | -bioc_reqs = rev_df$package[rev_df$source == "BioC"] |
38 | | - |
39 | | -# First-level downstreams typically need their Suggests available to pass their own |
40 | | -# tests (and even if they pass without Suggests, they might have a much richer suite |
41 | | -# with their Suggests available), hence install their Suggests, however, _don't_ use |
42 | | -# dependencies=TRUE since that installs Suggests-of-Suggests, which is much too wide |
43 | | -# a net to case for the purposes here. We can use the default dependencies=NA on the |
44 | | -# output of this function. |
45 | | -first_level_reqs = function(pkgs) { |
46 | | - direct_full_req = |
47 | | - available.packages()[pkgs, c("Depends", "Imports", "Suggests", "LinkingTo")] |
48 | | - c(direct_full_req) |> |
49 | | - na.omit() |> |
50 | | - tools:::.split_dependencies() |> |
51 | | - names() |> |
52 | | - setdiff("R") |
53 | | -} |
| 47 | +sudo = Sys.which("sudo") |
| 48 | +cmd_update = paste(sudo, c("apt modernize-sources", "apt update", "apt-get update"), collapse = " && ") |
| 49 | +cmd_apt = paste(sudo, "apt install", paste(apt_packages, collapse = " ")) |
| 50 | +cmd_apt_get = paste(sudo, "apt-get install -y", paste(apt_get_packages, collapse = " ")) |
54 | 51 |
|
55 | | -# This iteration is mainly to ensure second-order deps are also installed, |
56 | | -# including Suggests to minimize spurious test failures even though it can |
57 | | -# massively increase install time. |
58 | | -message("Installing all revdeps to latest CRAN version (indiscriminately)") |
59 | | -install.packages(first_level_reqs(cran_reqs)) |
60 | | -# TODO: figure out how to do the same for BioConductor |
61 | | -install(bioc_reqs, dependencies=TRUE) |
| 52 | +system(cmd_update) |
| 53 | +system(cmd_apt) |
| 54 | +system(cmd_apt_get) |
62 | 55 |
|
63 | | -if (!all(rev_df$package %in% rownames(installed.packages()))) |
64 | | - stop("Some packages failed to install, necessitating some manual intervention...") |
| 56 | +cat(sprintf("Installing downstreams with --install-tests\n")) |
65 | 57 |
|
66 | 58 | message("Installing all revdeps (again), this time with --install-tests") |
67 | | -install.packages(cran_reqs, INSTALL_opts = "--install-tests") |
68 | | -install( bioc_reqs, INSTALL_opts = "--install-tests") |
| 59 | +install(rev_deps, INSTALL_opts="--install-tests", dependencies=TRUE) |
| 60 | + |
| 61 | +if (!all(rev_deps %in% rownames(installed.packages()))) |
| 62 | + stop("Some packages failed to install, necessitating some manual intervention...") |
| 63 | + |
| 64 | +if (!basename(getwd()) == "bit64") |
| 65 | + stop("The proceeding assumes you're in the bit64 package directory.") |
| 66 | + |
| 67 | +run_revdep_tests = function(pkgs) { |
| 68 | + log_file = 'all_test_output.log' |
| 69 | + file.create(log_file) |
| 70 | + log_file = normalizePath(log_file) |
| 71 | + for (pkg in pkgs) { |
| 72 | + cat(pkg, "") |
| 73 | + dir.create(pkg, showWarnings=FALSE) |
| 74 | + local({ |
| 75 | + tmp <- tempfile() |
| 76 | + setwd(pkg) |
| 77 | + on.exit({unlink(tmp); setwd("..")}) |
| 78 | + |
| 79 | + system2("Rscript", |
| 80 | + c("-e", shQuote(sprintf("tools::testInstalledPackage('%s')", pkg))), |
| 81 | + stderr = tmp, stdout = tmp |
| 82 | + ) |
| 83 | + cat(readLines(tmp), sep='\n', file=log_file, append=TRUE) |
| 84 | + }) |
| 85 | + } |
| 86 | + cat("\n") |
| 87 | +} |
| 88 | + |
| 89 | +## REVDEPS USING DEVEL VERSION |
| 90 | +system("R CMD INSTALL .") |
69 | 91 |
|
70 | 92 | dir.create("revdep", showWarnings=FALSE) |
71 | 93 | setwd("revdep") |
72 | | -con = file("all_test_output.log", "a") |
73 | | -for (pkg in rev_df$package) { |
74 | | - cat(pkg,"") |
75 | | - with_tempfile("tmp", { |
76 | | - system2("Rscript", |
77 | | - c("-e", shQuote(sprintf("tools::testInstalledPackage('%s')", pkg))), |
78 | | - stderr = tmp, stdout = tmp |
79 | | - ) |
80 | | - writeLines(readLines(tmp), con) |
81 | | - }) |
82 | | -} |
83 | | -close(con) |
84 | 94 |
|
85 | | -failing_pkg = unique(sub("-.*", "", list.files(recursive=TRUE, pattern="\\.Rout\\.fail$"))) |
| 95 | +dir.create("devel", showWarnings=FALSE) |
| 96 | +setwd("devel") |
| 97 | +run_revdep_tests(rev_deps) |
| 98 | + |
| 99 | +failing_pkgs = unique(sub("/.*", "", list.files(recursive=TRUE, pattern="\\.Rout\\.fail$"))) |
| 100 | +setwd("..") |
| 101 | + |
| 102 | +## REVDEPS USING CRAN VERSION (for baseline among failing packages) |
| 103 | + |
| 104 | +install('bit64', force=TRUE) |
| 105 | + |
| 106 | +dir.create("cran", showWarnings=FALSE) |
| 107 | +setwd("cran") |
| 108 | +run_revdep_tests(failing_pkgs) |
| 109 | + |
| 110 | +failing_on_cran = unique(sub("/.*", "", list.files(recursive=TRUE, pattern="\\.Rout\\.fail$"))) |
| 111 | + |
| 112 | +cat(sprintf( |
| 113 | + "The following packages fail on CRAN as well as with devel and are ignored:\n %s\n", |
| 114 | + paste(failing_on_cran, collapse = " ") |
| 115 | +)) |
86 | 116 |
|
87 | | -# examine failure logs manually... |
| 117 | +setdiff(failing_pkgs, failing_on_cran) |
0 commit comments