rstudio / renv

renv: Project environments for R.
https://rstudio.github.io/renv/
MIT License
1.02k stars 155 forks source link

reverting using restore doesn't work with change to local package #258

Closed kendonB closed 4 years ago

kendonB commented 4 years ago

Looks like the hashes aren't getting obeyed when it comes to local package changes:

library(reprex)
# create project
project <- file.path(tempdir(), "project")
dir.create(project)
setwd(project)
renv::init(settings = list(use.cache = FALSE), restart = FALSE)
#> * Discovering package dependencies ... Done!
#> * Copying packages into the library ... Done!
#> * Lockfile written to '/tmp/RtmpWSMNH8/project/renv.lock'.

local <- file.path(tempdir(), "local")
Sys.setenv(RENV_PATHS_LOCAL = local)
dir.create(local)
system(paste0("git clone https://github.com/yihui/rmini ", file.path(local, "rmini")))

owd <- getwd()
setwd(file.path(local))
# This outputs the file in the same place that devtools::build would
system(paste0("R CMD build --no-build-vignettes --md5 ", file.path(local, "rmini")))
setwd(owd)

# use and install rmini
writeLines("library(rmini)", con = "deps.R")

renv::install(file.path(local, "rmini_0.0.4.tar.gz"))
#> * Package rmini [0.0.4] will be installed from local sources rather than /tmp/rtmpwsmnh8/local/rmini_0.0.4.tar.gz.
#> Installing rmini [0.0.4] ...
#>  OK [built from source]

renv::snapshot(confirm = FALSE)
#> The following package(s) will be updated in the lockfile:
#> 
#> # GitHub =============================
#> - renv    [* -> rstudio/renv]
#> 
#> # Local ==============================
#> - rmini   [* -> 0.0.4]
#> 
#> * Lockfile written to '/tmp/RtmpWSMNH8/project/renv.lock'.

# Try and alter the built package
write("this_is_a_new_function <- function(){1 + 1}", file=file.path(local, "rmini", "R", "rmini.R"), append=TRUE)

file.remove(file.path(local, "rmini_0.0.4.tar.gz"))
#> [1] TRUE
owd <- getwd()
setwd(file.path(local))
# This outputs the file in the same place that devtools::build would
system(paste0("R CMD build --no-build-vignettes --md5 ", file.path(local, "rmini")))
setwd(owd)

# Install new version of the package
renv::install(file.path(local, "rmini_0.0.4.tar.gz"))
#> * Package rmini [0.0.4] will be installed from local sources rather than /tmp/rtmpwsmnh8/local/rmini_0.0.4.tar.gz.
#> Installing rmini [0.0.4] ...
#>  OK [built from source]

rmini:::this_is_a_new_function
#> function () 
#> {
#>     1 + 1
#> }
#> <bytecode: 0x564a54fc8ad8>
#> <environment: namespace:rmini>

# Try to go back to the snapshotted version - doesn't work
renv::restore(repos = character(), confirm = FALSE)
#> * The library is already synchronized with the lockfile.

# hash is in there
writeLines(readLines("renv.lock"))
#> {
#>   "R": {
#>     "Version": "3.6.1",
#>     "Repositories": [
#>       {
#>         "Name": "CRAN",
#>         "URL": "https://cloud.r-project.org"
#>       }
#>     ]
#>   },
#>   "Packages": {
#>     "renv": {
#>       "Package": "renv",
#>       "Version": "0.8.3-39",
#>       "Source": "GitHub",
#>       "RemoteType": "github",
#>       "RemoteHost": "api.github.com",
#>       "RemoteRepo": "renv",
#>       "RemoteUsername": "rstudio",
#>       "RemoteRef": "master",
#>       "RemoteSha": "19195d811fbed646ded4662a9e9c9ec9b1f55625",
#>       "Hash": "7b5a2815c32c42271bb02ad5425cdc2c"
#>     },
#>     "rmini": {
#>       "Package": "rmini",
#>       "Version": "0.0.4",
#>       "Source": "Local",
#>       "Hash": "fb1784feb14df095a6eef0bf49554cd0"
#>     }
#>   }
#> }

Created on 2019-11-21 by the reprex package (v0.3.0)

kevinushey commented 4 years ago

This is expected. Package hashes are built from the DESCRIPTION file only.

You should bump your package version when you modify the package. Or, host your package on GitHub or another Git repository so that the commit hash can be used instead when hashing the package.

kendonB commented 4 years ago

I see - might a future version of renv hash user packages like I thought?

kevinushey commented 4 years ago

This is unlikely to change.

One of the main constraints on the hashing function is that it must produce the same hash for the same package, regardless of the machine. This implies that the same package installed on macOS, Linux, or Windows needs to have the same hash. Otherwise, in collaborative scenarios, the lockfile hashes would change every time someone on a different OS tried to snapshot the project!

kendonB commented 4 years ago

@wlandau see above. Would an extension to drake's approach to code hashing work for R packages as a whole? I'm guessing it would have to be comprehensive including compiled code and possibly docs for renv.