r-lib / pkgload

Simulate installing and loading a package
http://pkgload.r-lib.org
Other
59 stars 48 forks source link

Using `load_all()` in `.Rprofile` breaks the help functionality #294

Closed arnaudgallou closed 2 months ago

arnaudgallou commented 2 months ago

Considering the following function:

#' @title foo function
#' @description Function that prints `"foo"`.
#' @returns A character vector
#' @export
foo <- function() "foo"

And .Rprofile:

pkgload::load_all()

Generating the documentation with devtools::document(), restarting the R session and running ?foo will print:

No documentation for ‘foo’ in specified packages and libraries:
you could try ‘??foo’

Calling load_all() again, manually, won't fix it. The only way to make it work is to remove load_all() from the .Rprofile, restart the session and then call load_all().

Context

I'm using a research compendium for the project I'm working on. The compendium has the basic structure of an R package plus a few extra directories for the analyses and the manuscript (using Quarto projects). I use an .Rprofile to load all the utility functions on opening so that I've access to the helpers in the various manuscript files and scripts directly, and to make it easier if someone wants to run the analyses once the paper's published. Ideally I'd like potential users to be able to access help documentation easily.

I'm aware this is an edge case and I don't know if it's a bug or a limit of the function. I do believe using load_all() and .Rprofile in a research compendium works wonderfully so I hope you'll consider fixing it (assuming there's a fix).

DavisVaughan commented 2 months ago

The problem is that R runs .Rprofile too early for your use case. It typically looks something like this:

The problem is, by doing some pkgload related things in Rprofile, you end up with

So pkgload::load_all() technically runs correctly, and everything is working. Its just that the ? operator isn't masked by our special version anymore due to the timing of things.


In RStudio, there is a special hook for these kinds of "too early" problems

setHook("rstudio.sessionInit", function(...) {
  pkgload::load_all()
})

If you do that, it should "just work"


Ironically, this actually works out of the box in Positron without that hook, because we disable R's ability to run your Rprofile, and instead manually run it for you at a later time after more things are set up (which happens to include the utils package).

arnaudgallou commented 2 months ago

Thanks for the explanation (and simple fix), that makes perfect sense. I confirm that using the hook solved the problem so I guess we can close the issue.

arnaudgallou commented 2 months ago

I've just realized that using this hook seems to run .Rprofile too late for Quarto, causing the rendering to fail in my case.

@DavisVaughan I haven't had the chance to try Positron yet but that could be worth checking if the same happens with it. Using .Rprofile with Quarto projects is currently the only solution to execute a piece of code automatically in all .qmd files (see this Quarto discussion for details) so that would be a real bummer if that functionality was broken.