########################################################################/**
# @RdocDefault patchCode
#
# @title "Patches installed and loaded packages and more"
#
# @synopsis
#
# \description{
# @get "title".
# }
#
# \arguments{
# \item{paths}{The path to the directory (and subdirectories) which
# contains source code that will patch loaded packages.
# If @NULL, the patch path is given by the option \code{R_PATCHES},
# If the latter is not set, the system environment with the same name
# is used. If neither is given, then \code{~/R-patches/} is used.}
# \item{recursive}{If @TRUE, source code in subdirectories will also
# get loaded. }
# \item{suppressWarnings}{If @TRUE, @warnings will be suppressed,
# otherwise not.}
# \item{knownExtensions}{A @character @vector of filename extensions
# used to identify source code files. All other files are ignored.}
# \item{verbose}{If @TRUE, extra information is printed while patching,
# otherwise not.}
# \item{...}{Not used.}
# }
#
# \value{
# Returns (invisibly) the number of files sourced.
# }
#
# \details{
# The method will look for source code files (recursively or not) that
# match known filename extensions. Each found source code file is
# then @see "base::source"d.
#
# If the search is recursive, subdirectories are entered if and only if
# either (1) the name of the subdirectory is the same as a \emph{loaded}
# (and installed) package, or (2) if there is no installed package
# with that name. The latter allows common code to be organized in
# directories although it is still not assigned to packages.
#
# Each of the directories given by argument \code{paths} will be
# processed one by one. This makes it possible to have more than one
# file tree containing patches.
#
# To set an options, see @see "base::options". To set a system
# environment, see @see "base::Sys.setenv".
# The character \code{;} is interpreted as a separator. Due to
# incompatibility with Windows pathnames, \code{:} is \emph{not} a
# valid separator.
# }
#
# \examples{\dontrun{
# # Patch all source code files in the current directory
# patchCode(".")
#
# # Patch all source code files in R_PATCHES
# options("R_PATCHES"="~/R-patches/")
# # alternatively, Sys.setenv("R_PATCHES"="~/R-patches/")
# patchCode()
# }}
#
# @author
#
# \seealso{
# @see "base::source".
# @see "base::library".
# }
#
# @keyword "utilities"
# @keyword "programming"
#*/#########################################################################
setMethodS3("patchCode", "default", function(paths=NULL, recursive=TRUE, suppressWarnings=TRUE, knownExtensions=c("R","r","S","s"), verbose=FALSE, ...) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (is.null(paths)) {
paths <- getOption("R_PATCHES")
if (is.null(paths)) {
paths <- Sys.getenv("R_PATCHES")
if (is.null(paths)) {
paths <- "~/R-patches/"
}
}
}
paths <- as.character(paths)
paths <- unlist(strsplit(paths, split="[;]"))
if (is.null(paths) || length(paths) == 0 || identical(paths, "")) {
paths <- "."
}
# Number of files sourced.
count <- 0
# Loaded packages
loadedPackages <- gsub("package:", "", search()[-1])
# Installed packages
# installedPackages <- library()$results[,"Package"]; # Too slow!
installedPackages <- NULL
for (libpath in .libPaths())
installedPackages <- c(installedPackages, list.files(libpath))
# Regular expression to match source code files.
pattern <- paste(knownExtensions, collapse="|")
pattern <- paste("\\.(", pattern, ")$", collapse="", sep="")
# if (verbose) {
# message("Patch paths: ", paste(paths, collapse=", "))
# }
# For each path in the list of paths, ...
for (path in paths) {
# Get all files and directories in the current path
pathnames <- list.files(path=path, full.names=TRUE)
excl <- grep("patchAll.R", pathnames)
if (length(excl))
pathnames <- pathnames[-excl]
# For each file or directory...
for (pathname in pathnames) {
isDirectory <- isDirectory(pathname)
isSourceCodeFile <- (regexpr(pattern, pathname) != -1)
if (!isDirectory && isSourceCodeFile) {
# ...for each R source file...
if (verbose)
message("Patching ", pathname)
if (suppressWarnings) {
suppressWarnings(source(pathname))
} else {
source(pathname)
}
count <- count + 1
} else if (isDirectory && recursive) {
# ...for each directory...
pkgname <- basename(pathname)
isPkgLoaded <- (pkgname %in% loadedPackages)
isPkgInstalled <- (pkgname %in% installedPackages)
if (isPkgLoaded || !isPkgInstalled) {
if (verbose) {
if (isPkgInstalled) {
message("Loaded and installed package found: ", pkgname)
} else {
message("Non-installed package found: ", pkgname)
}
}
count <- count + patchCode(pathname, recursive=recursive,
suppressWarnings=suppressWarnings,
knownExtensions=knownExtensions, verbose=verbose)
} else {
if (verbose)
message("Ignore non-loaded package: ", pkgname)
}
}
} # for (pathname in pathnames)
} # for (path in paths)
# Return nothing.
invisible(count)
}) # patchCode()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.