'R: Sys.getenv in package startup code always returns empty

So I think I kind of know what's going on here, but I've had trouble finding a reference (in SO or the R docs) for it, so I wanted to air this out and see if people can shed any light.

I have an R package that includes the following code at the top level (not inside any function) of a utils.R file:

S3_BUCKET <- Sys.getenv('S3_BUCKET')
CACHE_DIR <- if (S3_BUCKET == "") {
  'cache/foo'
} else {
  paste0('s3://', S3_BUCKET, '/dir/cache/foo')
}
print(paste("CACHE_DIR:", CACHE_DIR))

This works fine in "development mode" when I load the package via devtools::load_all('.'), but when I install the package in my environment and load it via library(mypkg), Sys.getenv('S3_BUCKET') in this code always returns the empty string (as verified by checking mypkg:::S3_BUCKET).

My hypothesis is that environment variables aren't set up yet at the time the "package-level code" is evaluated during package load. If so - is this documented anywhere, and if it's not, where's the right place to add it to the docs? Or is it a bug that should be fixed?

It also looks like maybe stdout isn't set up yet (for the package?) either, because the print output never seems to appear.

The solution I'm going with is to convert it to an .onLoad callback, which is better practice anyway I'm sure:

GLOBALS <- new.env()
GLOBALS$CACHE_DIR <- 'cache/foo'

.onLoad <- function(libname, pkgname) {
  S3_BUCKET <- Sys.getenv('S3_BUCKET')
  if (S3_BUCKET != "") {
    assign('CACHE_DIR', paste0('s3://', S3_BUCKET, '/dir/cache/foo'), GLOBALS)
    print(paste("CACHE_DIR:", CACHE_DIR))
  }
}

This works as intended.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source