Kevin Ushey
2016-Jul-19 16:46 UTC
[Rd] package installation fails when symlink of same name exists
R fails to install a package from source over a pre-existing package when the path to that package is a symlink, rather than a directory. A reproducible example to illustrate (using MASS as an example): # create a temporary R library in tempdir library <- tempfile() if (!dir.exists(library)) dir.create(library) # symlink MASS from system library to temporary library MASS <- find.package("MASS", lib.loc = .Library) file.symlink(MASS, file.path(library, "MASS")) # use our custom library, and try to install MASS .libPaths(library) utils::install.packages("MASS", lib = library, type = "source") On running this, I see a surprising error message: ERROR: 'MASS' is not a legal package name The code that I'm bumping into lives here: https://github.com/wch/r-source/blob/62f5acbdbdf36e1fc618510312125d1677d79941/src/library/tools/R/install.R#L283-L287 I guess my wish here would be that R would check if any file already existed at the 'instdir' path, and if it existed and was a symlink, R would remove that symlink before install. It could happen before creating the directory, e.g. here: https://github.com/wch/r-source/blob/62f5acbdbdf36e1fc618510312125d1677d79941/src/library/tools/R/install.R#L277-L281 One thing that was a bit surprising to me -- R does not remove a pre-existing package installation if it exists (when installing from source), it merely installs over it, so files / artifacts from a previous package installation could be left over after installing a new package. It seems this is not a problem in practice since I don't think anyone's reported this being an issue before, but for hygiene it seems like a pre-existing directory could / should be removed when installing a new package. (It appears that R does clear out a pre-existing directory when downloading and installing a package binary directly from CRAN.) For motivation: I bumped into this when attempting to implement a package caching feature with packrat. A packrat project using a global cache will have a (private) R library containing symlinks to R package installations in a separate, global library. This allows projects to effectively be isolated from one another, while avoiding duplication of packages used across multiple projects. Unfortunately, some packrat users bump into this when attempting to update a package that has entered the cache (and so is a symlink in their R library). Thanks for your time, Kevin --- $ R --vanilla --slave -e 'sessionInfo()' | head -n 3 R version 3.3.0 Patched (2016-05-23 r70665) Platform: x86_64-apple-darwin13.4.0 (64-bit) Running under: OS X 10.11.5 (El Capitan)
Jeroen Ooms
2016-Jul-20 08:26 UTC
[Rd] package installation fails when symlink of same name exists
On Tue, Jul 19, 2016 at 6:46 PM, Kevin Ushey <kevinushey at gmail.com> wrote:> R fails to install a package from source over a pre-existing package > when the path to that package is a symlink, rather than a directory. > ... > I don't think anyone's reported this being an issue beforeI ran into this as well a while back: https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=16725
Martin Maechler
2016-Jul-20 10:52 UTC
[Rd] package installation fails when symlink of same name exists
>>>>> Jeroen Ooms <jeroenooms at gmail.com> >>>>> on Wed, 20 Jul 2016 10:26:19 +0200 writes:> On Tue, Jul 19, 2016 at 6:46 PM, Kevin Ushey <kevinushey at gmail.com> wrote: >> R fails to install a package from source over a pre-existing package >> when the path to that package is a symlink, rather than a directory. >> ... >> I don't think anyone's reported this being an issue before > I ran into this as well a while back: > https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=16725 I've now at least "acknowledged" that bug report. and have looked into changing the is_subdir() function so it returns TRUE in the case of a symlink [on those platforms where Sys.readlink() "works", i.e., supposedly not on Windows; however that maybe sufficient to close that bug report and also Kevin's issue, right ?] However, Kevin, in his posting, continues > I guess my wish here would be that R would check if any file already > existed at the 'instdir' path, and if it existed and was a symlink, R > would remove that symlink before install. are you sure? I think ... and from what you mention below ("packrat") it would rather be important to *keep* the symlink, and install to whereever the symlink is pointing, no ? > It could happen before creating the directory, e.g. here: > https://github.com/wch/r-source/blob/62f5acbdbdf36e1fc618510312125d1677d79941/src/library/tools/R/install.R#L277-L281 > One thing that was a bit surprising to me -- R does not remove a > pre-existing package installation if it exists (when installing from > source), it merely installs over it, so files / artifacts from a > previous package installation could be left over after installing a > new package. It seems this is not a problem in practice since I don't > think anyone's reported this being an issue before, but for hygiene it > seems like a pre-existing directory could / should be removed when > installing a new package. (It appears that R does clear out a > pre-existing directory when downloading and installing a package > binary directly from CRAN.) Well, at least with update.packages() it seems natural to me that R would not just remove all previous parts there .. > For motivation: I bumped into this when attempting to implement a > package caching feature with packrat. A packrat project using a global > cache will have a (private) R library containing symlinks to R package > installations in a separate, global library. This allows projects to > effectively be isolated from one another, while avoiding duplication > of packages used across multiple projects. Yes, I found this a nice feature when I heard about packrat. But then, really R should *not* remove the symlink and create a regular subdirectory in that library there ! > Unfortunately, some packrat > users bump into this when attempting to update a package that has > entered the cache (and so is a symlink in their R library). > Thanks for your time, > Kevin