问题
Actual question
Is it possible to override the blocking of a package's (re-)installation after it has been required/loaded?
I understand that blocking a "true" re-installation to the same library that the package was loaded from makes perfect sense once the package is in use. But my use case is a bit different
Background
I like the idea of having a "sandbox library" to test own packages. Besides the package(s) to test, those sandbox libraries contain all base packages of a clean base R installation plus some contrib packages necessary in order for my whole package building and testing framework to work (e.g. digest, stringr etc.). However, my framework loads the latter packages from the standard lib and then needs to install them to the sandbox lib - which is blocked. Hence my question if it is possible to override this as I'm not really doing what people had in mind when implementing the block.
Illustration
Specify paths to the two libraries
lib <- file.path(R.home(), "library")
lib.sandbox <- file.path(tempdir(), "library")
Create sandbox library
dir.create(lib.sandbox, showWarnings=FALSE)
Install a package to the standard library and load it
install.packages("digest", lib=lib)
require("digest", lib.loc=lib)
Then also install it to the sandbox library
> install.packages("digest", lib=lib.sandbox)
Warning: package 'digest' is in use and will not be installed
My framework figures certain stuff out after certain packages that should also be installed to the sandbox lib are loaded, so I can't put the "install-to-sandbox-lib" step before the initial loading step.
回答1:
Here's a general version of what you suggest in your answer. This will unload the package before installing and reload the package from the same location afterward.
install.packages.sandbox <- function(pkgs, lib, repos=getOption("repos"), ...) {
if (is.null(repos))
stop("Can't install from source. Need package name.")
pkg.pos <- grep(pkgs, search())
pkg.path <- searchpaths()[grep(pkgs, searchpaths())]
in.use <- length(pkg.pos) > 0
# detach
if (in.use) do.call(detach,
list(pkg.pos),
envir=.GlobalEnv)
# install
utils::install.packages(pkgs, lib, repos, ...)
# re-attach from original library location
if (in.use) library(pkgs,
character.only=TRUE,
lib.loc=.libPaths()[sapply(.libPaths(), grepl, pkg.path)])
}
回答2:
Not what I was after conceptually, but a pragmatic workaround: detaching the package right before installing it
Specify paths to the two libraries
lib <- file.path(R.home(), "library")
lib.sandbox <- file.path(tempdir(), "library")
Create sandbox library
dir.create(lib.sandbox, showWarnings=FALSE)
Install a package to the standard library and load it
install.packages("digest", lib=lib)
require("digest", lib.loc=lib)
Detach package
detach(package:digest)
Then also install it to the sandbox library
> install.packages("digest", lib=lib.sandbox)
trying URL 'http://cran.at.r-project.org/bin/windows/contrib/2.15/digest_0.5.2.zip'
Content type 'application/zip' length 79053 bytes (77 Kb)
opened URL
downloaded 77 Kb
package 'digest' successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\wwa418\AppData\Local\Temp\Rtmp6XSVYq\downloaded_packages
来源:https://stackoverflow.com/questions/13163248/possible-to-override-the-blocking-of-a-packages-re-installation-after-it-has