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

capture source package with renv in package root #634

Closed
lorenzwalthert opened this issue Feb 4, 2021 · 4 comments
Closed

capture source package with renv in package root #634

lorenzwalthert opened this issue Feb 4, 2021 · 4 comments

Comments

@lorenzwalthert
Copy link

lorenzwalthert commented Feb 4, 2021

I have an R package {mypkg} and I want to create a virtual environment where this (built) package and its dependencies are available. So I thought I could, in the root of the sources of {mypkg}

renv::settings$snapshot.type("explicit") # Just from DESCRIPTION
renv::settings$package.dependency.fields("Imports")
renv::init()

I am not sure why {mypkg} does not end up captured with {renv} in both the lockfile and the library. This makes it (apparently) impossible to use it in non-dev workflows (e.g. without calling devtools::load_all())

library(mypkg)
#> Error in library(gli.clu) : there is no package called ‘gli.clu’

In particular, I want to share my code with other people, so they could clone the repo and use renv::restore() and then library(mypkg) without the requirements of the {devtools} toolchain. Next, I tried renv::install("."), beacuse in the help file for renv::install(), I saw renv::install("~/path/to/package"). This didn't do what I wanted either.

renv::install(".")
#> Error in if (is.character(url) && grepl("/__[^_]+__/", url)) type <- "binary" : 
#>  missing value where TRUE/FALSE needed

Last attempt was remotes::install_local(), which installed the package properly, but:

  • then I did not know how to add it to the lockfile, the following attempt also did not do it:
renv::settings$snapshot.type("custom")
options(renv.snapshot.filter = function(proj_dir) {
  desc_deps <- desc::desc_get_deps() # probably needed recursive deps here but...
  c(
    desc_deps[desc_deps$type == "Imports",]$package,
    unlist(read.dcf('DESCRIPTION', 'Package'))
  )
})

Given my understanding and challenges, I think when renv::init() is called in a package directory, it should also install that package and make it available on renv::restore(), potentially add it to the lock file (maybe this requires to extend the lockfile specs for this particular case). Alternatives are that at least renv::install(".") would install the package properly and there is a way to add it to the lockfile. Putting a library statement in some random file should not be the solution to this I think, in particular not since for this to work, I couldn't use

renv::settings$snapshot.type("explicit") # Just from DESCRIPTION
renv::settings$package.dependency.fields("Imports")

Anymore (I think) and all dev deps would have to be installed. I found #624, which is related.

Context: I am trying to add renv as a supported language for https://pre-commit.com (partly tracked in lorenzwalthert/precommit#215).

@lorenzwalthert lorenzwalthert changed the title capture source package with renv capture source package with renv in package root Feb 4, 2021
@kevinushey
Copy link
Collaborator

The current renv behavior, I think, is correct: within a package project, renv.lock captures the dependencies required to work on that package; it does not capture the package itself. (If it did, that package would be challenging to restore, since it would require access to your project sources at the time the package was built -- we don't have any of the same way of mapping to versions as we do when e.g. package sources are committed to git)

This implies that if you want to explicitly load and test that package, you'll need to install that package into the project library as a second step -- for example:

# install the packages that your package depends on
renv::restore()

# explicitly install this package itself into the same project library
renv::install(getwd())

I think the fact that renv::install(getwd()) works, but renv::install(".") does not, can be viewed as a bug. (renv is erroneously treating . as the name of a package to be retrieved on CRAN, rather than the path to local package sources.)

Am I correct that making sure renv::install(".") does the right thing would be a suitable workaround in your case?

@lorenzwalthert
Copy link
Author

lorenzwalthert commented Feb 4, 2021

Thanks for your quick answer.

Am I correct that making sure renv::install(".") does the right thing would be a suitable workaround in your case?

Yes. Also relative paths would be nice, like ../mypkg.

(If it did, that package would be challenging to restore, since it would require access to your project sources at the time the package was built -- we don't have any of the same way of mapping to versions as we do when e.g. package sources are committed to git).

Maybe I don't have full context here but if you have the source code of the package, this is really all it needed to restore that package, isn't it? Like it would not make sense to restore a different version of the package than the one you just have here. But probably the use case is not very common and the introduced complexity to represent such a source package (I agree it would not extend well to situations where the renv project and the package source are not in the same directory) in renv.lock is not worth it, so the renv::install(".") solution would also do it. Just need to remember to install the package after restore.

@kevinushey
Copy link
Collaborator

Maybe I don't have full context here but if you have the source code of the package, this is really all it needed to restore that package, isn't it?

In general, you also need all of the package's dependencies as well, though -- your package cannot be built and installed unless the packages it depends on are installed and available at build time.

The development version better handles paths of the form "./path/to/package" now, so I think this issue can ultimately be closed. Feel free to re-open if I'm missing something.

@lorenzwalthert
Copy link
Author

Thanks Kevin, I really appreciate your responsiveness. I'll try it out and come back in case of problems, but I don't expect there will be any 😊.

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

2 participants