library(pacs)
library(withr)
library(remotes)

pacs: A set of tools that make life easier for developers and maintainers of R packages.

  • Validating the library, packages and renv lock files.
  • Exploring the complexity of a specific package, like evaluating its size in bytes with dependencies.
  • The shiny app complexity could be explored too.
  • Assessing the life duration of a specific package version.
  • Checking a CRAN package check page status for any errors and warnings.
  • Retrieving a DESCRIPTION or NAMESPACE file for any package version.
  • Comparing DESCRIPTION or NAMESPACE files between different package versions.
  • Getting a list of all releases for a specific package.
  • The Bioconductor is partly supported.

Functions Reference

Hints

Hint0: An Internet connection is required to take full advantage of most features.

Hint1: Almost all calls that requiring an Internet connection are cached (for 30 minutes) by the memoise package, so the second invocation of the same command (and arguments) is immediate. Restart the R session if you want to clear cached data.

Hint2: Version variable is mostly a minimal required i.e. max(version1, version2 , …).

Hint3: When working with many packages, global functions are recommended, which retrieve data for many packages at once. An example will be the usage of pacs::checked_packages() over pacs::pac_checkpage (or pacs::pac_checkred). Another example will be the usage of utils::available.packages over pacs::pac_last. Finally, the most important one will be pacs::lib_validate over pacs::pac_validate and pacs::pac_checkred and others.

Hint4: Character string “all” is shorthand for the c("Depends", "Imports", "LinkingTo", "Suggests", "Enhances") vector, character string “most” for the same vector without “Enhances”, character string “strong” (default setup) for the first three elements of that vector.

Hint5: Use parallel::mclapply (Linux and Mac) or parallel::parLapply (Windows, Linux and Mac) to speed up loop calculations. Nevertheless, under parallel::mclapply, computation results are NOT cached with memoise package. Warning: Parallel computations might be unstable.

Hint6: withr and remotes packages are a valuable addition.

Validate the library

pacs::lib_validate()

This procedure will be crucial for R developers, clearly showing the possible broken packages inside the local library.
We could assess which packages require versions to update.

Default validation of the library with the pacs::lib_validate function.
The field argument is equal to c("Depends", "Imports", "LinkingTo") by default as these are the dependencies installed when the install.packages function is used.

The full library validation requires activation of two additional arguments, lifeduration and checkred. Additional arguments are by default turned off as they are time-consuming, for lifeduration assessment might take even a few minutes for bigger libraries.

Assessment of status on CRAN check pages takes only a few additional seconds, even for all R CRAN packages. pacs::checked_packages() is used to gather all package check statuses for all CRAN servers.

pacs::lib_validate(checkred = list(scope = c("ERROR", "FAIL")))

When lifeduration is triggered then assessment might take even few minutes.

pacs::lib_validate(lifeduration = TRUE, 
                   checkred = list(scope = c("ERROR", "FAIL")))

Not only scope field inside checkred list could be updated, to remind any of c("ERROR", "FAIL", "WARN", "NOTE"). We could specify flavors field inside the checkred list argument and narrow the tested machines. The full list of CRAN servers (flavors) might be get with pacs::cran_flavors()$Flavor.

flavs <- pacs::cran_flavors()$Flavor[1:2]
pacs::lib_validate(checkred = list(scope = c("ERROR", "FAIL"), 
                   flavors = flavs))

Investigate by filtering

Packages are not installed (and should be) or have too low version:

lib <- pacs::lib_validate(checkred = list(scope = c("ERROR", "FAIL")))
# not installed (and should be) or too low version
lib[(lib$version_status == -1), ]
# not installed (and should be)
lib[is.na(lib$Version.have), ]
# too low version
lib[(!is.na(lib$Version.have)) & (lib$version_status == -1), ]

Packages which have at least one CRAN server which ERROR or FAIL:

red <- lib[(!is.na(lib$checkred)) & (lib$checkred == TRUE), ]
nrow(red)
head(red)

Packages that are not a dependency (default c("Depends", "Imports", "LinkingTo")) of any other package:

lib[is.na(lib$Version.expected.min), ]

Non-CRAN packages:

lib[lib$cran == FALSE, ]

Not newest packages:

lib[(!is.na(lib$newest)) & (lib$newest == FALSE), ]

Core idea behind lib_validate

The core idea behind the function comes from proper processing of the installed.packages function result.

# aggregate function is needed as we could have different versions
# installed under different `.libPaths()`.
installed_packages_unique <- stats::aggregate(
  installed.packages()[, c("Version", "Depends", "Imports", "LinkingTo")], 
  list(Package = installed.packages()[, "Package"]), 
  function(x) x[1]
)
# installed_descriptions function transforms direct dependencies DESCRIPTION file fields
# installed_packages_unique[, c("Depends", "Imports", "LinkingTo&q