in R/R/sqlPackage.R [2426:2602]
getDependentPackagesToUninstall <- function(pkgs, installedPackages, dependencies = TRUE, checkReferences = TRUE, verbose = getOption("verbose"))
{
excludeTopMostPackagesDependencies <- function(pkgsToRemove, dependencies, db, basePackages, verbose)
{
# This function remove, from the given packages dependency lists, all the packages which are top most (and their dependencies) which are not explicitly
# stated to be removed
#
prunedDependencies <- dependencies
# If we have the topmost package information, remove, from the dependencies, packages which are marked as topmost
#
if ('Attributes' %in% colnames(db))
{
# Find all the packegs , in the installed packages database, which are explicitly marked as top most
#
topMostInstalledPackages <- db[!is.na(db[,'Attributes']) &
bitwAnd(as.integer(db[,'Attributes']), getPackageTopMostAttributeFlag()) == 1
,, drop = FALSE]
topMostDependencies <- unique(unlist(dependencies, recursive = TRUE, use.names = FALSE))
topMostDependencies <- topMostDependencies[topMostDependencies %in% topMostInstalledPackages[,"Package"]]
if (length(topMostDependencies) != 0)
{
# Exclude, from the top most dependencies the packages which we specifically asked to remove
#
topMostDependencies <- topMostDependencies[!(topMostDependencies %in% pkgsToRemove)]
}
if (length(topMostDependencies) != 0)
{
# Get the top most packages dependencies to ensure they can still work
#
topMostDependencies <- unique(c(unlist(tools::package_dependencies(packages = topMostDependencies,
db = db, recursive = TRUE,
verbose = FALSE), recursive = TRUE, use.names = FALSE),
topMostDependencies))
# Remove the dependencies which are base classes to allow the correct code to use these
#
topMostDependencies <- topMostDependencies[!topMostDependencies %in% basePackages]
}
if (length(topMostDependencies) != 0)
{
skippedDependencies <- character(0)
prunedDependencies <- lapply(X = dependencies,
FUN = function(dependency)
{
skippedDependencies <<- c(skippedDependencies, dependency[dependency %in% topMostDependencies])
dependency[!dependency %in% topMostDependencies]
}
)
if (verbose && length(skippedDependencies) > 0)
{
write(sprintf("%s skipping following top level dependent packages (%s)...", pkgTime(), paste(unique(skippedDependencies), collapse = ', ')), stdout())
}
}
}
prunedDependencies
}
# prune requested packages to exclude base packages
#
basePackages <- installedPackages[installedPackages[,"Priority"] %in% c("base", "recommended"), c("Package", "Priority"), drop = FALSE]$Package
droppedPackages <- pkgs[pkgs %in% basePackages]
if (length(droppedPackages) > 0)
{
warning(sprintf("Skipping base packages (%s)", paste(droppedPackages, collapse = ', ')), call. = FALSE)
}
pkgs <- pkgs[!(pkgs %in% droppedPackages)]
if (length(pkgs) < 1)
{
return (NULL)
}
if (dependencies == FALSE)
{
dependencies = pkgs
}
else
{
# get dependency closure for all given packages
#
if (verbose)
{
write(sprintf("%s Resolving package dependencies for (%s)...", pkgTime(), paste(pkgs, collapse = ', ')), stdout())
}
dependencies <- tools::package_dependencies(packages = pkgs, db = installedPackages, recursive = TRUE, verbose = FALSE)
# Exclude, from the package dependencies, all the packages which are marked as top most and their dependencies
#
dependencies <- excludeTopMostPackagesDependencies(pkgsToRemove = pkgs,
dependencies = dependencies,
db = installedPackages,
basePackages = basePackages,
verbose = verbose)
dependencies <- c(dependencies, pkgs)
# get combined dependency closure w/o base packages
#
dependencies <- unique(unlist(c(dependencies, names(dependencies)), recursive = TRUE, use.names = FALSE))
dependencies <- dependencies[dependencies != "NA" & dependencies != ""]
dependencies <- dependencies[!(dependencies %in% basePackages)]
if (length(dependencies) < 1)
{
return (NULL)
}
}
if (checkReferences == TRUE)
{
# get reverse dependency closure for all given packages
#
if (verbose)
{
write(sprintf("%s Resolving package reverse dependencies for (%s)...", pkgTime(), paste(pkgs, collapse = ', ')), stdout())
}
pkgsToSkip <- list()
for (dependency in dependencies)
{
rdependencies <- tools::package_dependencies(packages = dependency, db = installedPackages, reverse = TRUE, recursive = TRUE, verbose = FALSE)
rdependencies <- unique(unlist(c(rdependencies, names(rdependencies)), recursive = TRUE, use.names = FALSE))
rdependencies <- rdependencies[rdependencies != "NA"]
rdependencies <- rdependencies[rdependencies != ""]
rdependencies <- rdependencies[!(rdependencies %in% dependencies)]
if (length(rdependencies) > 0)
{
if (dependency %in% pkgs)
{
skipMessage <- sprintf("skipping package (%s) being used by packages (%s)...",
dependency, paste(rdependencies, collapse = ', '))
warning(skipMessage, call. = FALSE)
}
else
{
skipMessage <- sprintf("skipping dependent package (%s) being used by packages (%s)...",
dependency, paste(rdependencies, collapse = ', '))
write(skipMessage, stdout())
}
pkgsToSkip <- c(pkgsToSkip, dependency)
}
}
pkgsToSkip <- unique(unlist(pkgsToSkip, recursive = TRUE, use.names = FALSE))
# remove packages which are being referenced by other packages
#
dependencies <- dependencies[!(dependencies %in% pkgsToSkip)]
if (length(dependencies) < 1)
{
return (NULL)
}
}
# get the packages in order of dependency closure
#
dependencies <- unique(dependencies)
pkgsToRemove <- installedPackages[match(dependencies, installedPackages$Package),, drop = FALSE]
pkgsToRemove <- pkgsToRemove[!is.na(pkgsToRemove$Package),]
return (pkgsToRemove)
}