5

I am intending to use the package in R to set up a global cache on a linux server, where other users would be able to: i) use the packages by creating symlinks to the library I created (and therefore save on memory and time by not installing it into their own private library), and ii) quickly switch between several versions of a package (depending on the project).

The goal is to be able to quickly reproduce a persons code, with no prior installations or discussions on the set-up. The only thing the person would need is a lock-file, set up his/her environment identically according to the respective lock-file using renv, and run/reproduce the code.

Consider the following example:

I finished with one project that uses public packages from CRAN and also a package developed by myself. I now create a shared/global cache by setting:

Sys.setenv(RENV_PATHS_CACHE = "/path/to/global/cache")

And run:

renv::init()

Which creates a folder with all packages as expected.

Nevertheless, if I want to test this by creating a new project, copying the renv.lock file into the new project folder, and then run

renv::restore()

It fails to retrieve the private package, because it tries to retrieve it from the CRAN repository:

Error: failed to retrieve package 'rmvtools' In addition: Warning message: could not retrieve available packages for url 'https://cran.rstudio.com/src/contrib' Traceback (most recent calls last): 9: renv::restore() 8: renv_restore_run_actions(project, diff, current, lockfile, rebuild) 7: renv_retrieve(packages) 6: handler(package, renv_retrieve_impl(package)) 5: renv_retrieve_impl(package) 4: renv_retrieve_unknown_source(record) 3: renv_retrieve_repos(record) 2: stopf("failed to retrieve package '%s'", record$Package) 1: stop(sprintf(fmt, ...), call. = call.)

How do I "force" ::restore to create so-called symlinks directly from the global cache (and not the CRAN repository)?

My workaround for now is to set the RENV_PATHS_LOCAL variable to the same path as the global cache, and copy the private_package.tar.gz file to the global cache. Nevertheless, this should not be necessary, as I already have installed the package when setting up the global cache. With this workaround, the user has to use the .tar.gz file to install the private package into his own private renv-library (which is not a symlink in this case and stores a duplicate version for every user).

M M
  • 429
  • 5
  • 13

1 Answers1

2

Normally, renv::restore() will find and use packages from the global cache if the requested package(s) can be found there, so I think the underlying question is to why renv is failing to resolve that package in the cache.

What does the entry for your package in renv.lock look like? Does it have a Hash field? Does that Hash field resolve to the correct location in the renv cache? This is the key that renv uses when attempting to resolve a package in the global cache.

You can use:

renv:::renv_cache_list(packages = "<package>")

to see the cache entries for a particular package.

The other option would be to set up a local R package repository, with your private package made available from that repository. This could even be a package repository on a network filesystem referenced with a file URI; e.g. something like:

options(repos = c(ORG = "file:///path/to/local/repository"))

The miniCRAN package may be useful in creating such repositories.

If none of this information suffices, I would recommend filing an issue at https://github.com/rstudio/renv/issues.

Kevin Ushey
  • 20,530
  • 5
  • 56
  • 88