r-lib / remotes

Install R packages from GitHub, GitLab, Bitbucket, git, svn repositories, URLs
https://remotes.r-lib.org/
Other
333 stars 153 forks source link

Install does not offer the user a chance to create a personal library #431

Closed cfhammill closed 4 years ago

cfhammill commented 6 years ago

Hi devtools devs, I ran into some somewhat surprising behavour. I administer a multi-user R environment that makes use of modules. I use the modules to point to centrally installed packages, this involves R_USER_LIBS. I noticed that across an R version upgrade my users could no longer install packages with devtools. This issue is that users do not have write access to anything on the .libPaths(), install.packages prompts the user to create a library whereas install_* does not. Here's a quick example:

>.libPaths()
[1] "/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.0"        
[2] "/axiom/projects/software/arch/linux-xenial-xerus/R/3.5.1/lib/R/library"
> devtools::install_cran("rgl", force = TRUE)
trying URL 'https://cran.rstudio.com/src/contrib/rgl_0.99.16.tar.gz'
Content type 'application/x-gzip' length 3058794 bytes (2.9 MB)
==================================================
downloaded 2.9 MB

Installing rgl
'/axiom2/projects/software/arch/linux-xenial-xerus/R/3.5.1/lib/R/bin/R'  \
  --no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL  \
  '/tmp/RtmpYzS7SH/devtoolsda27fbbe84c/rgl'  \
  --library='/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.0'  \
  --install-tests --no-lock 

Error: ERROR: no permission to install to directory ‘/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.0’
Installation failed: Command failed (1)

whereas installing with install.packages prompts me to create a user library

> install.packages("rgl")
Installing package into ‘/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.0’
(as ‘lib’ is unspecified)
Warning in install.packages("rgl") :
  'lib = "/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.0"' is not writable
Would you like to use a personal library instead? (yes/No/cancel) y
Would you like to create a personal library
‘~/R/x86_64-pc-linux-gnu-library/3.5’
to install packages into? (yes/No/cancel) y

Once the directory is created devtools works fine. Obviously this is not a common issue, but if it was simple to add it would be nice.

Xiaojieqiu commented 5 years ago

I had the same issue today. Will this issue resolved soon?

dtenenba commented 5 years ago

Just a +1, and also I don't think this is a feature request. IMO it's a bug. None of our users have write access to R_LIBS_SITE (nor should they). Having install() work like install.packages() seems like a reasonable expectation. This is actually a complete showstopper -- install_github() and friends just fail with no way to make them work.

BTW, manually creating the R_LIBS_USER directory does not work for me, I still get the same error.

Adding a lib argument to install_github() whose value is Sys.getenv("R_LIBS_USER") does not work either, even though ... is supposed to be passed to install.packages().

jimhester commented 5 years ago

R only puts uses R_LIBS_USER for the library path if the directory exists when the R session starts, so setting it during a session won't do anything.

I don't believe remotes is doing anything to prevent the normal behavior, the dialog is coming from a call to install.packages(), so I don't really know why the directory is not being created.

There is also an straightforward way to work around this issue, create a writable directory manually and put it on your library path.

cfhammill commented 5 years ago

install.packages (sort of) gets tricked. remotes sets the full R_LIBS_USER to the full .libPath()

https://github.com/r-lib/remotes/blob/ac34fc67a3d6a56a2c850f77ed3139174747c397/R/install.R#L46

Then install.packages checks for file existence of R_LIBS_USER[1] (if the user lib doesn't exist this will still just be the site lib), decide it exists and not offer to make a user lib.

So it fails on the case when no element of .libPaths() is writeable, and R_LIBS_USER[1] exists and is unwriteable.

I wish I had put this in the initial report.

jimhester commented 5 years ago

So can you see the same behavior outside of remotes with the following?

lib <- paste(.libPaths(), collapse = .Platform$path.sep)
Sys.setenv("R_LIBS_USER" = lib)
install.packages("xyz")
cfhammill commented 5 years ago

Yes, I think so.

Edit: Just tried and yes.

> lib <- paste(.libPaths(), collapse = .Platform$path.sep)
> Sys.setenv("R_LIBS_USER" = lib)
> install.packages("lenses")
Installing package into ‘/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.1’
(as ‘lib’ is unspecified)
Warning in install.packages("lenses") :
  'lib = "/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.1"' is not writable
Would you like to use a personal library instead? (yes/No/cancel) yes
--- Please select a CRAN mirror for use in this session ---
trying URL 'https://cloud.r-project.org/src/contrib/lenses_0.0.3.tar.gz'
Content type 'application/x-gzip' length 25603 bytes (25 KB)
==================================================
downloaded 25 KB

Error: ERROR: no permission to install to directory ‘/axiom2/projects/software/arch/linux-xenial-xerus/RMINC/1.5.2.1’

The downloaded source packages are in
        ‘/tmp/RtmpY4zeGP/downloaded_packages’
Warning message:
In install.packages("lenses") :
  installation of package ‘lenses’ had non-zero exit status
jimhester commented 4 years ago

This seems like a bug in install.packages() then rather than remotes.

cfhammill commented 4 years ago

I think this is still a remotes issue, remotes munges R_LIBS, R_LIBS_USER, and R_LIBS_SITE to all be the same, the distinction between them is relevant to install.packages.

StyXman commented 1 year ago

This seems like a bug in install.packages() then rather than remotes.

remotes munges R_LIBS, R_LIBS_USER, and R_LIBS_SITE to all be the same

https://github.com/r-lib/remotes/blame/ac34fc67a3d6a56a2c850f77ed3139174747c397/R/install.R#L57 clearly says:

  lib <- paste(.libPaths(), collapse = .Platform$path.sep)
  [...]
  with_envvar(
    c(R_LIBS = lib,
      R_LIBS_USER = lib,
      R_LIBS_SITE = lib,
      RGL_USE_NULL = "TRUE"), [...]

@jimhester you've been around that code, maybe you can do something about it? I can't install on a machine where I have a user but not root.

gaborcsardi commented 1 year ago

I can't install on a machine where I have a user but not root.

Can you create the user library before calling remotes?

douglasgscofield commented 10 months ago

this is still an issue, the "not writable" directory is held by R_LIBS_SITE:

Warning in i.p(...) :
  'lib = "/sw/apps/R_packages/4.3.1/rackham"' is not writable
Would you like to use a personal library instead? (yes/No/cancel) yes
Error: ERROR: no permission to install to directory '/sw/apps/R_packages/4.3.1/rackham'
Warning message:
In i.p(...) :
  installation of package '/scratch/RtmpIbVKHP/file5ad827b7beea/DoubletFinder_2.0.4.tar.gz' had non-zero exit status
mirizarry-ortiz commented 8 months ago

Works for me if I specify lib = .libPaths()[2] as argument, where .libPaths()[2] has the path to my personal library

douglasgscofield commented 6 months ago

The reason why this is an important issue for us is that we have many relatively inexperienced users, and we would really like remotes::install_github() (and devtools::install_github() for that matter) to handle this issue just like install.packages() does, and automatically create the directory tree for the personal R library. That is the structure we want our users to have for their personal R library trees, since it contains Major.Minor versioning and prevents incompatibilities when switching to new R versions.