3 r_requiring <- function(names) {
4 # approximately prune first into a smaller availability
5 candidates <- rownames(available)[sapply(rownames(available)
7 length(grep(paste(names,collapse='|')
8 ,available[name,r_depend_fields])) > 0)]
9 if (length(candidates) == 0) {
12 # find a logical index into available of every package
13 # whose dependency field contains at least one element of names.
14 # (this is not particularly easy to read---sorry---but is much faster than
15 # the alternatives i could think of)
17 dep_matches <- function(dep) chomp(gsub('\\([^\\)]+\\)','',dep)) %in% names
18 any_dep_matches <- function(name,field=NA)
19 any(sapply(strsplit(chomp(available[name,field])
20 ,'[[:space:]]*,[[:space:]]*')
23 for (field in r_depend_fields) {
24 matches = sapply(candidates, any_dep_matches, field=field)
25 if (length(matches) > 0) {
26 prereq = c(prereq,candidates[matches])
29 return(unique(prereq))
32 r_dependencies_of <- function(name=NULL,description=NULL) {
33 # find the immediate dependencies (children in the dependency graph) of an
35 if (!is.null(name) && (name == 'R' || name %in% base_pkgs)) {
38 if (is.null(description) && is.null(name)) {
39 fail('must specify either a description or a name.')
41 if (is.null(description)) {
42 if (!(name %in% rownames(available))) {
43 # unavailable packages don't depend upon anything
46 description <- data.frame()
47 # keep only the interesting fields
48 for (field in r_depend_fields) {
49 if (!(field %in% names(available[name,]))) {
52 description[1,field] = available[name,field]
55 # extract the dependencies from the description
57 for (field in r_depend_fields) {
58 if (!(field %in% names(description[1,]))) {
61 new_deps <- lapply(strsplit(chomp(description[1,field])
62 ,'[[:space:]]*,[[:space:]]*')[[1]]
64 deps <- iterate(lapply(new_deps[!is.na(new_deps)],rbind),deps,rbind)
69 r_parse_dep_field <- function(dep) {
73 # remove other comments
74 dep = gsub('(\\(\\)|\\([[:space:]]*[^<=>!].*\\))','',dep)
76 dep = chomp(gsub('[[:space:]]+',' ',dep))
78 pat = '^([^ ()]+) ?(\\( ?([<=>!]+ ?[0-9.-]+) ?\\))?$'
79 if (!length(grep(pat,dep))) {
80 fail('R dependency',dep,'does not appear to be well-formed')
82 version = sub(pat,'\\3',dep)
83 dep = sub(pat,'\\1',dep)
84 return(list(name=dep,version=version))
87 r_dependency_closure <- function(fringe, forward_arcs=T) {
88 # find the transitive closure of the dependencies/prerequisites of some R
91 if (is.data.frame(fringe)) {
92 fringe <- as.list(fringe$name)
94 fun = function(x) r_dependencies_of(name=x)$name
98 while(length(fringe) > 0) {
101 if (length(fringe) > 1) {
102 fringe <- fringe[2:length(fringe)]
106 src <- pkgname_as_debian(top,binary=F)
111 closure=c(closure,top)
112 fringe=c(fringe,newdeps)
115 return(rev(unique(closure,fromLast=T)))