-
Notifications
You must be signed in to change notification settings - Fork 154
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
Refine auto-loading behaviour #1915
Conversation
Context: I'm launching an renv-using project, in RStudio, but I just got it from my colleague, e.g. I just git cloned it or similar. So it's clear we're using renv, but the project-specific library doesn't exist yet. While auto-loading, renv wants to interact with me and offer to do
https://stat.ethz.ch/R-manual/R-patched/library/base/html/Startup.html To this end, renv has arrangements to defer loading and any associated user interaction until R is fully initialized, using a hook (added in #1652). But I think the hook isn't currently working as intended. Before this PR, in RStudio Version 2024.04.2+764, having done
Note there is no offer to run After this PR, in RStudio, the interactive nudge to
After this PR, not in RStudio, there's no attempt to interact but the exact command is given (
|
# if we're running within RStudio at this point, and we're running | ||
# within the auto-loader, we need to defer execution here so that | ||
# the console is able to properly receive user input and update | ||
# https://github.com/rstudio/renv/issues/1650 | ||
autoloading <- getOption("renv.autoloader.running", default = FALSE) | ||
if (autoloading && renv_rstudio_available()) { | ||
setHook("rstudio.sessionInit", function() { renv::load(project) }) | ||
setHook("rstudio.sessionInit", function(...) { renv::load(project) }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before, renv::load(project)
was definitely being appended to the "rstudio.sessionInit"
hook. I can see that with getHook("rstudio.sessionInit")
. However it wasn't actually being executed and I think it must have failed some pre-check re: its signature. In my hands, adding ...
makes this feature start to work as intended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the explanation:
RStudio forwards arguments and the whole thing happens inside tryCatch()
. So I guess if the hook function does not accept any arguments, the attempt to run the hook fails. Silently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole chain is:
@@ -881,7 +881,7 @@ renv_load_report_synchronized <- function(project = NULL, lockfile = NULL) { | |||
return(FALSE) | |||
} | |||
|
|||
response <- ask("Would you like to restore the project library?", default = FALSE) | |||
response <- ask("Would you like to run `renv::restore()` to restore the project library?", default = FALSE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like this could ease decision-making for the user, i.e. it's easier to answer this question confidently if you know exactly what's being proposed. Also might have some value in terms of user education.
renv_rstudio_autoloading <- function() { | ||
renv_rstudio_available() && getOption("renv.autoloader.running", default = FALSE) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the sole usage of this function.
autoloading <- getOption("renv.autoloader.running", default = FALSE) | ||
if (autoloading) | ||
return(default) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More simplification now that we've decided to never attempt interaction when autoloading, regardless of the frontend.
@@ -70,7 +70,8 @@ load <- function(project = NULL, quiet = FALSE, profile = NULL, ...) { | |||
|
|||
action <- renv_load_action(project) | |||
if (action[[1L]] == "cancel") { | |||
cancel() | |||
autoloading <- getOption("renv.autoloader.running", default = FALSE) | |||
cancel(verbose = !autoloading) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows us to see the "- Operation canceled." message after overt cancelation by the user, but suppresses such a message when deferring the project load to the session init hook. Discussed elsewhere.
This is ready now. I took a look at adding a test but TBH it looks pretty 😬 . I think this behaviour is legitimately hard to test (interactive usage, with and without RStudio), but I'm also not familiar with all of renv's test helpers, which are extensive. So either this can go forward without an explicit test or else I could use some guidance on how to approach that. |
If you're interested in getting clickable hyperlinks w/o taking a true cli dependency (I understand why that's a nonstarter), this would be one way: https://github.com/r-lib/rlang/blob/main/R/standalone-cli.R I could open a separate issue for that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Do we need a NEWS update? (I'm going to merge this now for testing but we can merge a separate NEWS update after if appropriate) |
I'd definitely be on board for this. |
renv::restore()
during auto-loading.To do/discuss:
After "Installing cli ..." it's easy to think the session is busy or hung. But it's not. If you hit return, you get the normal R prompt. Why does that happen?As I play around with renv, I run into this phenomenon elsewhere. It feels like one or more of the messaging helpers, such ascatf()
orwritef()
sometimes fail to get their trailing newline? In any case, I think it's unrelated to what I'm doing here and out of scope for this PR.rstudio.sessionInit
below), do that. If we can't, emit a message telling the user what to do.If possible, style theI had to give up on that part.renv::restore()
part as a runnable link.