diff --git a/.github/workflows/r-ci.yml b/.github/workflows/r-ci.yml index 6187410c8c..a09f7d19a0 100644 --- a/.github/workflows/r-ci.yml +++ b/.github/workflows/r-ci.yml @@ -16,7 +16,7 @@ env: COVERAGE_TOKEN: ${{ secrets.CODECOV_TOKEN }} _R_CHECK_TESTS_NLINES_: 0 CATCHSEGV: "TRUE" - + jobs: ci: strategy: @@ -52,6 +52,11 @@ jobs: - name: Bootstrap run: cd apis/r && tools/r-ci.sh bootstrap + - name: Set pkgType to binary (macOS) + if: ${{ matrix.os == 'macOS-latest' }} + run: cat("\noptions(pkgType = 'binary')\n", file = "~/.Rprofile", append = TRUE) + shell: Rscript {0} + - name: Install BioConductor package SingleCellExperiment run: cd apis/r && tools/r-ci.sh install_bioc SingleCellExperiment @@ -77,6 +82,10 @@ jobs: - name: Dependencies run: cd apis/r && tools/r-ci.sh install_all + - name: Install dataset packages from source (macOS) + if: ${{ matrix.os == 'macOS-latest' }} + run: cd apis/r && _CI_PKG_TYPE_=both _CI_USE_BIOC_=true Rscript tools/install_missing_deps.R + - name: CMake uses: lukka/get-cmake@latest @@ -116,4 +125,3 @@ jobs: - name: View Logs run: apis/r/tools/r-ci.sh dump_logs if: failure() - diff --git a/apis/r/tools/install_missing_deps.R b/apis/r/tools/install_missing_deps.R new file mode 100644 index 0000000000..42a8232d82 --- /dev/null +++ b/apis/r/tools/install_missing_deps.R @@ -0,0 +1,111 @@ +#!/usr/bin/env Rscript + +wd <- Sys.getenv("_CI_WORKING_DIRECTORY_", unset = getwd()) +pkgtype <- Sys.getenv("_CI_PKG_TYPE_", unset = getOption("pkgType")) + +if (isTRUE(as.logical(Sys.getenv("_CI_USE_BIOC_")))) { + message("Setting up Bioconductor repos") + setRepositories(ind = 1:3) +} + +desc <- as.list(x = as.data.frame(x = read.dcf( + file = file.path(wd, "DESCRIPTION"), + fields = c( + "Depends", + "Imports", + "LinkingTo", + "Suggests", + "Enhances", + "Additional_repositories" + ) +))) + +desc <- Filter(f = Negate(f = is.na), x = desc) + +if (!is.null(desc$Additional_repositories)) { + desc$Additional_repositories <- trimws(x = unlist(x = strsplit( + x = desc$Additional_repositories, + split = ',' + ))) +} + +repos <- c(desc$Additional_repositories, getOption("repos")) +desc$Additional_repositories <- NULL + +message("Identifying dependencies to install") +desc <- lapply( + X = desc, + FUN = function(x) { + x <- trimws(x = unlist(x = strsplit(x = x, split = ","))) + x <- strsplit(x = x, split = " \\(>= ") + for (i in seq_along(along.with = x)) { + x[[i]][2L] <- x[[i]][2L] + } + x <- as.data.frame(x = t(x = data.frame(x))) + row.names(x = x) <- NULL + names(x = x) <- c("Package", "Version") + x$Version <- sub(pattern = "\\)$", replacement = "", x = x$Version) + if (length(idx <- which(x = x$Package == "R"))) { + x <- x[-idx, , drop = FALSE] + } + if (!nrow(x = x)) { + return(x) + } + x$Version[is.na(x = x$Version)] <- "0.0.0" + x$Installed <- logical(length = nrow(x = x)) + pb <- txtProgressBar(max = nrow(x), style = 3L, file = stderr()) + on.exit(expr = close(con = pb), add = TRUE) + for (i in seq_len(length.out = nrow(x = x))) { + x$Installed[i] <- requireNamespace(x$Package[i], quietly = TRUE) && + utils::packageVersion(x$Package[i]) >= x$Version[i] + setTxtProgressBar(pb = pb, value = i) + } + return(x) + } +) + +desc <- do.call(what = "rbind", args = desc) +row.names(x = desc) <- NULL + +desc <- desc[!desc$Installed, , drop = FALSE] + +if (nrow(x = desc)) { + message( + "Found ", + nrow(x = desc), + " missing ", + ngettext(n = nrow(x = desc), msg1 = "dependency", msg2 = "dependencies") + ) + message("Finding additional downstream dependencies") + db <- utils::available.packages(repos = repos, type = pkgtype) + deps <- unique(x = unlist( + x = tools::package_dependencies( + packages = desc$Package, + db = db, + recursive = TRUE + ), + use.names = FALSE + )) + deps <- setdiff(x = deps, y = c(utils::sessionInfo()$basePkgs, desc$Package)) + deps <- Filter( + f = Negate(f = \(x) isTRUE(requireNamespace(x, quietly = TRUE))), + x = deps + ) + if (length(x = deps)) { + message( + "Found ", + length(x = deps), + " additional ", + ngettext(n = length(x = deps), msg1 = "pacakge", msg2 = "packages") + ) + } + pkgs <- union(x = deps, y = desc$Package) + message( + "Installing ", + length(x = pkgs), + ngettext(n = length(x = pkgs), msg1 = " package", msg2 = " packages"), + ":\n", + paste(" -", pkgs, collapse = "\n") + ) + install.packages(pkgs, type = pkgtype, repos = repos) +}