From ca921497c6da495f28faab99aea776d39f0c7083 Mon Sep 17 00:00:00 2001 From: Sean Davis Date: Thu, 25 Jun 2026 10:16:45 -0400 Subject: [PATCH] Fix pkgBiocRevDeps(recursive = TRUE) leaking forward dependencies Recursing reverse dependencies over 'Suggests' / 'Enhances' edges explodes to nearly the entire repository (e.g. thousands of packages 'Suggests' knitr), which pulled in the queried package's own forward (non-reverse) dependencies. Restrict the recursion to strong dependencies so only genuine reverse dependencies are returned. For Rarr this reduces the recursive result from 25,613 packages to 4. Adds a regression test and bumps the version with a NEWS entry. Fixes #81 Co-Authored-By: Claude Opus 4.8 --- DESCRIPTION | 4 ++-- NEWS | 10 ++++++++++ R/pkgBiocDeps.R | 6 +++++- tests/testthat/test-pkgBiocDeps.R | 26 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/testthat/test-pkgBiocDeps.R diff --git a/DESCRIPTION b/DESCRIPTION index 0a8f92e..7918fa7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: BiocPkgTools Type: Package Title: Collection of simple tools for learning about Bioconductor Packages -Version: 1.29.4 -Date: 2026-03-13 +Version: 1.29.5 +Date: 2026-06-25 Authors@R: c( person("Shian", "Su", role=c("aut", "ctb"), email = "su.s@wehi.edu.au"), person("Lori", "Shepherd", role="ctb", email = "Lori.Shepherd@roswellpark.org"), diff --git a/NEWS b/NEWS index 18dafef..3a0c0a5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +CHANGES IN VERSION 1.30.0 +------------------------- + +BUG FIXES AND MINOR IMPROVEMENTS + + o `pkgBiocRevDeps(recursive = TRUE)` no longer returns forward + (non-reverse) dependencies. Recursion now follows only strong + dependencies, avoiding the `Suggests` / `Enhances` explosion that pulled + in nearly the entire repository (#81). + CHANGES IN VERSION 1.28.0 ------------------------- diff --git a/R/pkgBiocDeps.R b/R/pkgBiocDeps.R index fc8faff..b19fd6c 100644 --- a/R/pkgBiocDeps.R +++ b/R/pkgBiocDeps.R @@ -98,8 +98,12 @@ pkgBiocRevDeps <- function( biocdb <- utils::available.packages(repos = repo) if (recursive) + ## Only recurse over strong dependencies. Recursing reverse + ## dependencies over 'Suggests' / 'Enhances' explodes to nearly the + ## entire repository (e.g. thousands of packages 'Suggests' knitr), + ## which pulls in forward (non-reverse) dependencies. See issue #81. res <- tools::package_dependencies( - pkg, all_db, reverse = TRUE, which = which, recursive = recursive + pkg, all_db, reverse = TRUE, which = which, recursive = "strong" )[[pkg]] else res <- lapply(which, function(ofwhich) { diff --git a/tests/testthat/test-pkgBiocDeps.R b/tests/testthat/test-pkgBiocDeps.R new file mode 100644 index 0000000..ddbb348 --- /dev/null +++ b/tests/testthat/test-pkgBiocDeps.R @@ -0,0 +1,26 @@ +test_that("pkgBiocRevDeps(recursive = TRUE) returns only reverse deps", { + ## Regression test for issue #81: recursive reverse dependencies must not + ## leak forward (non-reverse) dependencies. Recursing reverse dependencies + ## over 'Suggests' / 'Enhances' previously exploded to nearly the entire + ## repository, pulling in forward dependencies of the queried package. + pkg <- "Rarr" + + db <- utils::available.packages(repos = BiocManager::repositories()) + skip_if_not(pkg %in% rownames(db), "Rarr not available in repositories") + + ## Forward dependencies that are not themselves reverse dependencies should + ## never appear in the recursive reverse-dependency result. + fwd <- tools::package_dependencies(pkg, db, which = "all")[[pkg]] + rev1 <- tools::package_dependencies( + pkg, db, reverse = TRUE, which = "all" + )[[pkg]] + fwd_only <- setdiff(fwd, rev1) + + res <- pkgBiocRevDeps(pkg, recursive = TRUE, only.bioc = FALSE) + rec <- as.character(res) + + expect_false(any(fwd_only %in% rec)) + ## The explosion produced tens of thousands of packages; a sane recursive + ## reverse-dependency set is a small fraction of the repository. + expect_lt(length(rec), nrow(db) / 2) +})