Open arnold-c opened 1 year ago
Thanks for the suggestion, this would make sense, but rig currently does not do this.
Maybe it will at some point, but not just yet. It is not entirely clear how this should work with rig, but the Python docs are useful.
If you really want to do this, you can change the PATH
to point a specific R version, in your local shell, and then that version is used in all subprocesses, unless they change or ignore the PATH
of course.
Echoing this would be useful expecially when mounting projects in the rig container (be it via visual studio code and the devcontainer setup or manually via docker), so it auto-selects either the nearest or exact version depending on implementation logic.
Be nice to be able to have a .r-version
file with 4.1
in and then get the latest supported rig build for that branch.
Alternatively or optionally, RIG_DEFAULT_VERSION
environment variable being checked, and if set, used.
One question that comes up early with this pattern is what should happen with user package libraries. Currently the libraries are shared between R patch versions, e.g. R 4.3.0, R 4.3.1 and R 4.3.2 use the same user package library, at ~/R/aarch64-unknown-linux-gnu-library/4.3
(on a typical Linux).
Is that a problem? Should 4.3.0 and 4.3.1 have a separate library? I would lean towards NO, implying that if you want more separation and (say) project-specific libraries, you'd need to use an additional tool, e.g. https://github.com/rstudio/renv.
Does this make sense? (Maybe we should have another option to use fully version-specific libraries, independently of the local .rigrc
feature?)
Yet another question. Do I understand it correctly, that in order to set up a "project" with the correct R versions, users would need to run rig use
within the directory first?
I.e. it is not expected that just changing the working directory and starting R (or equivalently, opening RStudio or VS code in that project/directory) is supposed to set up the correct R version (and possibly other setup)?
Isn't that a bit inconvenient? Ideally, opening the project in RStudio should already start up with the correct R version? How do other editors do this? Does VS Code recognize .nvmrc
files, and does it set up the correct Node version?
One question that comes up early with this pattern is what should happen with user package libraries. Currently the libraries are shared between R patch versions, e.g. R 4.3.0, R 4.3.1 and R 4.3.2 use the same user package library, at
~/R/aarch64-unknown-linux-gnu-library/4.3
(on a typical Linux).Is that a problem? Should 4.3.0 and 4.3.1 have a separate library? I would lean towards NO, implying that if you want more separation and (say) project-specific libraries, you'd need to use an additional tool, e.g. https://github.com/rstudio/renv.
Does this make sense? (Maybe we should have another option to use fully version-specific libraries, independently of the local
.rigrc
feature?)
Slightly off topic but you've raised a question - if patch versions are considered the same, is it desirable for the following to happen:
As you can see rig isn't able to select a version by the major.minor even if it's installed already.
Interestingly, it can if you do rig add 4.1
first, presumably setting up an alias internally?
Yet another question. Do I understand it correctly, that in order to set up a "project" with the correct R versions, users would need to run
rig use
within the directory first?I.e. it is not expected that just changing the working directory and starting R (or equivalently, opening RStudio or VS code in that project/directory) is supposed to set up the correct R version (and possibly other setup)?
Isn't that a bit inconvenient? Ideally, opening the project in RStudio should already start up with the correct R version? How do other editors do this? Does VS Code recognize
.nvmrc
files, and does it set up the correct Node version?
As to this, you're right to question this, because it's definitely not intuitive - I guess personally I was asking in an exclusively docker framed context. I want to be able to use rig as a base container to build a project in a multistage build - right now I need to do RUN commands to add then default a version, if I could use an ENV/ARG to set the version, where it adds it if it's missing, and defaults to it after it would make this workflow easier to handle.
To be clear it's not a blocker, the RUN commands will do in a pinch.
if patch versions are considered the same
They are not the same (on Linux and Windows), but they share the same user package library, simply because that's the default setup by R.
In that case would it be a good or bad design choice if rig being asked to default to a major.minor release just sets to the nearest major.minor.patch, maybe with an additional but non fatal warning in the terminal that an exact match has not been found?
if patch versions are considered the same
They are not the same (on Linux and Windows), but they share the same user package library, simply because that's the default setup by R.
In that case would it be a good or bad design choice if rig being asked to default to a major.minor release just sets to the nearest major.minor.patch, maybe with an additional but non fatal warning in the terminal that an exact match has not been found?
Possibly. I have wanted to have more explicit support for aliases (e.g. you can say rig default release
already), so this would kind of fall into that category.
But yeah, mostly independent of the original issue.
I think to answer some of the questions that have come up, it might be good if rig has a fallback version that it defaults if it can't find a file/something that specifies a particular version be used. It might be reasonable to have this as the most recent version (e.g. rig default release
, as @gaborcsardi suggested).
Regarding how it should work in practice, I would potentially lean towards having separate libraries for each minor version, where a project that specifies a particular R version should also require specific package versions, managed by renv
. Upon setting a local R version, rig
could run renv::init()
, for example. I believe this might reduce the number of edge cases that have to be dealt with. However, I appreciate that there are some instances where renv
isn't warranted, so this isn't a strong preference.
To initialize a project with an R version, I think forcing the user to be intentional is OK e.g. rig local 4.2.1
. After this first time, possibly it could save and source the version information in a similar manner as renv
i.e., using .Rprofile
? Then when R/RStudio/other editors start up in that directory it switches to the local version, otherwise it stays in the default R version?
In general, I think renv users will need to have a different workflow, so for now, I would focus on use cases without renv.
The thing is, using .Rprofile
is not great, because if there is an .Rprofile
, then the ~/.Rprofile
is not used, and people have setup code there. Unless of course they use renv, but that case is difficult as well, because we would need to merge renv and rig setup in a single .Rprofile
.
So ideally, this would work without creating an .Rprofile
file. Which means that the user needs to run rig use
every time they "open" the project.
Yet another question. Do I understand it correctly, that in order to set up a "project" with the correct R versions, users would need to run
rig use
within the directory first?I.e. it is not expected that just changing the working directory and starting R (or equivalently, opening RStudio or VS code in that project/directory) is supposed to set up the correct R version (and possibly other setup)?
Isn't that a bit inconvenient? Ideally, opening the project in RStudio should already start up with the correct R version? How do other editors do this? Does VS Code recognize
.nvmrc
files, and does it set up the correct Node version?
Sorry, just seeing this now. You're right that running rig use
every time would be very annoying. nvm
and chruby
solve for this by asking that users add hooks into their .zshrc
or .bashrc
(or whatever) files that automatically switch versions if the right dotfile is detected. This is explained in this nvm
guide: https://github.com/nvm-sh/nvm?tab=readme-ov-file#calling-nvm-use-automatically-in-a-directory-with-a-nvmrc-file
I think something similar for rig
would be great. cd
into a folder, and rig automaticaly runs rig use X
based on a version in a .rig
or .r-version
file. I'm not sure how this would work with RStudio, though. Can pre-launch hooks be added to RStudio, or is there any ability for version switching there? That's a bit beyond my comprehension.
@tomcardoso I suppose rig could set up an /usr/local/bin/R
(+ Rscript
) script that switches version to the one prescribed in a local .rigconfig
(or .rconfig
?) file.
But we can't really do much with RStudio, I am afraid. There is an RStudio hook to run R code at startup, but you'd need to set that up from an .Rprofile
, which means that R has to be running already, which is too late to choose a version. So RStudio would need to support .rconfig
files explicitly.
@gaborcsardi Makes sense. FWIW, I think shell hooks would be a great start. And I wonder, too, if the RStudio folks would consider building this into the app.
R (and R package) version inconsistencies are one of the great pain points for me (and, I suspect, many others) in R. Sharing code, deploying to GitHub or Shiny, etc. are a huge pain because packages change, backwards compatibility gets broken, functions get deprecated, and so on – all of which makes the R development toolchain quite brittle. Deploying a GitHub Action-based R scraper is often an exercise in frustration. renv
has helped somewhat, but the problem is that the libraries are still at the mercy of the local R version. So whatever can be done to integrate the shell, rig
, renv
and RStudio more tightly would be hugely appreciated. I'm happy to help with code, feature/design suggestions or as a guinea pig for an auto-switching feature, FWIW; just let me know.
Thanks for the suggestion, this would make sense, but rig currently does not do this.
Maybe it will at some point, but not just yet. It is not entirely clear how this should work with rig, but the Python docs are useful.
If you really want to do this, you can change the
PATH
to point a specific R version, in your local shell, and then that version is used in all subprocesses, unless they change or ignore thePATH
of course.
I think that the error of rig default
command requiring sudo permsions could be improved by explaining the user how can they set the required variables theirself.
For example: $ export PATH=/opt/R/3.6.3/bin:$PATH or $ export PATH=/opt/R/4.3.2/bin:$PATH
(I assume other things should be changed too)
Yet another question. Do I understand it correctly, that in order to set up a "project" with the correct R versions, users would need to run
rig use
within the directory first?I.e. it is not expected that just changing the working directory and starting R (or equivalently, opening RStudio or VS code in that project/directory) is supposed to set up the correct R version (and possibly other setup)?
Isn't that a bit inconvenient? Ideally, opening the project in RStudio should already start up with the correct R version? How do other editors do this? Does VS Code recognize
.nvmrc
files, and does it set up the correct Node version?
AFAIK, it leaves it up to the user on how they'd like to hook in, but provides some examples. Though this is just shell integration, and not editor-specific.
I will add that using direnv
is always a good workaround:
rig switch $(< .rigrc)
rig switch $(< .rigrc)
I think this is fine, as long as you are not running multiple versions in parallel, because rig switch
is a global switch.
This requires sudo:
rig switch $(< .rigrc)
I think this is fine, as long as you are not running multiple versions in parallel, because
rig switch
is a global switch.
For Ubuntu 22, I imagine something like this using an .env file with autoenv or another similar tool:
if [ -f .rigrc ]; then
NEWPATH=$PATH
NEWPATH=$(echo "$NEWPATH" | sed -e 's/:\/usr\/local\/bin\/R$//')
NEWPATH=$(echo "$NEWPATH" | sed -e 's/:\/opt\/R\/3.6.3\/bin$//')
NEWPATH=$(echo "$NEWPATH" | sed -e 's/:\/opt\/R\/4.3.2\/bin$//')
NEWPATH=$(echo "$NEWPATH" | sed -e 's/:\/opt\/R\/4.4.0\/bin$//')
RPATH=/opt/R/$(< .rigrc)/bin
export PATH=$RPATH:$NEWPATH
echo $PATH
fi
Any updates regarding this? I think it could be easier to solve it using Positron, right?
For what it's worth, I like rig, but I've been trying out a combination of pixi and direnv with some success (see here, though be sure to add the direnv
eval to your shell, which isn't included in the pixi instructions). This allows me to specify an R version for each project, and, assuming I have created the necessary .envrc
file in the project root, the correct version is automatically loaded by pixi
. A few extra steps and files that I would ideally like, but has been pretty smooth overall
@arnold-c Maybe we can close this issue then?
@gaborcsardi More than happy to - I didn't originally in case this was something that was being left as a future plan, but please feel free to close if that's not the case (at least, not imminently). Thanks for the discussion and openness to the thought!
Apologies if I missed this being discussed previously (possibly related to #74, #132, #139, and #45), but is there any way to set a default R version per directory? I don't use RStudio, so I'm not sure if the method described in the other issues would apply here (please correct me if I'm wrong).
I was thinking that this could work a little like pyenv in python, which has the
pyenv local 3.x
command to set the version you'd like to use (https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local). Obviously this could be tied to therenv.lock
file if used, but I think manually specifying it would work well and might be easier to implement.