Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to change renv folder location #472

Closed
reifjulian opened this issue Jul 8, 2020 · 11 comments
Closed

Option to change renv folder location #472

reifjulian opened this issue Jul 8, 2020 · 11 comments

Comments

@reifjulian
Copy link

It would be nice to allow the user to specify the location of the /renv folder and the renv.lock file. For example, rather than having these items located in the root folder, I might instead want to locate them in a /libraries subfolder.

@kevinushey
Copy link
Collaborator

Can you expand on why you want to change the location of the renv folder? Where are you hoping to place it instead?

The main challenge here is the renv auto-loader, which is created as part of the project .Rprofile. This typically contains a line of the form:

source("renv/activate.R")

and the path in the auto-loader needs to be "stable"; e.g. it needs to be able to find the activate script without renv itself being available yet.

@reifjulian
Copy link
Author

I generally use R as part of a larger project that does separate analyses in Stata. My Stata libraries are kept in a subfolder, /scripts/libraries/stata. These Stata libraries are crossplatform and small in size, and thus can easily be shared for reproducibility purposes. It is often awkward to do this with R, however, since many libraries such as tidyverse are gigantic and need separate installations for each OS. (Hence the appeal of renv!) Additional discussion is available in my Stata coding guide.

What I would like is the ability to store renv.lock and renv/activate.R in my subfolder /scripts/libraries/. I do not personally have any need for the autoloader, and I do not mind having to write a line of code that supplies the path by calling source("[path]/renv/activate.R") directly. Essentially, I would like to use this as a configuration command that sets up a user's system prior to reproducing an analysis.

@kevinushey
Copy link
Collaborator

Thanks for the clarification. We could do this, but I think there's a bunch of things that would have to be done. Here are the places where we make use of the "renv" path by default:

  • renv/R/paths.R

    Lines 68 to 72 in 15b044d

    renv_paths_settings <- function(project = NULL) {
    project <- renv_project_resolve(project)
    components <- c(project, renv_profile_prefix(), "renv/settings.dcf")
    paste(components, collapse = "/")
    }
  • paste(c(project, prefix, "renv/library"), collapse = "/")
  • renv/renv/activate.R

    Lines 607 to 608 in 15b044d

    # check for a profile file (nothing to do if it doesn't exist)
    path <- file.path(project, "renv/local/profile")
    (+ others)
  • renv/R/infrastructure.R

    Lines 73 to 78 in 15b044d

    renv_infrastructure_write_entry_impl(
    add = as.character(add$data()),
    remove = as.character(remove$data()),
    file = file.path(project, "renv/.gitignore"),
    create = TRUE
    )
  • renv/R/install.R

    Lines 282 to 288 in 15b044d

    # determine root directory for staging
    root <- if (!is.na(staging))
    staging
    else if (!is.na(project))
    file.path(project, "renv/staging")
    else
    file.path(libpath, ".renv")

We'd likely want to add a configuration option autoloader.enabled and also an argument for e.g. renv::init(autoloader = FALSE).

@kevinushey
Copy link
Collaborator

I've made some changes in the development version of renv to facilitate this workflow:

  • You can set RENV_PATHS_RENV to control where the project renv resources are stored; e.g. you might use RENV_PATHS_RENV = "scripts/libraries/renv" or something similar.
  • Similarly, the path to the lockfile can be customized via RENV_PATHS_LOCKFILE.
  • You can set RENV_CONFIG_AUTOLOADER_ENABLED = FALSE to disable the renv autoloader. When set, renv won't try to update the project .Rprofile, and won't run any existing autoloaders it finds on startup.

If you can, please give it a try and let me know if you run into any trouble.

@reifjulian
Copy link
Author

I gave it a quick try and ran into a few problems.

  1. renv::init initially gave me an error, and told me I had to specify force=TRUE
  2. The renv.lock file was not created in the directory I specified
  3. renv modified my .Rprofile, but I would prefer not to have it do this.
  4. Calling renv::snapshot() freezes R

I confirmed that renv created the folder /renv in my local user folder, with contents activate.R, library, etc, as expected. It also successfully linked the installed library (estimatr, see below) to what had been previously installed.

Here is sample code
R version 4.0.2 (2020-06-22) -- "Taking Off Again"
Platform: x86_64-apple-darwin17.0 (64-bit)

# Project folder location
MyProject <- Sys.getenv(c("MyProject"))

# Install development version of renv
library(devtools)
install_github("rstudio/renv")

# Disable autoloader, set lockfile path
RENV_CONFIG_AUTOLOADER_ENABLED = FALSE
RENV_PATHS_LOCKFILE <- paste0(MyProject,'/scripts/libraries')

# Error: refusing to initialize project in home directory -- use renv::init(force = TRUE) to override
renv::init(bare = TRUE, force = TRUE)
renv::install("[email protected]")

renv::snapshot()

@kevinushey
Copy link
Collaborator

# Disable autoloader, set lockfile path
RENV_CONFIG_AUTOLOADER_ENABLED = FALSE
RENV_PATHS_LOCKFILE <- paste0(MyProject,'/scripts/libraries')

These need to be set as environment variables. For example:


remotes::install_github("rstudio/renv")

project <- tempfile()
dir.create(project)
setwd(project)

# Disable autoloader, set lockfile path
Sys.setenv(
  RENV_CONFIG_AUTOLOADER_ENABLED = "FALSE",
  RENV_PATHS_LOCKFILE = file.path(project, "scripts/libraries/")
)

renv::init(bare = TRUE, restart = FALSE)
renv::install("[email protected]")

renv::snapshot()

I see, at the end:

* Lockfile written to '/var/folders/9n/3nxsgkrj0rlfx196kzdttpww0000gn/T//Rtmp7sirUH/file393ec1cc3e1/scripts/libraries/renv.lock'.

Note that if you want renv.lock to be placed within the requested directory, you should append a trailing slash. If you want to control the location of the project-local renv folder, you should set RENV_PATHS_RENV.

@kevinushey
Copy link
Collaborator

A more complete solution changing both the renv and renv.lock folders would look like:

Sys.setenv(
  RENV_CONFIG_AUTOLOADER_ENABLED = "FALSE",
  RENV_PATHS_RENV = file.path(project, "scripts/libraries/renv"),
  RENV_PATHS_LOCKFILE = file.path(project, "scripts/libraries/renv.lock")
)

renv::init(bare = TRUE, restart = FALSE)
renv::snapshot()

@Fuco1
Copy link

Fuco1 commented Apr 12, 2023

The article at https://rstudio.github.io/renv/reference/paths.html does not mention RENV_PATHS_RENV.

I'm also using it for a monorepo setup. I think it would be quite useful to write a vignette on a monorepo setup. I work on a proprietary codebase (we opensource what we can though) and a monorepo is just superiour layout to having many small packages, which when change necessitate updates to all the other packages. It's really just a single "solution" split into smaller modules for some operations reasons.

@jacob-lee
Copy link

jacob-lee commented Oct 4, 2024

We frequently are in a situation in which the same directory might be mounted as a SMB share on Mac, or it might be accessed via a number of different virtual Linux systems (a virtual machine with gui environment, or on a cluster). The binaries being compiled won't be cross-compatible. It seems like there should be a relatively simple way to (1) check the OS/server-name etc. and then (2) load the appropriate library folder (assuming that the same package versions are available across OS's).

Is there a vignette or documentation on how that might be achieved reliably and with little hassle? Which environment variables would have to be set? RENV_PATHS_RENV? renv profiles, i.e. https://github.com/rstudio/renv/blob/main/vignettes/profiles.Rmd ?

@kevinushey
Copy link
Collaborator

@jacob-lee can you elaborate? renv already included architecture-specific information in the library paths by default. For example, I see on macOS:

> .libPaths()
[1] "/Users/kevin/scratch/example/renv/library/macos/R-4.4/aarch64-apple-darwin20"
[2] "/Users/kevin/Library/Caches/org.R-project.R/R/renv/sandbox/macos/R-4.4/aarch64-apple-darwin20/f7156815"

and you should see similar OS-specific components for other platforms.

@Arthfael
Copy link

Arthfael commented Jan 29, 2025

I am running into a similar issue and would appreciate knowing what the current solution is:

  • I typically run analysis in a temporary folder then deliver them in another location shared with users and/or archive them
  • I recently moved to renv for the very purpose of ensuring that I can reconstitute analyses as exactly as possible in the future
  • However if some of the information is not copied when I move the data to a new location, then this voids the whole purpose of using renv in the first place
  • I cannot use git for this purpose: most of my users have never written a single line of code nor can they be expected to use complicated IT solutions.

If I understand correctly (from [https://github.com//issues/1757]), one solution would be to create a new renv project in the destination location, replace its renv.lock with that of the original project then run renv::restore(lockfile="renv.lock"), is that correct?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants