Title: | Installing and Loading R Packages for Reproducible Workflows |
---|---|
Description: | A single key function, 'Require' that makes rerun-tolerant versions of 'install.packages' and `require` for CRAN packages, packages no longer on CRAN (i.e., archived), specific versions of packages, and GitHub packages. This approach is developed to create reproducible workflows that are flexible and fast enough to use while in development stages, while able to build snapshots once a stable package collection is found. As with other functions in a reproducible workflow, this package emphasizes functions that return the same result whether it is the first or subsequent times running the function, with subsequent times being sufficiently fast that they can be run every time without undue waiting burden on the user or developer. |
Authors: | Eliot J B McIntire [aut, cre] , Alex M Chubaty [ctb] , Her Majesty the Queen in Right of Canada, as represented by the Minister of Natural Resources Canada [cph] |
Maintainer: | Eliot J B McIntire <[email protected]> |
License: | GPL-3 |
Version: | 1.0.1.9003 |
Built: | 2024-12-17 18:30:24 UTC |
Source: | https://github.com/PredictiveEcology/Require |
A single key function, 'Require' that makes rerun-tolerant versions of 'install.packages' and 'require' for CRAN packages, packages no longer on CRAN (i.e., archived), specific versions of packages, and GitHub packages. This approach is developed to create reproducible workflows that are flexible and fast enough to use while in development stages, while able to build snapshots once a stable package collection is found. As with other functions in a reproducible workflow, this package emphasizes functions that return the same result whether it is the first or subsequent times running the function, with subsequent times being sufficiently fast that they can be run every time without undue waiting burden on the user or developer.
This is an "all in one" function that will run install.packages
for CRAN
and GitHub https://github.com/ packages and will install specific versions
of each package if versions are specified either via an (in)equality (e.g.,
"glue (>=1.6.2)"
or "glue (==1.6.2)"
for an exact version) or with a
packageVersionFile
. If require = TRUE
, the default, the function will
then run require
on all named packages that satisfy their version
requirements. If packages are already installed (packages
supplied), and
their optional version numbers are satisfied, then the "install" component
will be skipped.
Require( packages, packageVersionFile, libPaths, install_githubArgs = list(), install.packagesArgs = list(INSTALL_opts = "--no-multiarch"), standAlone = getOption("Require.standAlone", FALSE), install = getOption("Require.install", TRUE), require = getOption("Require.require", TRUE), repos = getOption("repos"), purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose", FALSE), type = getOption("pkgType"), upgrade = FALSE, returnDetails = FALSE, ... ) Install( packages, packageVersionFile, libPaths, install_githubArgs = list(), install.packagesArgs = list(INSTALL_opts = "--no-multiarch"), standAlone = getOption("Require.standAlone", FALSE), install = TRUE, repos = getOption("repos"), purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose", FALSE), type = getOption("pkgType"), upgrade = FALSE, ... )
Require( packages, packageVersionFile, libPaths, install_githubArgs = list(), install.packagesArgs = list(INSTALL_opts = "--no-multiarch"), standAlone = getOption("Require.standAlone", FALSE), install = getOption("Require.install", TRUE), require = getOption("Require.require", TRUE), repos = getOption("repos"), purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose", FALSE), type = getOption("pkgType"), upgrade = FALSE, returnDetails = FALSE, ... ) Install( packages, packageVersionFile, libPaths, install_githubArgs = list(), install.packagesArgs = list(INSTALL_opts = "--no-multiarch"), standAlone = getOption("Require.standAlone", FALSE), install = TRUE, repos = getOption("repos"), purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose", FALSE), type = getOption("pkgType"), upgrade = FALSE, ... )
packages |
Either a character vector of packages to install via
|
packageVersionFile |
Character string of a file name or logical. If
|
libPaths |
The library path (or libraries) where all packages should be
installed, and looked for to load (i.e., call |
install_githubArgs |
Deprecated. Values passed here are merged with
|
install.packagesArgs |
List of optional named arguments, passed to
|
standAlone |
Logical. If |
install |
Logical or "force". If |
require |
Logical or character string. If |
repos |
The remote repository (e.g., a CRAN mirror), passed to either
|
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
type |
See |
upgrade |
When |
returnDetails |
Logical. If |
... |
Passed to |
Install
is the same as Require(..., require = FALSE)
, for convenience.
Require
is intended to replace base::require
, thus it returns a
logical, named vector indicating whether the named packages have been loaded.
Because Require
also has the ability to install packages, a return value of
FALSE
does not mean that it did not install correctly; rather, it means it
did not attach with require
, which could be because it did not install
correctly, or also because e.g., require = FALSE
.
standAlone
will either put the Require
d packages and their dependencies
all within the libPaths
(if TRUE
) or if FALSE
will only install
packages and their dependencies that are otherwise not installed in
.libPaths()[1]
, i.e., the current active R package directory. Any packages
or dependencies that are not yet installed will be installed in libPaths
.
Follows remotes::install_github
standard. As with
remotes::install_github
, it is not possible to specify a past version of
a GitHub package unless that version is a tag or the user passes the SHA
that had that package version. Similarly, if a developer does a local
install e.g., via pkgload::install
, of an active project, this package
will not be able know of the GitHub state, and thus pkgSnapshot
will not
be able to recover this state as there is no SHA associated with a local
installation. Use Require
(or remotes::install_github
) to create a
record of the GitHub state.
To build a snapshot of the desired packages and
their versions, first run Require
with all packages, then pkgSnapshot
.
If a libPaths
is used, it must be used in both functions.
This function works best if all required
packages are called within one Require
call, as all dependencies can be
identified together, and all package versions will be addressed (if there
are no conflicts), allowing a call to pkgSnapshot()
to take a snapshot or
"record" of the current collection of packages and versions.
When installing new packages, Require
will put all source and binary files in an R-version specific subfolder of
getOption("Require.cachePkgDir")
whose default is RPackageCache()
,
meaning cache packages locally in a project-independent location, and
will reuse them if needed. To turn off this feature, set
options("Require.cachePkgDir" = FALSE)
.
For advanced use and diagnosis, the user can set verbose = TRUE
or
1
or 2
(or via options("Require.verbose")
). This will attach an
attribute attr(obj, "Require")
to the output of this function.
Maintainer: Eliot J B McIntire [email protected] (ORCID)
Other contributors:
Alex M Chubaty [email protected] (ORCID) [contributor]
Her Majesty the Queen in Right of Canada, as represented by the Minister of Natural Resources Canada [copyright holder]
Useful links:
Report bugs at https://github.com/PredictiveEcology/Require/issues
## Not run: opts <- Require:::.setupExample() library(Require) getCRANrepos(ind = 1) Require("utils") # analogous to require(stats), but it checks for # pkg dependencies, and installs them, if missing # unquoted version Require(c(tools, utils)) if (Require:::.runLongExamples()) { # Install in a new local library (libPaths) tempPkgFolder <- file.path(tempdir(), "Require/Packages") # use standAlone, means it will put it in libPaths, even if it already exists # in another local library (e.g., personal library) Install("crayon", libPaths = tempPkgFolder, standAlone = TRUE) # Mutual dependencies, only installs once -- e.g., cli tempPkgFolder <- file.path(tempdir(), "Require/Packages") Install(c("cli", "R6"), libPaths = tempPkgFolder, standAlone = TRUE) # Mutual dependencies, only installs once -- e.g., rlang tempPkgFolder <- file.path(tempdir(), "Require/Packages") Install(c("rlang", "ellipsis"), libPaths = tempPkgFolder, standAlone = TRUE) ##################################################################################### # Isolated projects -- Use a project folder and pass to libPaths or set .libPaths() # ##################################################################################### # GitHub packages if (requireNamespace("gitcreds", quietly = TRUE)) { #if (is(try(gitcreds::gitcreds_get(), silent = TRUE), "gitcreds")) { ProjectPackageFolder <- file.path(tempdir(), "Require/ProjectA") if (requireNamespace("curl")) { Require("PredictiveEcology/fpCompare@development", libPaths = ProjectPackageFolder, ) } # No install because it is there already Install("PredictiveEcology/fpCompare@development", libPaths = ProjectPackageFolder, ) # the latest version on GitHub ############################################################################ # Mixing and matching GitHub, CRAN, with and without version numbering ############################################################################ pkgs <- c( "remotes (<=2.4.1)", # old version "digest (>= 0.6.28)", # recent version "PredictiveEcology/fpCompare@a0260b8476b06628bba0ae73af3430cce9620ca0" # exact version ) Require::Require(pkgs, libPaths = ProjectPackageFolder) #} } Require:::.cleanup(opts) } ## End(Not run)
## Not run: opts <- Require:::.setupExample() library(Require) getCRANrepos(ind = 1) Require("utils") # analogous to require(stats), but it checks for # pkg dependencies, and installs them, if missing # unquoted version Require(c(tools, utils)) if (Require:::.runLongExamples()) { # Install in a new local library (libPaths) tempPkgFolder <- file.path(tempdir(), "Require/Packages") # use standAlone, means it will put it in libPaths, even if it already exists # in another local library (e.g., personal library) Install("crayon", libPaths = tempPkgFolder, standAlone = TRUE) # Mutual dependencies, only installs once -- e.g., cli tempPkgFolder <- file.path(tempdir(), "Require/Packages") Install(c("cli", "R6"), libPaths = tempPkgFolder, standAlone = TRUE) # Mutual dependencies, only installs once -- e.g., rlang tempPkgFolder <- file.path(tempdir(), "Require/Packages") Install(c("rlang", "ellipsis"), libPaths = tempPkgFolder, standAlone = TRUE) ##################################################################################### # Isolated projects -- Use a project folder and pass to libPaths or set .libPaths() # ##################################################################################### # GitHub packages if (requireNamespace("gitcreds", quietly = TRUE)) { #if (is(try(gitcreds::gitcreds_get(), silent = TRUE), "gitcreds")) { ProjectPackageFolder <- file.path(tempdir(), "Require/ProjectA") if (requireNamespace("curl")) { Require("PredictiveEcology/fpCompare@development", libPaths = ProjectPackageFolder, ) } # No install because it is there already Install("PredictiveEcology/fpCompare@development", libPaths = ProjectPackageFolder, ) # the latest version on GitHub ############################################################################ # Mixing and matching GitHub, CRAN, with and without version numbering ############################################################################ pkgs <- c( "remotes (<=2.4.1)", # old version "digest (>= 0.6.28)", # recent version "PredictiveEcology/fpCompare@a0260b8476b06628bba0ae73af3430cce9620ca0" # exact version ) Require::Require(pkgs, libPaths = ProjectPackageFolder) #} } Require:::.cleanup(opts) } ## End(Not run)
main
-master
-aware download from GitHubEquivalent to utils::download.file
, but taking the GITHUB_PAT
environment
variable and using it to access the Github url.
.downloadFileMasterMainAuth( url, destfile, need = "HEAD", verbose = getOption("Require.verbose"), verboseLevel = 2 )
.downloadFileMasterMainAuth( url, destfile, need = "HEAD", verbose = getOption("Require.verbose"), verboseLevel = 2 )
url |
a |
destfile |
a character string (or vector, see the |
need |
If specified, user can suggest which |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
verboseLevel |
A numeric indicating what verbose threshold (level) above which this message will show. |
This is called for its side effect, namely, the same as utils::download.file
, but
using a GITHUB_PAT
, it if is in the environment, and trying both master
and
main
if the actual url
specifies either master
or main
and it does not exist.
installed.packages
This reads the DESCRIPTION files only, so can only access fields that are
available in the DESCRIPTION file. This is different than installed.packages
which has many other fields, like "Built", "NeedsCompilation" etc. If those
fields are needed, then this function will return an empty column in the returned
character matrix.
.installed.pkgs( lib.loc = .libPaths(), which = c("Depends", "Imports", "LinkingTo"), other = NULL, purge = getOption("Require.purge", FALSE), packages = NULL, collapse = FALSE )
.installed.pkgs( lib.loc = .libPaths(), which = c("Depends", "Imports", "LinkingTo"), other = NULL, purge = getOption("Require.purge", FALSE), packages = NULL, collapse = FALSE )
lib.loc |
character vector describing the location of R library trees to
search through, or |
which |
a character vector listing the types of dependencies, a subset
of |
other |
Can supply other fields; the only benefit here is that a user
can specify |
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
packages |
Character vector. If |
collapse |
Logical. If |
This is the mechanism by which install.packages
determines which packages
should be installed from where. With this override, we can indicate arbitrary
repos
, Package
, File
for each individual package.
availablePackagesOverride( toInstall, repos, purge, type = getOption("pkgType"), verbose = getOption("Require.verbose") )
availablePackagesOverride( toInstall, repos, purge, type = getOption("pkgType"), verbose = getOption("Require.verbose") )
toInstall |
A |
repos |
The remote repository (e.g., a CRAN mirror), passed to either
|
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
type |
See |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
VersionOnRepos
, versionSpec
and inequality
columnsNeeds VersionOnRepos
, versionSpec
and inequality
columns
availableVersionOK(pkgDT)
availableVersionOK(pkgDT)
pkgDT |
A |
Clear Require Cache elements
cacheClearPackages( packages, ask = interactive(), Rversion = versionMajorMinor(), clearCranCache = FALSE, verbose = getOption("Require.verbose") ) clearRequirePackageCache( packages, ask = interactive(), Rversion = versionMajorMinor(), clearCranCache = FALSE, verbose = getOption("Require.verbose") )
cacheClearPackages( packages, ask = interactive(), Rversion = versionMajorMinor(), clearCranCache = FALSE, verbose = getOption("Require.verbose") ) clearRequirePackageCache( packages, ask = interactive(), Rversion = versionMajorMinor(), clearCranCache = FALSE, verbose = getOption("Require.verbose") )
packages |
Either missing or a character vector of package names (currently cannot specify version number) to remove from the local Require Cache. |
ask |
Logical. If |
Rversion |
An R version (major dot minor, e.g., "4.2"). Defaults to current R version. |
clearCranCache |
Logical. If |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
A wrapper around tools::R_user_dir("Require", which = "cache")
that
creates the directory, if it does not exist.
cacheDefaultDir()
cacheDefaultDir()
The default cache directory
Sets (if create = TRUE
) or gets the cache
directory associated with the Require
package.
cacheDir(create, verbose = getOption("Require.verbose")) cachePkgDir(create)
cacheDir(create, verbose = getOption("Require.verbose")) cachePkgDir(create)
create |
A logical indicating whether the path should
be created if it does not exist. Default is |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
To set a different directory than the default, set the system variable:
R_USER_CACHE_DIR = "somePath"
and/or R_REQUIRE_PKG_CACHE = "somePath"
e.g., in .Renviron
file or Sys.setenv()
. See Note below.
If !is.null(cacheGetOptionCachePkgDir())
, i.e., a cache path exists,
the cache directory will be created,
with a README placed in the folder. Otherwise, this function will just
return the path of what the cache directory would be.
Currently, there are 2 different Cache directories used by Require:
cacheDir
and cachePkgDir
. The cachePkgDir
is intended to be a sub-directory of the cacheDir
. If you set
Sys.setenv("R_USER_CACHE_DIR" = "somedir")
, then both the package cache
and cache dirs will be set, with the package cache a sub-directory. You can, however,
set them independently, if you set "R_USER_CACHE_DIR"
and "R_REQUIRE_PKG_CACHE"
environment variable. The package cache can also be set with
options("Require.cachePkgDir" = "somedir")
.
Require.cachePkgDir
First checks if an environment variable Require.cachePkgDir
is set and defines a path.
If not set, checks whether the options("Require.cachePkgDir")
is set.
If a character string, then it returns that.
If TRUE
, then use cachePkgDir()
. If FALSE
then returns NULL
.
cacheGetOptionCachePkgDir()
cacheGetOptionCachePkgDir()
Require uses caches for local Package saving, local caches of available.packages
,
local caches of GitHub (e.g., "DESCRIPTION"
) files, and some function calls
that are cached. This function clears all of them.
cachePurge(packages = FALSE, repos = getOption("repos")) purgeCache(packages = FALSE, repos = getOption("repos"))
cachePurge(packages = FALSE, repos = getOption("repos")) purgeCache(packages = FALSE, repos = getOption("repos"))
packages |
Either a character vector of packages to install via
|
repos |
The remote repository (e.g., a CRAN mirror), passed to either
|
Run for its side effect, namely, all cached objects are removed.
Creates the directories, and adds version number
checkLibPaths(libPaths, ifMissing, exact = FALSE, ...)
checkLibPaths(libPaths, ifMissing, exact = FALSE, ...)
libPaths |
The library path (or libraries) where all packages should be
installed, and looked for to load (i.e., call |
ifMissing |
An alternative path if |
exact |
Logical. If |
... |
Not used, but allows other functions to pass through arguments. |
Checks the specified path to a directory for formatting consistencies, such as trailing slashes, etc.
checkPath(path, create) ## S4 method for signature 'character,logical' checkPath(path, create) ## S4 method for signature 'character,missing' checkPath(path) ## S4 method for signature 'NULL,ANY' checkPath(path) ## S4 method for signature 'missing,ANY' checkPath()
checkPath(path, create) ## S4 method for signature 'character,logical' checkPath(path, create) ## S4 method for signature 'character,missing' checkPath(path) ## S4 method for signature 'NULL,ANY' checkPath(path) ## S4 method for signature 'missing,ANY' checkPath()
path |
A character string corresponding to a directory path. |
create |
A logical indicating whether the path should
be created if it does not exist. Default is |
Character string denoting the cleaned up filepath.
This will not work for paths to files.
To check for existence of files, use file.exists()
.
To normalize a path to a file, use normPath()
or normalizePath()
.
## normalize file paths paths <- list("./aaa/zzz", "./aaa/zzz/", ".//aaa//zzz", ".//aaa//zzz/", ".\\\\aaa\\\\zzz", ".\\\\aaa\\\\zzz\\\\", file.path(".", "aaa", "zzz")) checked <- normPath(paths) length(unique(checked)) ## 1; all of the above are equivalent ## check to see if a path exists tmpdir <- file.path(tempdir(), "example_checkPath") dir.exists(tmpdir) ## FALSE tryCatch(checkPath(tmpdir, create = FALSE), error = function(e) FALSE) ## FALSE checkPath(tmpdir, create = TRUE) dir.exists(tmpdir) ## TRUE unlink(tmpdir, recursive = TRUE) # clean up
## normalize file paths paths <- list("./aaa/zzz", "./aaa/zzz/", ".//aaa//zzz", ".//aaa//zzz/", ".\\\\aaa\\\\zzz", ".\\\\aaa\\\\zzz\\\\", file.path(".", "aaa", "zzz")) checked <- normPath(paths) length(unique(checked)) ## 1; all of the above are equivalent ## check to see if a path exists tmpdir <- file.path(tempdir(), "example_checkPath") dir.exists(tmpdir) ## FALSE tryCatch(checkPath(tmpdir, create = FALSE), error = function(e) FALSE) ## FALSE checkPath(tmpdir, create = TRUE) dir.exists(tmpdir) ## TRUE unlink(tmpdir, recursive = TRUE) # clean up
Alternative to utils::compareVersion
that is vectorized on version
,
versionSpec
and/or inequality
. This will also return an NA element
in the returned vector if one of the arguments has NA for that element.
compareVersion2(version, versionSpec, inequality)
compareVersion2(version, versionSpec, inequality)
version |
One or more package versions. Can be |
versionSpec |
One or more versions to compare to.
Can be |
inequality |
The inequality to use, i.e., |
a logical vector of the length of the longest of the 3 arguments.
Only checks for deprecated libPath argument (singular)
dealWithMissingLibPaths( libPaths, standAlone = getOption("Require.standAlone", FALSE), ... )
dealWithMissingLibPaths( libPaths, standAlone = getOption("Require.standAlone", FALSE), ... )
libPaths |
The library path (or libraries) where all packages should be
installed, and looked for to load (i.e., call |
standAlone |
Logical. If |
... |
Checks for the incorrect argument |
A series of helpers to access and deal with GitHub packages
DESCRIPTIONFileVersionV(file, purge = getOption("Require.purge", FALSE)) DESCRIPTIONFileOtherV(file, other = "RemoteSha") dlGitHubDESCRIPTION( pkg, purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose") )
DESCRIPTIONFileVersionV(file, purge = getOption("Require.purge", FALSE)) DESCRIPTIONFileOtherV(file, other = "RemoteSha") dlGitHubDESCRIPTION( pkg, purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose") )
file |
A file path to a |
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
other |
Any other keyword in a |
pkg |
A character string with a GitHub package specification (c.f. remotes) |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
dlGitHubDESCRIPTION
retrieves the DESCRIPTION file from GitHub.com
This uses pkgDepTopoSort
internally so that the package
dependency tree is determined, and then packages are unloaded
in the reverse order. Some packages don't unload successfully for
a variety of reasons. Several known packages that have this problem
are identified internally and not unloaded. Currently, these are
glue
, rlang
, ps
, ellipsis
, and, processx
.
detachAll( pkgs, dontTry = NULL, doSort = TRUE, verbose = getOption("Require.verbose") )
detachAll( pkgs, dontTry = NULL, doSort = TRUE, verbose = getOption("Require.verbose") )
pkgs |
A character vector of packages to detach. Will be topologically sorted
unless |
dontTry |
A character vector of packages to not try. This can be used by a user if they find a package fails in attempts to unload it, e.g., "ps" |
doSort |
If |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
A numeric named vector, with names of the packages that were attempted.
2
means the package was successfully unloaded, 1
it was
tried, but failed, 3
it was not loaded, so was not unloaded.
These are wrappers around available.packages and also get the archived versions available on CRAN.
dlArchiveVersionsAvailable( package, repos = getOption("repos"), verbose = getOption("Require.verbose") ) available.packagesCached( repos, purge, verbose = getOption("Require.verbose"), returnDataTable = TRUE, type )
dlArchiveVersionsAvailable( package, repos = getOption("repos"), verbose = getOption("Require.verbose") ) available.packagesCached( repos, purge, verbose = getOption("Require.verbose"), returnDataTable = TRUE, type )
package |
A single package name (without version or github specifications) |
repos |
The remote repository (e.g., a CRAN mirror), passed to either
|
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
returnDataTable |
Logical. If |
type |
See |
dlArchiveVersionsAvailable
searches CRAN Archives for available versions.
It has been borrowed from a sub-set of the code in a non-exported function:
remotes:::download_version_url
Deals with missing libPaths arg, and takes first
doLibPaths(libPaths, standAlone = FALSE)
doLibPaths(libPaths, standAlone = FALSE)
libPaths |
The library path (or libraries) where all packages should be
installed, and looked for to load (i.e., call |
standAlone |
Logical. If |
1st level –> create the .pkgEnv object in Require
envPkgCreate(parentEnv = asNamespace("Require"))
envPkgCreate(parentEnv = asNamespace("Require"))
parentEnv |
The parent environment in which to make the new environment.
Defaults to |
3rd level for deps #############################################
envPkgDepDepsCreate()
envPkgDepDepsCreate()
3rd level for DESCRIPTIONFile
envPkgDepDESCFileCreate()
envPkgDepDESCFileCreate()
Cleans a character vector of non-package name related information (e.g., version)
extractPkgName(pkgs, filenames) extractVersionNumber(pkgs, filenames) extractInequality(pkgs) extractPkgGitHub(pkgs)
extractPkgName(pkgs, filenames) extractVersionNumber(pkgs, filenames) extractInequality(pkgs) extractPkgGitHub(pkgs)
pkgs |
A character string vector of packages with or without GitHub path or versions |
filenames |
Can be supplied instead of |
Just the package names without extraneous info.
extractPkgName("Require (>=0.0.1)") extractVersionNumber(c( "Require (<=0.0.1)", "PredictiveEcology/Require@development (<=0.0.4)" )) extractInequality("Require (<=0.0.1)") extractPkgGitHub("PredictiveEcology/Require")
extractPkgName("Require (>=0.0.1)") extractVersionNumber(c( "Require (<=0.0.1)", "PredictiveEcology/Require@development (<=0.0.4)" )) extractInequality("Require (<=0.0.1)") extractPkgGitHub("PredictiveEcology/Require")
packages
argument may have up to 4 pieces of information for GitHub
packages: name, repository, branch, version. For CRAN-alikes, it will only
be 2 pieces: name, version. There can also be an inequality or equality, if
there is a version.The packages
argument may have up to 4 pieces of information for GitHub
packages: name, repository, branch, version. For CRAN-alikes, it will only
be 2 pieces: name, version. There can also be an inequality or equality, if
there is a version.
getDeps(pkgDT, which, recursive, type = type, repos, libPaths, verbose)
getDeps(pkgDT, which, recursive, type = type, repos, libPaths, verbose)
pkgDT |
A |
which |
a character vector listing the types of dependencies, a subset
of |
recursive |
Logical. Should dependencies of dependencies be searched,
recursively. NOTE: Dependencies of suggests will not be recursive. Default
|
type |
See |
repos |
is used for |
libPaths |
A path to search for installed packages. Defaults to
|
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
If version is not supplied, it will take the local, installed version, if it
exists. Otherwise, it is assumed that the HEAD is desired.
The function will find it in the ap
or on github.com
. For github packages,
this is obviously a slow step, which can be accelerated if user supplies a sha
or a version e.g., getDeps("PredictiveEcology/LandR@development (==1.0.2)")
A (named) vector of SaveNames, which is a concatenation of the 2 or 4 elements
above, plus the which
and the recursive
.
This is a simple version of purrr::transpose
, only for lists with 2 levels.
invertList(l)
invertList(l)
l |
A list with 2 levels. If some levels are absent, they will be |
A list with 2 levels deep, inverted from l
# create a 2-deep, 2 levels in first, 3 levels in second a <- list(a = list(d = 1, e = 2:3, f = 4:6), b = list(d = 5, e = 55)) invertList(a) # creates 2-deep, now 3 levels outer --> 2 levels inner
# create a 2-deep, 2 levels in first, 3 levels in second a <- list(a = list(d = 1, e = 2:3, f = 4:6), b = list(d = 5, e = 55)) invertList(a) # creates 2-deep, now 3 levels outer --> 2 levels inner
Package
column to available.packages
Will join available.packages()
with pkgDT
, if pkgDT
does not already have
a column named Depends
, which would be an indicator that this had already
happened.
joinToAvailablePackages(pkgDT, repos, type, which, verbose)
joinToAvailablePackages(pkgDT, repos, type, which, verbose)
pkgDT |
A |
repos |
is used for |
type |
See |
which |
a character vector listing the types of dependencies, a subset
of |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
The returned data.table
will have most of the columns from
available.packages
appended to the pkgDT
, including Depends
, Imports
,
Suggests
. It will change the column name that is normally
returned from available.packages
as Version
to VersionOnRepos
.
First try to create a hardlink to the file. If that fails, try a symbolic link (symlink) before falling back to copying the file. "File" here can mean a file or a directory.
linkOrCopy(from, to, allowSymlink = FALSE) fileRenameOrMove(from, to)
linkOrCopy(from, to, allowSymlink = FALSE) fileRenameOrMove(from, to)
from , to
|
character vectors, containing file names or paths. |
allowSymlink |
Logical. If |
This will also convert a git repo with nothing after the @ to @HEAD
masterMainToHead(gitRepo)
masterMainToHead(gitRepo)
gitRepo |
A git repository of the form account/repo with optional @branch or @sha or @tag |
The git repository with @HEAD if it had @master, @main or no @.
Sends to message
, but in a structured way so that a data.frame-like can
be cleanly sent to messaging.
This will only show a message if the value of verbose
is greater than the
verboseLevel
. This is mostly useful for developers of code who want to give
users of their code easy access to how verbose their code will be. A developer
of a function will place this messageVerbose
internally, setting the verboseLevel
according to how advanced they may want the message to be. 1
is a reasonable
default for standard use, 0
would be for "a very important message for all users",
2
or above would be increasing levels of details for e.g., advanced use.
If a user sets to -1
with this numeric approach, they can avoid all messaging.
messageDF(df, round, verbose = getOption("Require.verbose"), verboseLevel = 1) messageVerbose(..., verbose = getOption("Require.verbose"), verboseLevel = 1) messageVerboseCounter( pre = "", post = "", verbose = getOption("Require.verbose"), verboseLevel = 1, counter = 1, total = 1, minCounter = 1 )
messageDF(df, round, verbose = getOption("Require.verbose"), verboseLevel = 1) messageVerbose(..., verbose = getOption("Require.verbose"), verboseLevel = 1) messageVerboseCounter( pre = "", post = "", verbose = getOption("Require.verbose"), verboseLevel = 1, counter = 1, total = 1, minCounter = 1 )
df |
A data.frame, data.table, matrix |
round |
An optional numeric to pass to |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
verboseLevel |
A numeric indicating what verbose threshold (level) above which this message will show. |
... |
Passed to |
pre |
A single text string to paste before the counter |
post |
A single text string to paste after the counter |
counter |
An integer indicating which iteration is being done |
total |
An integer indicating the total number to be done. |
minCounter |
An integer indicating the minimum (i.e,. starting value) |
Used for side effects, namely messaging that can be turned on or off with different
numeric values of verboseLevel
. A user sets the verboseLevel
for a particular
message.
modifyList
for multiple listsThis calls utils::modifyList
iteratively using
base::Reduce
, so it can handle >2 lists.
The subsequent list elements that share a name will override
previous list elements with that same name.
It also will handle the case where any list is a NULL
. Note:
default keep.null = TRUE
, which is different than modifyList
modifyList2(..., keep.null = FALSE) modifyList3(..., keep.null = TRUE)
modifyList2(..., keep.null = FALSE) modifyList3(..., keep.null = TRUE)
... |
One or more named lists. |
keep.null |
If |
More or less a convenience around
Reduce(modifyList, list(...))
, with some checks, and the addition of
keep.null = TRUE
by default.
modifyList3
retains the original behaviour of modifyList2
(prior to
Oct 2022); however, it cannot retain NULL
values in lists.
modifyList2(list(a = 1), list(a = 2, b = 2)) modifyList2(list(a = 1), NULL, list(a = 2, b = 2)) modifyList2( list(a = 1), list(x = NULL), list(a = 2, b = 2), list(a = 3, c = list(1:10)) )
modifyList2(list(a = 1), list(a = 2, b = 2)) modifyList2(list(a = 1), NULL, list(a = 2, b = 2)) modifyList2( list(a = 1), list(x = NULL), list(a = 2, b = 2), list(a = 3, c = list(1:10)) )
Checks the specified filepath for formatting consistencies:
use slash instead of backslash;
do tilde etc. expansion;
remove trailing slash.
normPath(path) ## S4 method for signature 'character' normPath(path) ## S4 method for signature 'list' normPath(path) ## S4 method for signature 'NULL' normPath(path) ## S4 method for signature 'missing' normPath() ## S4 method for signature 'logical' normPath(path)
normPath(path) ## S4 method for signature 'character' normPath(path) ## S4 method for signature 'list' normPath(path) ## S4 method for signature 'NULL' normPath(path) ## S4 method for signature 'missing' normPath() ## S4 method for signature 'logical' normPath(path)
path |
A character vector of filepaths. |
Character vector of cleaned up filepaths.
## normalize file paths paths <- list("./aaa/zzz", "./aaa/zzz/", ".//aaa//zzz", ".//aaa//zzz/", ".\\\\aaa\\\\zzz", ".\\\\aaa\\\\zzz\\\\", file.path(".", "aaa", "zzz")) checked <- normPath(paths) length(unique(checked)) ## 1; all of the above are equivalent ## check to see if a path exists tmpdir <- file.path(tempdir(), "example_checkPath") dir.exists(tmpdir) ## FALSE tryCatch(checkPath(tmpdir, create = FALSE), error = function(e) FALSE) ## FALSE checkPath(tmpdir, create = TRUE) dir.exists(tmpdir) ## TRUE unlink(tmpdir, recursive = TRUE) # clean up
## normalize file paths paths <- list("./aaa/zzz", "./aaa/zzz/", ".//aaa//zzz", ".//aaa//zzz/", ".\\\\aaa\\\\zzz", ".\\\\aaa\\\\zzz\\\\", file.path(".", "aaa", "zzz")) checked <- normPath(paths) length(unique(checked)) ## 1; all of the above are equivalent ## check to see if a path exists tmpdir <- file.path(tempdir(), "example_checkPath") dir.exists(tmpdir) ## FALSE tryCatch(checkPath(tmpdir, create = FALSE), error = function(e) FALSE) ## FALSE checkPath(tmpdir, create = TRUE) dir.exists(tmpdir) ## TRUE unlink(tmpdir, recursive = TRUE) # clean up
This will pad floating point numbers, right or left. For integers, either class
integer or functionally integer (e.g., 1.0), it will not pad right of the decimal.
For more specific control or to get exact padding right and left of decimal,
try the stringi
package. It will also not do any rounding. See examples.
paddedFloatToChar(x, padL = ceiling(log10(x + 1)), padR = 3, pad = "0")
paddedFloatToChar(x, padL = ceiling(log10(x + 1)), padR = 3, pad = "0")
x |
numeric. Number to be converted to character with padding |
padL |
numeric. Desired number of digits on left side of decimal.
If not enough, |
padR |
numeric. Desired number of digits on right side of decimal.
If not enough, |
pad |
character to use as padding ( |
Character string representing the filename.
Eliot McIntire and Alex Chubaty
paddedFloatToChar(1.25) paddedFloatToChar(1.25, padL = 3, padR = 5) paddedFloatToChar(1.25, padL = 3, padR = 1) # no rounding, so keeps 2 right of decimal
paddedFloatToChar(1.25) paddedFloatToChar(1.25, padL = 3, padR = 5) paddedFloatToChar(1.25, padL = 3, padR = 1) # no rounding, so keeps 2 right of decimal
This converts a specification like PredictiveEcology/Require@development
into separate columns, "Account", "Repo", "Branch", "GitSubFolder" (if there is one)
parseGitHub(pkgDT, verbose = getOption("Require.verbose"))
parseGitHub(pkgDT, verbose = getOption("Require.verbose"))
pkgDT |
A pkgDT data.table. |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
parseGitHub
turns the single character string representation into 3 or 4:
Account
, Repo
, Branch
, SubFolder
.
parseGitHub
returns a data.table
with added columns.
This is primarily for package developers. It allows the testing of what the recursive dependencies would be if a package was removed from the immediate dependencies.
pkgDepIfDepRemoved( pkg = character(), depsRemoved = character(), verbose = getOption() )
pkgDepIfDepRemoved( pkg = character(), depsRemoved = character(), verbose = getOption() )
pkg |
A package name to be testing the dependencies |
depsRemoved |
A vector of package names who are to be "removed" from the
|
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
A list with 3 named lists Direct
, Recursive
and IfRemoved
.
Direct
will show the top level direct dependencies, either Remaining
or
Removed
. Recursive
will show the full recursive dependencies, either
Remaining
or Removed
. IfRemoved
returns all package dependencies that
are removed for each top level dependency. If a top level dependency is not
listed in this final list, then it means that it is also a recursive
dependency elsewhere, so its removal has no effect.
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDepIfDepRemoved("reproducible", "data.table") Require:::.cleanup(opts) } ## End(Not run)
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDepIfDepRemoved("reproducible", "data.table") Require:::.cleanup(opts) } ## End(Not run)
This is a wrapper around tools::dependsOnPkgs
,
but with the added option of topoSort
, which
will sort them such that the packages at the top will have
the least number of dependencies that are in pkgs
.
This is essentially a topological sort, but it is done
heuristically. This can be used to e.g., detach
or
unloadNamespace
packages in order so that they each
of their dependencies are detached or unloaded first.
pkgDep2
is a convenience wrapper of pkgDep
that "goes one level in",
i.e., the first order dependencies, and runs the pkgDep
on those.
This will first look in local filesystem (in .libPaths()
) and will use a
local package to find its dependencies. If the package does not exist
locally, including whether it is the correct version, then it will look in
(currently) CRAN
and its archives (if the current CRAN
version is not the
desired version to check). It will also look on GitHub
if the package
description is of the form of a GitHub package with format
account/repo@branch
or account/repo@commit
. For this, it will attempt to
get package dependencies from the GitHub ‘DESCRIPTION’ file. This is
intended to replace tools::package_dependencies
or pkgDep
in the
miniCRAN package, but with modifications to allow multiple sources to
be searched in the same function call.
pkgDepTopoSort( pkgs, deps, reverse = FALSE, topoSort = TRUE, libPaths, useAllInSearch = FALSE, returnFull = TRUE, recursive = TRUE, purge = getOption("Require.purge", FALSE), which = c("Depends", "Imports", "LinkingTo"), type = getOption("pkgType"), verbose = getOption("Require.verbose"), ... ) pkgDep2(...) pkgDep( packages, libPaths, which = c("Depends", "Imports", "LinkingTo"), recursive = TRUE, depends, imports, suggests, linkingTo, repos = getOption("repos"), keepVersionNumber = TRUE, includeBase = FALSE, includeSelf = TRUE, sort = TRUE, simplify = TRUE, purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose"), type = getOption("pkgType"), Additional_repositories = FALSE, ... )
pkgDepTopoSort( pkgs, deps, reverse = FALSE, topoSort = TRUE, libPaths, useAllInSearch = FALSE, returnFull = TRUE, recursive = TRUE, purge = getOption("Require.purge", FALSE), which = c("Depends", "Imports", "LinkingTo"), type = getOption("pkgType"), verbose = getOption("Require.verbose"), ... ) pkgDep2(...) pkgDep( packages, libPaths, which = c("Depends", "Imports", "LinkingTo"), recursive = TRUE, depends, imports, suggests, linkingTo, repos = getOption("repos"), keepVersionNumber = TRUE, includeBase = FALSE, includeSelf = TRUE, sort = TRUE, simplify = TRUE, purge = getOption("Require.purge", FALSE), verbose = getOption("Require.verbose"), type = getOption("pkgType"), Additional_repositories = FALSE, ... )
pkgs |
A vector of package names to evaluate their reverse depends (i.e., the packages that use each of these packages) |
deps |
An optional named list of (reverse) dependencies.
If not supplied, then |
reverse |
Logical. If |
topoSort |
Logical. If |
libPaths |
A path to search for installed packages. Defaults to
|
useAllInSearch |
Logical. If |
returnFull |
Logical. Primarily useful when |
recursive |
Logical. Should dependencies of dependencies be searched,
recursively. NOTE: Dependencies of suggests will not be recursive. Default
|
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
which |
a character vector listing the types of dependencies, a subset
of |
type |
See |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
... |
Currently only |
packages |
Either a character vector of packages to install via
|
depends |
Logical. Include packages listed in "Depends". Default |
imports |
Logical. Include packages listed in "Imports". Default |
suggests |
Logical. Include packages listed in "Suggests". Default
|
linkingTo |
Logical. Include packages listed in "LinkingTo". Default
|
repos |
The remote repository (e.g., a CRAN mirror), passed to either
|
keepVersionNumber |
Logical. If |
includeBase |
Logical. Should R base packages be included, specifically,
those in |
includeSelf |
Logical. If |
sort |
Logical. If |
simplify |
Logical or numeric. If |
Additional_repositories |
Logical. If |
A possibly ordered, named (with packages as names) list where list elements are either full reverse depends.
tools::package_dependencies
and pkgDep
will differ under the
following circumstances:
GitHub packages are not detected
using tools::package_dependencies
;
tools::package_dependencies
does not detect the dependencies of base packages among themselves, e.g.,
methods
depends on stats
and graphics
.
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDepTopoSort(c("Require", "data.table"), reverse = TRUE) Require:::.cleanup(opts) } ## End(Not run) ## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDep2("reproducible") # much bigger one pkgDep2("tidyverse") Require:::.cleanup(opts) } ## End(Not run) ## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDep("tidyverse", recursive = TRUE) # GitHub, local, and CRAN packages pkgDep(c("PredictiveEcology/reproducible", "Require", "plyr")) Require:::.cleanup(opts) } ## End(Not run)
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDepTopoSort(c("Require", "data.table"), reverse = TRUE) Require:::.cleanup(opts) } ## End(Not run) ## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDep2("reproducible") # much bigger one pkgDep2("tidyverse") Require:::.cleanup(opts) } ## End(Not run) ## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() pkgDep("tidyverse", recursive = TRUE) # GitHub, local, and CRAN packages pkgDep(c("PredictiveEcology/reproducible", "Require", "plyr")) Require:::.cleanup(opts) } ## End(Not run)
This can be used later by Require
to install or re-install the correct versions. See examples.
pkgSnapshot( packageVersionFile = getOption("Require.packageVersionFile"), libPaths = .libPaths(), standAlone = FALSE, purge = getOption("Require.purge", FALSE), exact = TRUE, includeBase = FALSE, verbose = getOption("Require.verbose") ) pkgSnapshot2( packageVersionFile = getOption("Require.packageVersionFile"), libPaths, standAlone = FALSE, purge = getOption("Require.purge", FALSE), exact = TRUE, includeBase = FALSE, verbose = getOption("Require.verbose") )
pkgSnapshot( packageVersionFile = getOption("Require.packageVersionFile"), libPaths = .libPaths(), standAlone = FALSE, purge = getOption("Require.purge", FALSE), exact = TRUE, includeBase = FALSE, verbose = getOption("Require.verbose") ) pkgSnapshot2( packageVersionFile = getOption("Require.packageVersionFile"), libPaths, standAlone = FALSE, purge = getOption("Require.purge", FALSE), exact = TRUE, includeBase = FALSE, verbose = getOption("Require.verbose") )
packageVersionFile |
A filename to save the packages and their currently
installed version numbers. Defaults to |
libPaths |
The path to the local library where packages are installed.
Defaults to the |
standAlone |
Logical. If |
purge |
Logical. Should all caches be purged? Default is
Internally, there are calls to |
exact |
Logical. If |
includeBase |
Logical. Should R base packages be included, specifically,
those in |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
A file is written with the package names and versions of all packages within libPaths
.
This can later be passed to Require
.
pkgSnapshot2
returns a vector of package names and versions, with no file output. See
examples.
Will both write a file, and (invisibly) return a vector of packages with the
version numbers. This vector can be used directly in Require
, though it should likely
be used with require = FALSE
to prevent attaching all the packages.
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() # install one archived version so that below does something interesting libForThisEx <- tempdir2("Example") Require("crayon (==1.5.1)", libPaths = libForThisEx, require = FALSE) # Normal use -- using the libForThisEx for example; # normally libPaths would be omitted to get all # packages in user or project library tf <- tempfile() # writes to getOption("Require.packageVersionFile") # within project; also returns a vector # of packages with version pkgs <- pkgSnapshot( packageVersionFile = tf, libPaths = libForThisEx, standAlone = TRUE # only this library ) # Now move this file to another computer e.g. by committing in git, # emailing, googledrive # on next computer/project Require(packageVersionFile = tf, libPaths = libForThisEx) # Using pkgSnapshot2 to get the vector of packages and versions pkgs <- pkgSnapshot2( libPaths = libForThisEx, standAlone = TRUE ) Install(pkgs) # will install packages from previous line Require:::.cleanup(opts) unlink(getOption("Require.packageVersionFile")) } ## End(Not run)
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() # install one archived version so that below does something interesting libForThisEx <- tempdir2("Example") Require("crayon (==1.5.1)", libPaths = libForThisEx, require = FALSE) # Normal use -- using the libForThisEx for example; # normally libPaths would be omitted to get all # packages in user or project library tf <- tempfile() # writes to getOption("Require.packageVersionFile") # within project; also returns a vector # of packages with version pkgs <- pkgSnapshot( packageVersionFile = tf, libPaths = libForThisEx, standAlone = TRUE # only this library ) # Now move this file to another computer e.g. by committing in git, # emailing, googledrive # on next computer/project Require(packageVersionFile = tf, libPaths = libForThisEx) # Using pkgSnapshot2 to get the vector of packages and versions pkgs <- pkgSnapshot2( libPaths = libForThisEx, standAlone = TRUE ) Install(pkgs) # will install packages from previous line Require:::.cleanup(opts) unlink(getOption("Require.packageVersionFile")) } ## End(Not run)
Require
optionsThese provide top-level, powerful settings for a comprehensive reproducible workflow. See Details below.
RequireOptions() getRequireOptions()
RequireOptions() getRequireOptions()
RequireOptions()
prints the default values of package options set at startup, which may have been changed (e.g., by the user) during the current session.
getRequireOptions()
prints the current values of package options.
Below are options that can be set with options("Require.xxx" = newValue)
,
where xxx
is one of the values below, and newValue
is a new value to give
the option. Sometimes these options can be placed in the user's .Rprofile
file so they persist between sessions.
The following options are likely of interest to most users:
install
Default: TRUE
. This is the default argument to Require
,
but does not affect Install
. If this is FALSE
, then no installations
will be attempted, and missing packages will result in an error.
RPackageCache
Default: cacheGetOptionCachePkgDir()
, which must be
either a path or a logical. To turn off package caching, set this to FALSE
.
This can be set using an environment variable e.g.
Sys.setenv(R_REQUIRE_PKG_CACHE = "somePath")
, or
Sys.setenv(R_REQUIRE_PKG_CACHE = "TRUE")
; if that is not set, then an
either a path or logical option (options(Require.cachePkgDir = "somePath")
or options(Require.cachePkgDir = TRUE)
). If TRUE
, the
default folder location cachePkgDir()
will be used. If this is
TRUE
or a path is provided, then binary and source packages will be cached
here. Subsequent downloads of same package will use local copy. Default is to
have packages not be cached locally so each install of the same version will
be from the original source, e.g., CRAN, GitHub.
otherPkgs
Default: A character vector of packages that are
generally more successful if installed from Source on Unix-alikes. Since
there are repositories that offer binary packages builds for Linux (e.g.,
RStudio Package Manager), the vector of package names indicated here will
default to a standard CRAN repository, forcing a source install. See also
spatialPkgs
option, which does the same for spatial packages.
purge
Default: FALSE
. If set to (almost) all internal caches used
by Require
will be deleted and rebuilt. This should not generally be
necessary as it will automatically be deleted after (by default) 1 hour (set
via R_AVAILABLE_PACKAGES_CACHE_CONTROL_MAX_AGE
environment variable in
seconds)
spatialPkgs
Default: A character vector of packages that are
generally more successful if installed from Source on Unix-alikes. Since
there are repositories that offer binary packages builds for Linux (e.g.,
RStudio Package Manager), the vector of package names indicated here will
default to a standard CRAN repository, forcing a source install. See also
otherPkgs
option, which does the same for non-spatial packages.
useCranCache
Default: FALSE
. A user can optionally use the
locally cached packages that are available due to a user's use of the
crancache
package.
verbose
Default: 1
. See ?Require.
.basePkgs
Recursive function to remove .basePkgs
rmBase(includeBase = formals(pkgDep)[["includeBase"]], deps)
rmBase(includeBase = formals(pkgDep)[["includeBase"]], deps)
includeBase |
Logical. If |
deps |
Either a list of dependencies, a data.table of dependencies with
a column |
Reference table of R versions and their release dates (2018 and later).
rversions
rversions
An object of class data.frame
with 21 rows and 2 columns.
Update this as needed using rversions::r_versions()
:
# install.packages("rversions")
v = rversions::r_versions()
keep = which(as.Date(v$date, format = "
as.Date("2018-01-01", format = "
dput(v[keep, c("version", "date")])
setdiff
, but takes into account namesThis will identify the elements in l1
that are not in l2
. If
missingFill
is provided, then elements that are in l2
, but not in l1
will be returned, assigning missingFill
to their values. This might be
NULL
or ""
, i.e., some sort of empty value. This function will work on
named lists, named vectors and likely on other named classes.
setdiffNamed(l1, l2, missingFill)
setdiffNamed(l1, l2, missingFill)
l1 |
A named list or named vector |
l2 |
A named list or named vector (must be same class as |
missingFill |
A value, such as |
There are 3 types of differences that might occur with named
elements: 1. a new named element, 2. an removed named element, and 3. a
modified named element. This function captures all of these. In the case of
unnamed elements, e.g., setdiff
, the first two are not seen as differences,
if the values are not different.
A vector or list of the elements in l1
that are not in l2
, and
optionally the elements of l2
that are not in l1
, with values set to
missingFill
.libPaths
This will set the .libPaths()
by either adding a new path to it if
standAlone = FALSE
, or will concatenate c(libPath, tail(.libPaths(), 1))
if standAlone = TRUE
. Currently, the default is to make this new
.libPaths()
"sticky", meaning it becomes associated with the current
directory even through a restart of R. It does this by adding and/updating
the ‘.Rprofile’ file in the current directory. If this current directory
is a project, then the project will have the new .libPaths()
associated
with it, even through an R restart.
setLibPaths( libPaths, standAlone = TRUE, updateRprofile = getOption("Require.updateRprofile", FALSE), exact = FALSE, verbose = getOption("Require.verbose") )
setLibPaths( libPaths, standAlone = TRUE, updateRprofile = getOption("Require.updateRprofile", FALSE), exact = FALSE, verbose = getOption("Require.verbose") )
libPaths |
A new path to append to, or replace all existing user
components of |
standAlone |
Logical. If |
updateRprofile |
Logical or Character string. If |
exact |
Logical. This function will automatically append the R version
number to the |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
This details of this code were modified from https://github.com/milesmcbain. A different, likely non-approved by CRAN approach that also works is here: https://stackoverflow.com/a/36873741/3890027.
The main point of this function is to set .libPaths()
, which will
be changed as a side effect of this function. As when setting options
,
this will return the previous state of .libPaths()
allowing the user to
reset easily.
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() origDir <- setwd(tempdir()) td <- tempdir() setLibPaths(td) # set a new R package library locally setLibPaths() # reset it to original setwd(origDir) # Using standAlone = FALSE means that newly installed packages # will be installed # in the new package library, but loading packages can come # from any of the ones listed in .libPaths() # will have 2 or more paths otherLib <- file.path(td, "newProjectLib") setLibPaths(otherLib, standAlone = FALSE) # Can restart R, and changes will stay # remove the custom .libPaths() setLibPaths() # reset to previous; remove from .Rprofile # because libPath arg is empty Require:::.cleanup(opts) unlink(otherLib, recursive = TRUE) } ## End(Not run)
## Not run: if (Require:::.runLongExamples()) { opts <- Require:::.setupExample() origDir <- setwd(tempdir()) td <- tempdir() setLibPaths(td) # set a new R package library locally setLibPaths() # reset it to original setwd(origDir) # Using standAlone = FALSE means that newly installed packages # will be installed # in the new package library, but loading packages can come # from any of the ones listed in .libPaths() # will have 2 or more paths otherLib <- file.path(td, "newProjectLib") setLibPaths(otherLib, standAlone = FALSE) # Can restart R, and changes will stay # remove the custom .libPaths() setLibPaths() # reset to previous; remove from .Rprofile # because libPath arg is empty Require:::.cleanup(opts) unlink(otherLib, recursive = TRUE) } ## End(Not run)
Enable use of binary package builds for Linux from the RStudio Package
Manager repo. This will set the repos
option, affecting the current R
session. It will put this binaryLinux
in the first position. If the
getOption("repos")
is NULL
, it will put backupCRAN
in second position.
setLinuxBinaryRepo( binaryLinux = urlForArchivedPkgs, backupCRAN = srcPackageURLOnCRAN )
setLinuxBinaryRepo( binaryLinux = urlForArchivedPkgs, backupCRAN = srcPackageURLOnCRAN )
binaryLinux |
A CRAN repository serving binary Linux packages. |
backupCRAN |
If there is no CRAN repository set |
setup
and setupOff
are currently deprecated.
These may be re-created in a future version.
In its place, a user can simply put .libPaths(libs, include.site = FALSE)
in their .Rprofile
file, where libs
is the directory where the packages
should be installed and should be a folder with the R version number, e.g.,
derived by using checkLibPaths(libs)
.
setup( newLibPaths, RPackageFolders, RPackageCache = cacheGetOptionCachePkgDir(), standAlone = getOption("Require.standAlone", TRUE), verbose = getOption("Require.verbose") ) setupOff(removePackages = FALSE, verbose = getOption("Require.verbose"))
setup( newLibPaths, RPackageFolders, RPackageCache = cacheGetOptionCachePkgDir(), standAlone = getOption("Require.standAlone", TRUE), verbose = getOption("Require.verbose") ) setupOff(removePackages = FALSE, verbose = getOption("Require.verbose"))
newLibPaths |
Same as |
RPackageFolders |
One or more folders where R packages are installed to and loaded from. In the case of more than one folder provided, installation will only happen in the first one. |
RPackageCache |
See |
standAlone |
Logical. If |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
removePackages |
Deprecated. Please remove packages manually from the .libPaths() |
The list of R packages that Require
installs from source on Linux, even if
the getOptions("repos")
is a binary repository. This list can be updated by
the user by modifying the options Require.spatialPkgs
or
Require.otherPkgs
. Default "force source only packages" are visible with
RequireOptions()
.
sourcePkgs(additional = NULL, spatialPkgs = NULL, otherPkgs = NULL)
sourcePkgs(additional = NULL, spatialPkgs = NULL, otherPkgs = NULL)
additional |
Any other packages to be added to the other 2 argument vectors |
spatialPkgs |
A character vector of package names that focus on spatial analyses. |
otherPkgs |
A character vector of package names that often require system specific compilation. |
A sorted concatenation of the 3 input parameters.
split
for a data.table that keeps integrity of a column of lists of data.table objectsdata.table::split
does 2 bad things:
reorders if using f
destroys the integrity of a column that is a list of data.tables, when using by
So, to keep order, need by
, but to keep integrity, need f
. This function
splitKeepOrderAndDTIntegrity(pkgDT, splitOn)
splitKeepOrderAndDTIntegrity(pkgDT, splitOn)
pkgDT |
A |
splitOn |
Character vector passed to |
A list of data.table
objects of length(unique(splitOn))
.
This uses sys
package so that messaging can be controlled. This also provides
the option to parallelize by spawning multiple background
process to allow
parallel e.g., downloads. Noting that if libcurl
is installed (and detected
using capabilities("libcurl")
), then no explicit parallelism will be allowed,
instead method = "libcurl"
will be passed enabling parallel downloads.
sysInstallAndDownload( args, splitOn = "pkgs", doLine = "outfiles <- do.call(download.packages, args)", returnOutfile = FALSE, doLineVectorized = TRUE, tmpdir, libPaths, verbose )
sysInstallAndDownload( args, splitOn = "pkgs", doLine = "outfiles <- do.call(download.packages, args)", returnOutfile = FALSE, doLineVectorized = TRUE, tmpdir, libPaths, verbose )
args |
A list with all arguments for a do.call to either |
splitOn |
A character vector of the names in |
doLine |
A character string with the |
returnOutfile |
A logical. If |
doLineVectorized |
A logical. If |
tmpdir |
A single path where all downloads will be put |
libPaths |
The library path (or libraries) where all packages should be
installed, and looked for to load (i.e., call |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
Mostly for side effects, namely installed packages or downloaded packages or
files. However, in the case of returnOutfile = TRUE
, then a list of
filenames will be returned with any outputs from the doLine
.
Create a temporary subdirectory in .RequireTempPath()
, or a
temporary file in that temporary subdirectory.
tempdir2( sub = "", tempdir = getOption("Require.tempPath", .RequireTempPath()), create = TRUE )
tempdir2( sub = "", tempdir = getOption("Require.tempPath", .RequireTempPath()), create = TRUE )
sub |
Character string, length 1. Can be a result of
|
tempdir |
Optional character string where the
temporary dir should be placed. Defaults to |
create |
Logical. Should the directory be created. Default |
Make a temporary subfile in a temporary (sub-)directory
tempfile2( sub = "", tempdir = getOption("Require.tempPath", .RequireTempPath()), ... )
tempfile2( sub = "", tempdir = getOption("Require.tempPath", .RequireTempPath()), ... )
sub |
Character string, length 1. Can be a result of
|
tempdir |
Optional character string where the
temporary dir should be placed. Defaults to |
... |
passed to |
The resulting string(s) will have only name (including github.com repository if it exists).
trimVersionNumber(pkgs)
trimVersionNumber(pkgs)
pkgs |
A character string vector of packages with or without GitHub path or versions |
trimVersionNumber("PredictiveEcology/Require (<=0.0.1)")
trimVersionNumber("PredictiveEcology/Require (<=0.0.1)")
Similar to update.packages
, but works for archived, non-archived,
and Github packages.
updatePackages( libPaths = .libPaths()[1], purge = FALSE, verbose = getOption("Require.verbose") )
updatePackages( libPaths = .libPaths()[1], purge = FALSE, verbose = getOption("Require.verbose") )
libPaths |
The library to update; defaults to |
purge |
Logical. Should the assessment of |
verbose |
Numeric or logical indicating how verbose should the function
be. If -1 or -2, then as little verbosity as possible. If 0 or FALSE,
then minimal outputs; if |
Run for its side effect, namely, updating installed packages to their latest possible state, whether they are on CRAN currently, archived, or on GitHub.