Latest build
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -48,3 +48,6 @@ po/*~
|
|||||||
.Rproj.user
|
.Rproj.user
|
||||||
.Rdata
|
.Rdata
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# pacman - package management folder
|
||||||
|
.pacman/
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
Package: Rpacman
|
Package: Rpacman
|
||||||
Type: Package
|
Type: Package
|
||||||
Title: Very simple package manager for R
|
Title: Very simple package manager for R
|
||||||
Version: 1.0.0
|
Version: 1.0.3
|
||||||
Date: 2022-05-31
|
Date: 2022-05-31
|
||||||
Authors@R: person("Craig", "Williams", email = "craig@avsdev.uk", role = c("aut", "cre"))
|
Authors@R: person("Craig", "Williams", email = "craig@avsdev.uk", role = c("aut", "cre"))
|
||||||
URL: https://avsdev.uk/R/Rpacman
|
URL: https://avsdev.uk/R/Rpacman
|
||||||
Description: Very simple package manager for R which allows scanning for used packages, finding their dependencies and versions, creating a lock file and installing the packages on a new build.
|
Description: Very simple package manager for R which allows scanning for used packages, finding their dependencies and versions, creating a lock file and installing the packages on a new build.
|
||||||
License: GPL (>= 3)
|
License: GPL (>= 3)
|
||||||
Depends: R (>= 3.1.0), dplyr, magrittr, renv
|
Depends: R (>= 3.1.0), renv, jsonlite, remotes
|
||||||
RoxygenNote: 7.1.1
|
RoxygenNote: 7.1.1
|
||||||
|
|||||||
13
NAMESPACE
13
NAMESPACE
@@ -1,6 +1,19 @@
|
|||||||
# Generated by roxygen2: do not edit by hand
|
# Generated by roxygen2: do not edit by hand
|
||||||
|
|
||||||
|
export(activate)
|
||||||
|
export(compile_imports)
|
||||||
export(fetch_available_archives)
|
export(fetch_available_archives)
|
||||||
export(fetch_available_packages)
|
export(fetch_available_packages)
|
||||||
|
export(install_package_source)
|
||||||
|
export(isolate)
|
||||||
export(list_depends)
|
export(list_depends)
|
||||||
export(list_imports)
|
export(list_imports)
|
||||||
|
export(restore)
|
||||||
|
export(snapshot)
|
||||||
|
export(snapshot_create)
|
||||||
|
export(snapshot_history)
|
||||||
|
export(snapshot_latest)
|
||||||
|
import(jsonlite)
|
||||||
|
import(parallel)
|
||||||
|
import(remotes)
|
||||||
|
import(renv)
|
||||||
|
|||||||
15
R/activate.R
Normal file
15
R/activate.R
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#' Adds the pacman library path to the .libPaths variable, either as an extra
|
||||||
|
#' library or as the only library
|
||||||
|
#'
|
||||||
|
#' @param totalIsolation boolean Only refer to the pacman library, do not use
|
||||||
|
#' any user library paths
|
||||||
|
#'
|
||||||
|
#' @export
|
||||||
|
activate <- function(totalIsolation = FALSE) {
|
||||||
|
if (totalIsolation) {
|
||||||
|
environment(.libPaths)$.lib.loc <- c(file.path(getwd(), ".pacman/library"), .Library)
|
||||||
|
} else {
|
||||||
|
.libPaths(c(file.path(getwd(), ".pacman/library"), .libPaths()))
|
||||||
|
}
|
||||||
|
}
|
||||||
67
R/add_package.R
Normal file
67
R/add_package.R
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#' Add a package to the project.
|
||||||
|
#'
|
||||||
|
#' @param packageName boolean Only refer to the pacman library, do not use
|
||||||
|
#' any user library paths
|
||||||
|
#' @param installOpts boolean Only refer to the pacman library, do not use
|
||||||
|
#' any user library paths
|
||||||
|
#'
|
||||||
|
add_package <- function(packageName = NULL, installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
|
if (is.null(packageName)) {
|
||||||
|
repeat {
|
||||||
|
packageName <- trimws(readline("Please specify the name of the package you wish to add: "))
|
||||||
|
if (nchar(packageName) > 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cranPackages <- fetch_available_packages()
|
||||||
|
archivePackages <- fetch_available_archives()
|
||||||
|
|
||||||
|
if (packageName %in% cranPackages$package) {
|
||||||
|
repeat({
|
||||||
|
installCRAN <- trimws(readline("Found package in CRAN, proceed with install? [Yn]: "))
|
||||||
|
if (nchar(installCRAN) == 0) {
|
||||||
|
installCRAN <- "Y"
|
||||||
|
}
|
||||||
|
if (nchar(installCRAN) == 1 && installCRAN %in% c("Y", "y", "N", "n")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (installCRAN %in% c("Y", "y")) {
|
||||||
|
do.call(utils::install.packages, c(package, installOpts))
|
||||||
|
return(TRUE)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cat("Package not found on CRAN.\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
repeat({
|
||||||
|
installCustom <- trimws(readline("Would you like to provide a source? [Yn]: "))
|
||||||
|
if (nchar(installCustom) == 0) {
|
||||||
|
installCustom <- "Y"
|
||||||
|
}
|
||||||
|
if (nchar(installCustom) == 1 && installCustom %in% c("Y", "y", "N", "n")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (installCustom %in% c("N", "n")) {
|
||||||
|
cat("Package installation cancelled.\n")
|
||||||
|
return(FALSE)
|
||||||
|
}
|
||||||
|
|
||||||
|
source <- request_package_source(package)
|
||||||
|
|
||||||
|
if (is.null(source)) {
|
||||||
|
cat("Package installation cancelled.\n")
|
||||||
|
return(FALSE)
|
||||||
|
}
|
||||||
|
|
||||||
|
package <- install_package_source(c(package = packageName, source), installOpts)
|
||||||
|
|
||||||
|
return(TRUE)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
# Requires fetch_available_packages.R
|
# Requires fetch_available_packages.R
|
||||||
# Requires fetch_available_archives.R
|
# Requires fetch_available_archives.R
|
||||||
|
|
||||||
|
#' @import parallel
|
||||||
.solve_missing_imports <- function(missingImports, installOpts = list(Ncpus = parallel::detectCores())) {
|
.solve_missing_imports <- function(missingImports, installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
importsFormat <- data.frame(list(
|
importsFormat <- data.frame(list(
|
||||||
package_name = unlist(lapply(missingImports$package, format_str, width = 35)),
|
package_name = unlist(lapply(missingImports$package, format_str, width = 35)),
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
if ("Update to latest CRAN version" %in% actions) {
|
if ("Update to latest CRAN version" %in% actions) {
|
||||||
newPackages <- which("Update to latest CRAN version" == actions)
|
newPackages <- which("Update to latest CRAN version" == actions)
|
||||||
newPackages <- unique(missingImports[newPackages,"package"])
|
newPackages <- unique(missingImports[newPackages,"package"])
|
||||||
do.call(install.packages, c(list(newPackages), installOpts))
|
do.call(utils::install.packages, c(list(newPackages), installOpts))
|
||||||
cat("\n")
|
cat("\n")
|
||||||
cat("One or more new packages were installed. Please re-run the command.\n")
|
cat("One or more new packages were installed. Please re-run the command.\n")
|
||||||
stop_quietly()
|
stop_quietly()
|
||||||
@@ -67,6 +68,25 @@
|
|||||||
do.call(rbind, fixedImports)
|
do.call(rbind, fixedImports)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.install_order <- function(dependsTree) {
|
||||||
|
dependsPackages <- lapply(unique(dependsTree$package), function(p) {
|
||||||
|
package <- dependsTree[dependsTree$package == p,]
|
||||||
|
package <- package[package$generation == max(package$generation),]
|
||||||
|
package <- package[1,c("package", "version", "generation")]
|
||||||
|
return(package)
|
||||||
|
})
|
||||||
|
dependsPackages <- do.call(rbind, dependsPackages)
|
||||||
|
|
||||||
|
dependsOrder <- sort(dependsPackages$generation, index.return = T, decreasing = T)$ix
|
||||||
|
dependsOrder <- dependsPackages[dependsOrder,]
|
||||||
|
|
||||||
|
installOrder <- lapply(unique(dependsOrder$generation), function(g) {
|
||||||
|
return(dependsOrder[dependsOrder$generation == g,"package"])
|
||||||
|
})
|
||||||
|
|
||||||
|
return(installOrder)
|
||||||
|
}
|
||||||
|
|
||||||
#' Compile a structure containing the current state of the imports for the
|
#' Compile a structure containing the current state of the imports for the
|
||||||
#' project.
|
#' project.
|
||||||
#'
|
#'
|
||||||
@@ -86,7 +106,12 @@ compile_imports <- function(custom_sources = empty_sources(), installOpts = list
|
|||||||
)
|
)
|
||||||
|
|
||||||
imports <- list_imports()
|
imports <- list_imports()
|
||||||
depends <- list_depends(unique(imports$package))
|
dependsTree <- list_depends(unique(imports$package), TRUE)
|
||||||
|
|
||||||
|
depends <- dependsTree[,c("package", "version")]
|
||||||
|
depends <- unique(depends)
|
||||||
|
depends <- depends[sort(depends$package, index.return = TRUE)$ix,]
|
||||||
|
row.names(depends) <- 1:nrow(depends)
|
||||||
|
|
||||||
cranPackages <- fetch_available_packages()
|
cranPackages <- fetch_available_packages()
|
||||||
archivePackages <- fetch_available_archives()
|
archivePackages <- fetch_available_archives()
|
||||||
@@ -152,11 +177,13 @@ compile_imports <- function(custom_sources = empty_sources(), installOpts = list
|
|||||||
coreDeps <- dependsSources[dependsSources$in_core,]
|
coreDeps <- dependsSources[dependsSources$in_core,]
|
||||||
directDeps <- dependsSources[dependsSources$is_direct & !dependsSources$in_core & !missingImports,]
|
directDeps <- dependsSources[dependsSources$is_direct & !dependsSources$in_core & !missingImports,]
|
||||||
indirectDeps <- dependsSources[!dependsSources$is_direct & !dependsSources$in_core & !missingImports,]
|
indirectDeps <- dependsSources[!dependsSources$is_direct & !dependsSources$in_core & !missingImports,]
|
||||||
|
installOrder <- .install_order(dependsTree[!(dependsTree$package %in% coreDeps$package),])
|
||||||
|
|
||||||
return(list(
|
return(list(
|
||||||
core_depends = coreDeps[,c("package", "version")],
|
core_depends = coreDeps[,c("package", "version")],
|
||||||
direct_depends = directDeps[,c("package", "version")],
|
direct_depends = directDeps[,c("package", "version")],
|
||||||
indirect_depends = indirectDeps[,c("package", "version")],
|
indirect_depends = indirectDeps[,c("package", "version")],
|
||||||
custom_sources = customImports
|
custom_sources = customImports,
|
||||||
|
install_order = installOrder
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!file.exists(dist_fn)) {
|
if (!file.exists(dist_fn)) {
|
||||||
download.file(sprintf("%s/src/contrib/Meta/archive.rds", get_cran_repo()), dist_fn)
|
utils::download.file(sprintf("%s/src/contrib/Meta/archive.rds", get_cran_repo()), dist_fn)
|
||||||
.process_dist_archive(dist_fn, fn)
|
.process_dist_archive(dist_fn, fn)
|
||||||
}
|
}
|
||||||
con <- gzfile(fn, "rb")
|
con <- gzfile(fn, "rb")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!file.exists(fn)) {
|
if (!file.exists(fn)) {
|
||||||
download.file(sprintf("%s/src/contrib/PACKAGES.rds", get_cran_repo()), fn)
|
utils::download.file(sprintf("%s/src/contrib/PACKAGES.rds", get_cran_repo()), fn)
|
||||||
}
|
}
|
||||||
con <- gzfile(fn, "rb")
|
con <- gzfile(fn, "rb")
|
||||||
on.exit(close(con), add = TRUE)
|
on.exit(close(con), add = TRUE)
|
||||||
|
|||||||
8
R/init.R
Normal file
8
R/init.R
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
# init <- function(reInit = FALSE) {
|
||||||
|
# if (file.exists("pacman.lock") && !reInit) {
|
||||||
|
# return()
|
||||||
|
# }
|
||||||
|
# snapshot <- .makeSnapshot()
|
||||||
|
# jsonlite::write_json(snapshot, path = "pacman.lock", pretty = TRUE)
|
||||||
|
# }
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#' packages
|
#' packages
|
||||||
#'
|
#'
|
||||||
#' @return invisible return of the current snapshot
|
#' @return invisible return of the current snapshot
|
||||||
|
#' @import parallel remotes
|
||||||
#' @export
|
#' @export
|
||||||
install_package_source <- function(packageSource, installOpts = list(Ncpus = parallel::detectCores())) {
|
install_package_source <- function(packageSource, installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
packageRemote <- switch(
|
packageRemote <- switch(
|
||||||
@@ -18,19 +19,13 @@ install_package_source <- function(packageSource, installOpts = list(Ncpus = par
|
|||||||
Bioconductor = remotes:::bio_remote(packageSource$src)
|
Bioconductor = remotes:::bio_remote(packageSource$src)
|
||||||
)
|
)
|
||||||
|
|
||||||
print(dput(c(list(packageRemote), dependencies = NA, upgrade = "default",
|
|
||||||
force = FALSE, quiet = FALSE, build = TRUE, build_opts = c("--no-resave-data", "--no-manual",
|
|
||||||
"--no-build-vignettes"),
|
|
||||||
build_manual = FALSE, build_vignettes = FALSE,
|
|
||||||
repos = getOption("repos"), type = getOption("pkgType"), installOpts)))
|
|
||||||
|
|
||||||
remotes:::install_remote(packageRemote, dependencies = NA, upgrade = "default",
|
remotes:::install_remote(packageRemote, dependencies = NA, upgrade = "default",
|
||||||
force = FALSE, quiet = FALSE, build = TRUE, build_opts = c("--no-resave-data", "--no-manual",
|
force = FALSE, quiet = FALSE, build = TRUE, build_opts = c("--no-resave-data", "--no-manual",
|
||||||
"--no-build-vignettes"),
|
"--no-build-vignettes"),
|
||||||
build_manual = FALSE, build_vignettes = FALSE,
|
build_manual = FALSE, build_vignettes = FALSE,
|
||||||
repos = getOption("repos"), type = getOption("pkgType"), installOpts)
|
repos = getOption("repos"), type = getOption("pkgType"), installOpts)
|
||||||
|
|
||||||
allPackages <- installed.packages()
|
allPackages <- utils::installed.packages()
|
||||||
allPackages <- as.data.frame(allPackages)
|
allPackages <- as.data.frame(allPackages)
|
||||||
allPackages <- allPackages[allPackages$Package %in% packageSource$package,]
|
allPackages <- allPackages[allPackages$Package %in% packageSource$package,]
|
||||||
package <- data.frame(
|
package <- data.frame(
|
||||||
|
|||||||
7
R/isolate.R
Normal file
7
R/isolate.R
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
#' Isolates the current environment to only the pacman library
|
||||||
|
#'
|
||||||
|
#' @export
|
||||||
|
isolate <- function() {
|
||||||
|
environment(.libPaths)$.lib.loc <- c(file.path(getwd(), ".pacman/library"), .Library)
|
||||||
|
}
|
||||||
@@ -1,15 +1,33 @@
|
|||||||
|
|
||||||
.list_depends <- function(packages, gen) {
|
.list_depends <- function(packages, gen) {
|
||||||
allPackages <- installed.packages()
|
allPackages <- utils::installed.packages()
|
||||||
allPackages <- as.data.frame(allPackages)
|
allPackages <- as.data.frame(allPackages)
|
||||||
packages <- allPackages[allPackages$Package %in% packages,]
|
packages <- allPackages[allPackages$Package %in% packages,]
|
||||||
packages <- packages[,c("Package", "Version", "Imports")]
|
packages <- packages[,c("Package", "Version", "Imports", "Depends", "LinkingTo")]
|
||||||
|
|
||||||
packages$Imports <- gsub(packages$Imports, pattern = "\n", replacement = " ")
|
packages$Imports <- gsub(packages$Imports, pattern = "\n", replacement = " ")
|
||||||
packages$Imports <- strsplit(packages$Imports, ", ")
|
packages$Imports <- strsplit(packages$Imports, ", ")
|
||||||
|
#packages$Imports[is.na(packages$Imports)] <- list(NULL)
|
||||||
|
|
||||||
|
packages$LinkingTo <- gsub(packages$LinkingTo, pattern = "\n", replacement = " ")
|
||||||
|
packages$LinkingTo <- strsplit(packages$LinkingTo, ", ")
|
||||||
|
packages$LinkingTo[is.na(packages$LinkingTo)] <- list(NULL)
|
||||||
|
|
||||||
|
packages$Depends <- gsub(packages$Depends, pattern = "R \\([^\\)]+\\)", replacement = "")
|
||||||
|
packages$Depends <- gsub(packages$Depends, pattern = "^, ", replacement = "")
|
||||||
|
packages$Depends <- gsub(packages$Depends, pattern = ", *$", replacement = "")
|
||||||
|
packages$Depends[nchar(packages$Depends) == 0] <- NA
|
||||||
|
packages$Depends <- gsub(packages$Depends, pattern = "\n", replacement = " ")
|
||||||
|
packages$Depends <- strsplit(packages$Depends, ", ")
|
||||||
|
packages$Depends[is.na(packages$Depends)] <- list(NULL)
|
||||||
|
|
||||||
|
nDepends <- lengths(packages$Imports) + lengths(packages$LinkingTo) + lengths(packages$Depends)
|
||||||
packages <- data.frame(
|
packages <- data.frame(
|
||||||
package = rep(packages$Package, lengths(packages$Imports)),
|
package = rep(packages$Package, nDepends),
|
||||||
version = rep(packages$Version, lengths(packages$Imports)),
|
version = rep(packages$Version, nDepends),
|
||||||
imports = unlist(packages$Imports)
|
imports = unlist(lapply(seq_along(packages$Package), function(idx) {
|
||||||
|
c(packages$Imports[[idx]], packages$LinkingTo[[idx]], packages$Depends[[idx]])
|
||||||
|
}))
|
||||||
)
|
)
|
||||||
packages$min_version <- gsub(packages$imports, pattern = "[^ ]*( \\([=> ]*([^)]+)\\))?", replacement = "\\2")
|
packages$min_version <- gsub(packages$imports, pattern = "[^ ]*( \\([=> ]*([^)]+)\\))?", replacement = "\\2")
|
||||||
packages$min_version = ifelse(nchar(packages$min_version) == 0, NA_character_, packages$min_version)
|
packages$min_version = ifelse(nchar(packages$min_version) == 0, NA_character_, packages$min_version)
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
#' versions.
|
#' versions.
|
||||||
#'
|
#'
|
||||||
#' @return A data frame with the directly required packages
|
#' @return A data frame with the directly required packages
|
||||||
|
#' @import renv
|
||||||
#' @export
|
#' @export
|
||||||
list_imports <- function() {
|
list_imports <- function() {
|
||||||
packages <- renv::dependencies(progress = FALSE)$Package
|
packages <- renv::dependencies(progress = FALSE)$Package
|
||||||
packages <- sort(unique(packages))
|
packages <- sort(unique(packages))
|
||||||
allPackages <- installed.packages()
|
allPackages <- utils::installed.packages()
|
||||||
allPackages <- as.data.frame(allPackages)
|
allPackages <- as.data.frame(allPackages)
|
||||||
allPackages <- allPackages[allPackages$Package %in% packages,]
|
allPackages <- allPackages[allPackages$Package %in% packages,]
|
||||||
packages <- data.frame(
|
packages <- data.frame(
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#' @return invisible NULL on cancel
|
#' @return invisible NULL on cancel
|
||||||
#' @return List containing the type of the source, the source URI and an
|
#' @return List containing the type of the source, the source URI and an
|
||||||
#' optional reference
|
#' optional reference
|
||||||
|
#' @import remotes
|
||||||
request_package_source <- function(package) {
|
request_package_source <- function(package) {
|
||||||
source <- NULL
|
source <- NULL
|
||||||
repeat {
|
repeat {
|
||||||
|
|||||||
100
R/restore.R
Normal file
100
R/restore.R
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Requires activate.R
|
||||||
|
|
||||||
|
.install_if_missing <- function(packages, installOpts, lockVersion = TRUE, parallel = FALSE) {
|
||||||
|
installedPackages <- as.data.frame(utils::installed.packages()[,c("Package","Version")])
|
||||||
|
if (lockVersion) {
|
||||||
|
packageMatch <- merge(
|
||||||
|
packages,
|
||||||
|
cbind(installedPackages, matched = TRUE),
|
||||||
|
by.x = c("package", "version"),
|
||||||
|
by.y = c("Package", "Version"),
|
||||||
|
all.x = TRUE
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
packageMatch <- merge(
|
||||||
|
packages,
|
||||||
|
cbind(installedPackages, matched = TRUE),
|
||||||
|
by.x = "package", by.y = "Package",
|
||||||
|
all.x = TRUE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
missingPackages <- packageMatch[is.na(packageMatch$matched),]
|
||||||
|
if (parallel) {
|
||||||
|
cl <- parallel::makeCluster(parallel::detectCores() - 1)
|
||||||
|
parallel::parLapply(cl, seq_along(missingPackages$package), function(ridx, missingPackages, installOpts, repos) {
|
||||||
|
options(repos = repos)
|
||||||
|
do.call(remotes::install_version, c(
|
||||||
|
missingPackages$package[[ridx]],
|
||||||
|
missingPackages$version[[ridx]],
|
||||||
|
upgrade = "never",
|
||||||
|
dependencies = FALSE,
|
||||||
|
installOpts
|
||||||
|
))
|
||||||
|
}, missingPackages, installOpts, getOption("repos"))
|
||||||
|
parallel::stopCluster(cl)
|
||||||
|
} else {
|
||||||
|
lapply(seq_along(missingPackages$package), function(ridx) {
|
||||||
|
cat("Installing", missingPackages$package[[ridx]], "now...\n")
|
||||||
|
do.call(remotes::install_version, c(
|
||||||
|
missingPackages$package[[ridx]],
|
||||||
|
missingPackages$version[[ridx]],
|
||||||
|
upgrade = "never",
|
||||||
|
dependencies = FALSE,
|
||||||
|
installOpts
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#' Restores the project from a pacman snapshot file. Installs any missing
|
||||||
|
#' packages. This can be done into the user library or the packman library
|
||||||
|
#' (see totalIsolation)
|
||||||
|
#'
|
||||||
|
#' @param totalIsolation boolean Only refer to the pacman library, do not use
|
||||||
|
#' any user library paths
|
||||||
|
#' @param installOpts list Settings to be passed to install.packages etc.
|
||||||
|
#' Defaults to installing with multiple cores.
|
||||||
|
#'
|
||||||
|
#' @import parallel
|
||||||
|
#' @export
|
||||||
|
restore <- function(totalIsolation = FALSE, installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
|
activate(totalIsolation)
|
||||||
|
|
||||||
|
get_cran_repo()
|
||||||
|
|
||||||
|
lastSnapshot <- snapshot_latest()
|
||||||
|
|
||||||
|
requiredPackages <- lastSnapshot$packages
|
||||||
|
if (is.null(requiredPackages$direct)) {
|
||||||
|
requiredPackages$direct <- list()
|
||||||
|
}
|
||||||
|
if (is.null(requiredPackages$indirect)) {
|
||||||
|
requiredPackages$indirect <- list()
|
||||||
|
}
|
||||||
|
if (is.null(requiredPackages$custom)) {
|
||||||
|
requiredPackages$custom <- list()
|
||||||
|
}
|
||||||
|
simplePackages <- as.data.frame(apply(rbind(
|
||||||
|
do.call(rbind, requiredPackages$direct),
|
||||||
|
do.call(rbind, requiredPackages$indirect)
|
||||||
|
), 2, unlist))
|
||||||
|
customPackages <- as.data.frame(do.call(rbind, requiredPackages$custom))
|
||||||
|
|
||||||
|
# corePackages <- as.data.frame(apply(do.call(rbind, lastSnapshot$packages$core), 2, unlist))
|
||||||
|
|
||||||
|
installGroups <- 1:length(lastSnapshot$packages$install_order)
|
||||||
|
for(grpIdx in installGroups) {
|
||||||
|
installGroup <- lastSnapshot$packages$install_order[[grpIdx]]
|
||||||
|
|
||||||
|
groupCustomPackages <- customPackages[customPackages$package %in% installGroup,]
|
||||||
|
lapply(seq_along(groupCustomPackages$package), function(pkgIdx) {
|
||||||
|
install_package_source(groupCustomPackages[pkgIdx,], installOpts)
|
||||||
|
})
|
||||||
|
|
||||||
|
groupPackages <- simplePackages[simplePackages$package %in% installGroup,]
|
||||||
|
groupPackages <- groupPackages[!(groupPackages$package %in% groupCustomPackages$package),]
|
||||||
|
if (nrow(groupPackages) > 0) {
|
||||||
|
.install_if_missing(groupPackages, installOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,15 +7,14 @@
|
|||||||
#' packages
|
#' packages
|
||||||
#'
|
#'
|
||||||
#' @return invisible return of the current snapshot
|
#' @return invisible return of the current snapshot
|
||||||
|
#' @import parallel jsonlite
|
||||||
#' @export
|
#' @export
|
||||||
snapshot_save <- function(installOpts = list(Ncpus = parallel::detectCores()), snapshot = NULL) {
|
snapshot <- function(installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
if (is.null(snapshot)) {
|
snapshot <- snapshot_create(installOpts)
|
||||||
snapshot <- snapshot_create(installOpts)
|
|
||||||
}
|
|
||||||
history <- snapshot_history()
|
history <- snapshot_history()
|
||||||
history <- c(list(snapshot), history)
|
history <- c(list(snapshot), history)
|
||||||
snapshot$history <- history
|
snapshot$history <- history
|
||||||
jsonlite::write_json(snapshot, "pacman.lock")
|
jsonlite::write_json(snapshot, "pacman.lock", pretty = TRUE, auto_unbox = TRUE)
|
||||||
snapshot$history <- NULL
|
snapshot$history <- NULL
|
||||||
return(snapshot)
|
return(snapshot)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#' packages
|
#' packages
|
||||||
#'
|
#'
|
||||||
#' @return A list containing the current state of the project packages
|
#' @return A list containing the current state of the project packages
|
||||||
|
#' @import parallel
|
||||||
#' @export
|
#' @export
|
||||||
snapshot_create <- function(installOpts = list(Ncpus = parallel::detectCores())) {
|
snapshot_create <- function(installOpts = list(Ncpus = parallel::detectCores())) {
|
||||||
lastSnapshot <- snapshot_latest()
|
lastSnapshot <- snapshot_latest()
|
||||||
@@ -16,7 +17,7 @@ snapshot_create <- function(installOpts = list(Ncpus = parallel::detectCores()))
|
|||||||
customSources <- rbind(customSources, lastSnapshot$packages$custom)
|
customSources <- rbind(customSources, lastSnapshot$packages$custom)
|
||||||
}
|
}
|
||||||
packages <- compile_imports(customSources, installOpts)
|
packages <- compile_imports(customSources, installOpts)
|
||||||
names(packages) <- c("core", "direct", "indirect", "custom")
|
names(packages) <- c("core", "direct", "indirect", "custom", "install_order")
|
||||||
if (nrow(packages$core) == 0) {
|
if (nrow(packages$core) == 0) {
|
||||||
packages$core <- NULL
|
packages$core <- NULL
|
||||||
}
|
}
|
||||||
@@ -30,9 +31,6 @@ snapshot_create <- function(installOpts = list(Ncpus = parallel::detectCores()))
|
|||||||
packages$custom <- NULL
|
packages$custom <- NULL
|
||||||
}
|
}
|
||||||
description <- trimws(readline("Please provide a description for the snapshot (optional): "))
|
description <- trimws(readline("Please provide a description for the snapshot (optional): "))
|
||||||
if (nchar(description) == 0) {
|
|
||||||
description <- NULL
|
|
||||||
}
|
|
||||||
return(list(
|
return(list(
|
||||||
timestamp = Sys.time(),
|
timestamp = Sys.time(),
|
||||||
description = description,
|
description = description,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#' Load the existing snapshot history of the project
|
#' Load the existing snapshot history of the project
|
||||||
#'
|
#'
|
||||||
#' @return A list containing the previous snapshots
|
#' @return A list containing the previous snapshots
|
||||||
|
#' @import jsonlite
|
||||||
#' @export
|
#' @export
|
||||||
snapshot_history <- function() {
|
snapshot_history <- function() {
|
||||||
if (!file.exists("pacman.lock")) {
|
if (!file.exists("pacman.lock")) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#' Load the latest snapshot state from the lock file
|
#' Load the latest snapshot state from the lock file
|
||||||
#'
|
#'
|
||||||
#' @return A list containing the last saved snapshot of the project state
|
#' @return A list containing the last saved snapshot of the project state
|
||||||
|
#' @import jsonlite
|
||||||
#' @export
|
#' @export
|
||||||
snapshot_latest <- function() {
|
snapshot_latest <- function() {
|
||||||
if (!file.exists("pacman.lock")) {
|
if (!file.exists("pacman.lock")) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ check_pacman_dir <- function() {
|
|||||||
get_cran_repo <- function() {
|
get_cran_repo <- function() {
|
||||||
repo <- getOption("repos")[[1]]
|
repo <- getOption("repos")[[1]]
|
||||||
if (repo == "@CRAN@") {
|
if (repo == "@CRAN@") {
|
||||||
chooseCRANmirror()
|
utils::chooseCRANmirror()
|
||||||
repo <- getOption("repos")[[1]]
|
repo <- getOption("repos")[[1]]
|
||||||
}
|
}
|
||||||
repo
|
repo
|
||||||
@@ -84,6 +84,7 @@ empty_sources <- function() {
|
|||||||
#' @param str A character vector of strings to format
|
#' @param str A character vector of strings to format
|
||||||
#' @param width An optional width of the string to pad to
|
#' @param width An optional width of the string to pad to
|
||||||
#' @param justify "left" or "right" justification
|
#' @param justify "left" or "right" justification
|
||||||
|
#' @param ... formattable objects
|
||||||
#'
|
#'
|
||||||
#' @return A formatted (padded) character vector
|
#' @return A formatted (padded) character vector
|
||||||
format_str <- function (str, width = NULL, justify = "left", ...) {
|
format_str <- function (str, width = NULL, justify = "left", ...) {
|
||||||
@@ -99,6 +100,8 @@ format_str <- function (str, width = NULL, justify = "left", ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#' Calls stop() returning to the top level but masks the message
|
#' Calls stop() returning to the top level but masks the message
|
||||||
|
#'
|
||||||
|
#' @param ... ignored
|
||||||
stop_quietly <- function(...) {
|
stop_quietly <- function(...) {
|
||||||
blankMsg <- sprintf("\r%s\r", paste(rep(" ", getOption("width") - 1L), collapse = " "))
|
blankMsg <- sprintf("\r%s\r", paste(rep(" ", getOption("width") - 1L), collapse = " "))
|
||||||
stop(simpleError(blankMsg))
|
stop(simpleError(blankMsg))
|
||||||
|
|||||||
17
man/activate.Rd
Normal file
17
man/activate.Rd
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/activate.R
|
||||||
|
\name{activate}
|
||||||
|
\alias{activate}
|
||||||
|
\title{Adds the pacman library path to the .libPaths variable, either as an extra
|
||||||
|
library or as the only library}
|
||||||
|
\usage{
|
||||||
|
activate(totalIsolation = FALSE)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{totalIsolation}{boolean Only refer to the pacman library, do not use
|
||||||
|
any user library paths}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Adds the pacman library path to the .libPaths variable, either as an extra
|
||||||
|
library or as the only library
|
||||||
|
}
|
||||||
21
man/add_package.Rd
Normal file
21
man/add_package.Rd
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/add_package.R
|
||||||
|
\name{add_package}
|
||||||
|
\alias{add_package}
|
||||||
|
\title{Add a package to the project.}
|
||||||
|
\usage{
|
||||||
|
add_package(
|
||||||
|
packageName = NULL,
|
||||||
|
installOpts = list(Ncpus = parallel::detectCores())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{packageName}{boolean Only refer to the pacman library, do not use
|
||||||
|
any user library paths}
|
||||||
|
|
||||||
|
\item{installOpts}{boolean Only refer to the pacman library, do not use
|
||||||
|
any user library paths}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Add a package to the project.
|
||||||
|
}
|
||||||
28
man/compile_imports.Rd
Normal file
28
man/compile_imports.Rd
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/compile_imports.R
|
||||||
|
\name{compile_imports}
|
||||||
|
\alias{compile_imports}
|
||||||
|
\title{Compile a structure containing the current state of the imports for the
|
||||||
|
project.}
|
||||||
|
\usage{
|
||||||
|
compile_imports(
|
||||||
|
custom_sources = empty_sources(),
|
||||||
|
installOpts = list(Ncpus = parallel::detectCores())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{custom_sources}{datatable A table containing any previously known
|
||||||
|
custom data sources}
|
||||||
|
|
||||||
|
\item{installOpts}{list Installer options for use when installing CRAN
|
||||||
|
packages}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A list containing R base imports, directly imported/used packages,
|
||||||
|
indirectly imported/used packages (aka dependencies) and any custom
|
||||||
|
import sources.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Compile a structure containing the current state of the imports for the
|
||||||
|
project.
|
||||||
|
}
|
||||||
14
man/empty_sources.Rd
Normal file
14
man/empty_sources.Rd
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/utils.R
|
||||||
|
\name{empty_sources}
|
||||||
|
\alias{empty_sources}
|
||||||
|
\title{Structure of the imports data table}
|
||||||
|
\usage{
|
||||||
|
empty_sources()
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
datatable Empty table with the imports column structure
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Structure of the imports data table
|
||||||
|
}
|
||||||
23
man/format_str.Rd
Normal file
23
man/format_str.Rd
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/utils.R
|
||||||
|
\name{format_str}
|
||||||
|
\alias{format_str}
|
||||||
|
\title{Re-formats a string to fix the width by padding with spaces}
|
||||||
|
\usage{
|
||||||
|
format_str(str, width = NULL, justify = "left", ...)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{str}{A character vector of strings to format}
|
||||||
|
|
||||||
|
\item{width}{An optional width of the string to pad to}
|
||||||
|
|
||||||
|
\item{justify}{"left" or "right" justification}
|
||||||
|
|
||||||
|
\item{...}{formattable objects}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A formatted (padded) character vector
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Re-formats a string to fix the width by padding with spaces
|
||||||
|
}
|
||||||
23
man/install_package_source.Rd
Normal file
23
man/install_package_source.Rd
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/install_package_source.R
|
||||||
|
\name{install_package_source}
|
||||||
|
\alias{install_package_source}
|
||||||
|
\title{Installs a package from a custom source}
|
||||||
|
\usage{
|
||||||
|
install_package_source(
|
||||||
|
packageSource,
|
||||||
|
installOpts = list(Ncpus = parallel::detectCores())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{packageSource}{The custom source information for a package}
|
||||||
|
|
||||||
|
\item{installOpts}{list Installer options for use when installing CRAN
|
||||||
|
packages}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
invisible return of the current snapshot
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Installs a package from a custom source
|
||||||
|
}
|
||||||
11
man/isolate.Rd
Normal file
11
man/isolate.Rd
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/isolate.R
|
||||||
|
\name{isolate}
|
||||||
|
\alias{isolate}
|
||||||
|
\title{Isolates the current environment to only the pacman library}
|
||||||
|
\usage{
|
||||||
|
isolate()
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Isolates the current environment to only the pacman library
|
||||||
|
}
|
||||||
25
man/restore.Rd
Normal file
25
man/restore.Rd
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/restore.R
|
||||||
|
\name{restore}
|
||||||
|
\alias{restore}
|
||||||
|
\title{Restores the project from a pacman snapshot file. Installs any missing
|
||||||
|
packages. This can be done into the user library or the packman library
|
||||||
|
(see totalIsolation)}
|
||||||
|
\usage{
|
||||||
|
restore(
|
||||||
|
totalIsolation = FALSE,
|
||||||
|
installOpts = list(Ncpus = parallel::detectCores())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{totalIsolation}{boolean Only refer to the pacman library, do not use
|
||||||
|
any user library paths}
|
||||||
|
|
||||||
|
\item{installOpts}{list Settings to be passed to install.packages etc.
|
||||||
|
Defaults to installing with multiple cores.}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Restores the project from a pacman snapshot file. Installs any missing
|
||||||
|
packages. This can be done into the user library or the packman library
|
||||||
|
(see totalIsolation)
|
||||||
|
}
|
||||||
18
man/snapshot.Rd
Normal file
18
man/snapshot.Rd
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/snapshot.R
|
||||||
|
\name{snapshot}
|
||||||
|
\alias{snapshot}
|
||||||
|
\title{Save the current state of the project into the lock file as a snapshot}
|
||||||
|
\usage{
|
||||||
|
snapshot(installOpts = list(Ncpus = parallel::detectCores()))
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{installOpts}{list Installer options for use when installing CRAN
|
||||||
|
packages}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
invisible return of the current snapshot
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Save the current state of the project into the lock file as a snapshot
|
||||||
|
}
|
||||||
18
man/snapshot_create.Rd
Normal file
18
man/snapshot_create.Rd
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/snapshot_create.R
|
||||||
|
\name{snapshot_create}
|
||||||
|
\alias{snapshot_create}
|
||||||
|
\title{Create a snapshot of the project packages. Does not save the snapshot (see snapshot_save)}
|
||||||
|
\usage{
|
||||||
|
snapshot_create(installOpts = list(Ncpus = parallel::detectCores()))
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{installOpts}{list Installer options for use when installing CRAN
|
||||||
|
packages}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A list containing the current state of the project packages
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Create a snapshot of the project packages. Does not save the snapshot (see snapshot_save)
|
||||||
|
}
|
||||||
14
man/snapshot_history.Rd
Normal file
14
man/snapshot_history.Rd
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/snapshot_history.R
|
||||||
|
\name{snapshot_history}
|
||||||
|
\alias{snapshot_history}
|
||||||
|
\title{Load the existing snapshot history of the project}
|
||||||
|
\usage{
|
||||||
|
snapshot_history()
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A list containing the previous snapshots
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Load the existing snapshot history of the project
|
||||||
|
}
|
||||||
14
man/snapshot_latest.Rd
Normal file
14
man/snapshot_latest.Rd
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/snapshot_latest.R
|
||||||
|
\name{snapshot_latest}
|
||||||
|
\alias{snapshot_latest}
|
||||||
|
\title{Load the latest snapshot state from the lock file}
|
||||||
|
\usage{
|
||||||
|
snapshot_latest()
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A list containing the last saved snapshot of the project state
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Load the latest snapshot state from the lock file
|
||||||
|
}
|
||||||
14
man/stop_quietly.Rd
Normal file
14
man/stop_quietly.Rd
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/utils.R
|
||||||
|
\name{stop_quietly}
|
||||||
|
\alias{stop_quietly}
|
||||||
|
\title{Calls stop() returning to the top level but masks the message}
|
||||||
|
\usage{
|
||||||
|
stop_quietly(...)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{...}{ignored}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Calls stop() returning to the top level but masks the message
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user