Search code examples
rr-package

check if current execution is part of package installation process


I want to implement my.pkg::f as an active binding, computed using .GlobalEnv[["x"]]. If there is no .GlobalEnv[["x"]], it should raise an error. When installing my.pkg, R seems to evaluate my.pkg::f, and as there is currently no .GlobalEnv[["x"]], it raises an error and terminates the installation process.

I need a function installing.packages which checks if the code is being executed as part of the package installation process. I can make pkg::f return NULL in that case, to avoid it terminating the installation.

# ./my.pkg/NAMESPACE: export(f)
# ./my.pkg/R/file.R:

installing.package <- function () {
    ## TODO: check if we are installing the package
    ## a hacky way to check it
    return(length(names(.GlobalEnv)) <= 1) 
}
# to observe the failed install, use:
# installing.package <- function() FALSE

ff <- function() {
    if (!installing.package())
        get("x", globalenv())
}

NAMESPACE <- environment()

.onLoad <- function(libname, pkgname) {
  makeActiveBinding("f", ff, NAMESPACE)
}

NB: this is similar to use makeActiveBinding inside a package, but with additional complexity


Solution

  • Assuming your package is named my.pkg, you could do this:

    installing.package <- function () {
        Sys.getenv("R_INSTALL_PKG", unset = "") == "my.pkg"
    }
    

    That environment variable will only be set while a package is being installed, and will only contain my.pkg if that's the one being installed.

    You'll need to decide what to do if your package is loaded while another package is being installed. If you want that to count as installing.package() == TRUE, change the comparison to being not equal to "".