pkgdepends
pkgdepends copied to clipboard
not all .libPath() entries are taken into account when solving dependencies
If .libPath() has several entries not all are evaluated during dependency lookup. This can lead to re-installation of already available packages.
For example magrittr 1.5 was already installed to .libPaths()[3] on a Fedora 32 machine and would go again to .libPaths[1]:
> library(pkgdepends)
> .libPaths()
[1] "/home/cpuser2/R/x86_64-redhat-linux-gnu-library/4.0"
[2] "/usr/lib64/R/library"
[3] "/usr/share/R/library"
> pdi <- new_pkg_installation_proposal('dplyr')
> pdi$solve()
✓ Loading session disk cached package metadata ... done
> pdi$draw()
dplyr 1.0.1 [new][bld][cmp]
├─ellipsis 0.3.1
│ └─rlang 0.4.7
├─generics 0.0.2 [new][bld]
├─glue 1.4.1
├─lifecycle 0.2.0
│ ├─glue
│ └─rlang
├─magrittr 1.5 [new][bld]
├─...
I believe this is intentional behavior, the idea is that libraries should be self contained, e.g. all packages a project or package needs should be installed in the same library.
@gaborcsardi can correct me if I am mistaken.
Yes it is indeed intentional behavior.
However, I think the se case is important enough to support this optionally. I am thinking that pkgdepends should consider a character vector for the library config option. (But still default to .libPaths()[[1]].) And then we would consider installed packages from multiple libraries, but still always install everything new into the first specified library.
Would that make sense?
That sounds like a good solution to me
https://github.com/r-lib/pak/issues/154 is the same issue.
I have a use case where I'd like to:
- create a temporary library,
custom_lib - install a package into it
- run an R expression with
lib = c(custom_lib, .libPaths()) - remove the temporary library
So a solution to this issue would be pretty nice for that use case too.
Right now if I do pkg_install("vctrs", lib = custom_lib), then it would pull all the deps of vctrs in and put them in custom_lib, even if I already have them in .libPaths().
As Gabor mentioned earlier, pkg_install("vctrs", lib = c(custom_lib, .libPaths())) would be a nice solution.
Gabor mentioned a question of:
there are some non-trivial decisions, e.g. what if a dependency is installed but we need to upgrade it? where does the new package go?
and we both figured that it would be best for any “new” packages that you get as a result of the installation to all go in the same place, i.e. in lib[[1]] because that is where the pkg is probably going to go anyways.
That would be important for my use case because since custom_lib is temporary, I'd want to be sure that the original .libPaths() is left untouched after my function exits and custom_lib is removed.
For clarity, that might mean that the "extra" lib paths should go in a separate argument, like:
pkg_install(pkg, lib = custom_lib, lib_extra = .libPaths())
so you can document lib as the place where packages go, and lib_extra as extra lib paths to be considered in the solver process