Skip to content

Commit

Permalink
Consider packages in topological order
Browse files Browse the repository at this point in the history
  • Loading branch information
krlmlr committed Sep 26, 2023
1 parent 92c361d commit 4418a85
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions R/find.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#' conflict_scout()
conflict_scout <- function(pkgs = NULL) {
pkgs <- pkgs %||% pkgs_attached()
pkgs <- topo_sort(pkgs)
objs <- lapply(pkgs, pkg_ls)
names(objs) <- pkgs

Expand Down
54 changes: 54 additions & 0 deletions R/topo.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
pkg_dep <- function(pkg) {
if (pkg == "base") {
return()
}
ns <- asNamespace(pkg)
path <- ns$.__NAMESPACE__.$path

# Safety net
if (is.null(path)) {
lib <- NULL
} else {
lib <- dirname(path)
}

imports <- utils::packageDescription(pkg, lib.loc = lib)$Imports
if (is.null(imports)) {
return(character())
}
imports <- gsub(" *", "", imports)
imports <- gsub("[(][^)]+[)]", "", imports)
imports <- gsub("\n", "", imports)
strsplit(imports, ",")[[1]]
}

pkg_deps <- function(pkgs) {
lapply(set_names(pkgs), pkg_dep)
}

# AI generated
topo_sort <- function(pkgs) {
adj_list <- pkg_deps(pkgs)
visited <- list()
stack <- character()

dfs <- function(vertex) {
visited[[vertex]] <<- TRUE

for (neighbor in adj_list[[vertex]]) {
if (!isTRUE(visited[[neighbor]])) {
dfs(neighbor)
}
}

stack <<- c(stack, vertex)
}

for (vertex in names(adj_list)) {
if (!isTRUE(visited[[vertex]])) {
dfs(vertex)
}
}

intersect(stack, pkgs)
}
12 changes: 12 additions & 0 deletions tests/testthat/_snaps/topo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# topo_sort() works

Code
intersect(topo_sort(c("testthat", "rlang")), c("testthat", "rlang"))
Output
[1] "rlang" "testthat"
Code
intersect(topo_sort(c("testthat", "rlang", "withr")), c("testthat", "rlang",
"withr"))
Output
[1] "rlang" "withr" "testthat"

13 changes: 13 additions & 0 deletions tests/testthat/test-topo.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
test_that("topo_sort() works", {
# Can only use packages that we import or suggest
expect_snapshot({
intersect(
topo_sort(c("testthat", "rlang")),
c("testthat", "rlang")
)
intersect(
topo_sort(c("testthat", "rlang", "withr")),
c("testthat", "rlang", "withr")
)
})
})

0 comments on commit 4418a85

Please sign in to comment.