Skip to content
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

Use each blog post's renv environment when rendering #469

Open
3 tasks done
solarchemist opened this issue Aug 6, 2020 · 9 comments
Open
3 tasks done

Use each blog post's renv environment when rendering #469

solarchemist opened this issue Aug 6, 2020 · 9 comments
Labels
feature a feature request or enhancement

Comments

@solarchemist
Copy link

Right now (and please correct me if I'm wrong) blogdown uses the global R environment when it's rendering each blog post.

Would it be possible to make blogdown use each blog post's local R environment (specifically renv) instead?

I am suggesting something along these lines:

  • blogdown's render "chain" build_rms() -> render_page() -> render_page.R -> rmarkdown::render() should cd into each blog post directory, and read any ./.Rprofile so as to load renv if it is used for that blog post.

This way, I think blogdown would achieve several benefits. In particular, re-running blogdown would be less prone to break stuff (making blogdown behave a little more like distill in that regard, effectively inoculating each blog post against changing package versions). But it would also make it much easier to have only certain blog posts use specific package versions without having to muddle the global R installation.

What follows are the steps I took to test if blogdown uses renv's environment if a blog post specifies one (please correct me if I'm missing something).

As a simple test, I have created a new blog post for my existing blog using RStudio 1.3 (by creating a new project, and checking "use renv"). Then I created a plot that uses ggrepel's segment.curvature functionality (which is available in the latest dev version, but gives a warning message "unknown parameter" in the CRAN version).

So inside the project/blog post (which uses renv):

> renv::install("slowkow/ggrepel")
> packageVersion("ggrepel")
[1] ‘0.9.0’

and compiling the blog post using RStudio yields the expected curved ggrepel segments and no warning messages.

But when re-compiling the site with blogdown, the warning message is seen in the CLI output, and the resulting plot uses straight segments instead of nicely curved ones. And I can easily confirm that my global R environment uses the CRAN version of ggrepel:

> packageVersion("ggrepel")
[1] ‘0.8.2’

To re-iterate my point: would it be possible to make blogdown support renv for each blog post?


By filing an issue to this repo, I promise that

  • I have fully read the issue guide at https://yihui.org/issue/.
  • I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('blogdown'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('rstudio/blogdown').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • I have learned the Github Markdown syntax, and formatted my issue correctly.
@yihui
Copy link
Member

yihui commented Sep 9, 2020

That sounds like a great suggestion! We'll definitely consider it in the future. Thank you!

@apreshill apreshill mentioned this issue Sep 23, 2020
19 tasks
@cderv
Copy link
Collaborator

cderv commented Jan 8, 2021

Hi @solarchemist

We've been working hard on a new blogdown version and we will make release of 1.0 soon.
https://community.rstudio.com/t/blogdown-v1-0-to-be-released-soon/92604

Part of the change we made and features we had may help in your usage:

  • Rmd post are no more rebuild by default. Once a post has been rendered to HTML it won't be rendered again by blogdown without users asking for it by Knitting the post using IDE button. Or using the build_site(build_rmd = ) argument.
  • a method = "markdown" has been introduced for users who want to rely only in Hugo rendering for HTML output. It will configure blogdown to render .Rmd to .md and let Hugo do the html rendering. It is the same as using .Rmarkdown

By any chance, have you tried the new version yet ? If not, can you give it a spin (on a demo site maybe) to see if it changes thing for you ?

It will not be the same as having a "project" library for each of your Rmd post but old post won't be rendered anymore so new packages for new posts won't alter the results of previous posts as it could before in some cases.

About a library per post, this could lead to an heavy blog with all the duplicated libraries. However, with renv cache mechanism and renv lockfile I could see the advantage of having a lockfile per post that you could use to rerendered a post. maybe by recreating the library temporarily for the post rendering 🤔

Anyway, eager to here how the new stuff could change (or not) your existing workflow and your need of renv project for each blog post. Thanks!

@cderv cderv added the feature a feature request or enhancement label Jan 8, 2021
@solarchemist
Copy link
Author

Thanks for your kind words @cderv

It took me a while to get around to it, but I have finally upgraded R (v4.0), blogdown (v1.1) and now my blog. And I must say the changes to blogdown makes blogging with it significantly easier. Nice work!

Not building Rmd posts by default works very well, and creates peace of mind compared to before, just like you indicated. Also, asset bundling is awesome! It took a little work to edit image paths and whatnot in my existing blog posts, but bundling assets inside each blog post directory is clearly the better approach.

I think that thanks to asset bundling, now more than ever, each blog post becomes its own little stand-alone project. As such, it becomes even more rational to have each blog post be its own renv project, and it would be just awesome if blogdown actually used such renv environments when rendering.

As to the risk for bloated renv directories, I think I can put you at ease. Like you said, with the renv cache mechanism (I have set RENV_PATHS_ROOT=/nice/central/location/renv in Renviron.site) the renv library in each blog post is simply a long list of symbolic links. And I don't think there is any need for blogdown to actually do anything overly complicated to use a blog post's renv.

In practical terms, I see two approaches: blogdown can either cd into each blog post directory before rendering it and thus automatically invoke renv (perhaps along the lines in my first comment), or else, blogdown can somehow load each blog post's ./.Rprofile file before rendering said blog post (which should achieve the same thing).

In any case, congratulations on a significantly improved v1.0+!

@yihui
Copy link
Member

yihui commented Mar 19, 2021

We had a meeting with Kevin (renv's author) today. He mentioned a few interesting methods related to using renv for individual Rmd documents: renv::activate(), renv::use(), and renv::embed(). If you want to learn more, perhaps @cderv can share more info.

@alexpghayes
Copy link

Are there any updates on this? I'm trying to revitalize an old blog post that relies on some archived packages and would love pointers on how to use renv on a per-qmd basis.

@cderv
Copy link
Collaborator

cderv commented Apr 29, 2022

per-qmd basis.

Just to clarify, are you using Quarto and .qmd formats ? Or you meant Rmd files ?

@alexpghayes
Copy link

I'm starting to write blogposts in .qmd so ideally some sort of renv environment specific to a .qmd file would be great, but if something only works for .Rmd files that's also fine.

@cderv
Copy link
Collaborator

cderv commented Apr 29, 2022

I am asking because Quarto has a freeze feature useful for that purpose of having old post stay the same (https://quarto.org/docs/computations/r.html#freezing-execution, https://quarto.org/docs/projects/code-execution.html#freeze).

Also, since blogdown v1, post are not rerendered by default. Which prevent so difficulties to manage blog with old post.

However, if you want to rerun some R code from old blog post, then renv should be indeed quite useful. We are thinking that the recent feature renv::use() would help : https://rstudio.github.io/renv/articles/use.html
renv::embed() (https://rstudio.github.io/renv/reference/embed.html) will be more helpful with R Markdown file, as it should be able to include a lockfile into a chunk directly.
We were not sure that a specific blogdown support for this is needed. Our understanding is that when the rendering happens, the specific package definition in renv::use() would take care of using the correct packages.
That is yet to be tried in a real use case 😅 Did you already look into this in the past ?

@solarchemist
Copy link
Author

There's a recent blog post with an example of using renv::use() (as @cderv already noted) for a Quarto blog that could probably be applied to blogdown too (not tested myself yet, I just thought that this issue could be a good place to put this reminder to myself). Discussed in toots by the blog post's author: 1, 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement
Projects
None yet
Development

No branches or pull requests

4 participants