write_PACKAGES <- function(dir, fields = NULL, type = c("source", "mac.binary", "win.binary"), verbose = FALSE) { if(missing(type) && .Platform$OS.type == "windows") type <- "win.binary" type <- match.arg(type) desc <- .build_repository_package_db(dir, fields, type, verbose) if(length(desc)) { fields <- colnames(desc[[1]]) desc <- matrix(unlist(desc), ncol = length(fields), byrow = TRUE) colnames(desc) <- fields ## bundles do not have a Package entry in the DESCRIPTION, ## hence replace non-existing Package entries by Bundle entries noPack <- is.na(desc[,"Package"]) desc[noPack, "Package"] <- desc[noPack, "Bundle"] ## Writing PACKAGES file from matrix desc linewise in order to ## omit NA entries appropriately: out <- file(file.path(dir, "PACKAGES"), "wt") outgz <- gzfile(file.path(dir, "PACKAGES.gz"), "wt") for(i in seq_len(nrow(desc))){ desci <- desc[i, !(is.na(desc[i, ]) | (desc[i, ] == "")), drop = FALSE] write.dcf(desci, file = out) write.dcf(desci, file = outgz) } close(out) close(outgz) invisible(nrow(desc)) } else invisible(0) } .build_repository_package_db <- function(dir, fields = NULL, type = c("source", "mac.binary", "win.binary"), verbose = getOption("verbose")) { type <- match.arg(type) package_pattern <- switch(type, "source" = "\\.tar\\.gz$", "mac.binary" = "\\.tgz$", "win.binary" = "\\.zip$") files <- list.files(dir, pattern = package_pattern) if(!length(files)) return(list()) ## Add the standard set of fields required to build a repository's ## PACKAGES file: fields <- unique(c(.get_standard_repository_db_fields(), fields)) packages <- sapply(strsplit(files, "_"), "[", 1) files <- file.path(dir, files) db <- vector(length(files), mode = "list") ## Many (roughly length(files)) warnings are *expected*, hence ## suppressed. op <- options(warn = -1) on.exit(options(op)) if(verbose) message("Processing packages:") if(type == "win.binary") { for(i in seq_along(files)) { if(verbose) message(paste(" ", files[i])) ## for bundles: con <- unz(files[i], "DESCRIPTION") temp <- try(read.dcf(con, fields = fields), silent = TRUE) if(inherits(temp, "try-error")) { close(con) ## for regular packages: con <- unz(files[i], file.path(packages[i], "DESCRIPTION")) temp <- try(read.dcf(con, fields = fields), silent = TRUE) if(inherits(temp, "try-error")) { close(con) next } } db[[i]] <- temp close(con) } } else { dir <- file_path_as_absolute(dir) files <- list.files(dir, pattern = package_pattern, full.names = TRUE) cwd <- getwd() td <- tempfile("PACKAGES") if(!dir.create(td)) stop("unable to create ", td) on.exit(unlink(td, recursive = TRUE), add = TRUE) setwd(td) for(i in seq_along(files)) { if(verbose) message(paste(" ", files[i])) p <- file.path(packages[i], "DESCRIPTION") temp <- try(system(paste("tar zxf", files[i], p))) if(!inherits(temp, "try-error")) { temp <- try(read.dcf(p, fields = fields), silent = TRUE) if(!inherits(temp, "try-error")) db[[i]] <- temp } unlink(packages[i], recursive = TRUE) } setwd(cwd) } if(verbose) message("done") db }