Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export(use_rcpp)
export(use_rcpp_armadillo)
export(use_rcpp_eigen)
export(use_readme_md)
export(use_readme_qmd)
export(use_readme_rmd)
export(use_release_issue)
export(use_reprex)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# usethis (development version)

* `use_readme_qmd()` creates a starter `README.qmd` with Quarto-flavored YAML frontmatter, analogous to `use_readme_rmd()` (#1671). Thanks @VisruthSK for getting the ball rolling.

* `use_pipe()` is now deprecated (@math-mcshane, #2124).

* `use_claude_code()` is an experimental helper to set up Claude code in an R package in the same way as the tidyverse team (#2195).
Expand Down
8 changes: 4 additions & 4 deletions R/badge.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#' and link out to relevant external resources. To allow badges to be added
#' automatically, ensure your badge block starts with a line containing only
#' `<!-- badges: start -->` and ends with a line containing only
#' `<!-- badges: end -->`. The templates used by [use_readme_md()] and
#' [use_readme_rmd()] include this block.
#' `<!-- badges: end -->`. The templates used by [use_readme_qmd()],
#' [use_readme_rmd()], and [use_readme_md()] and include this block.
#'
#' @details
#'
Expand Down Expand Up @@ -53,7 +53,7 @@ use_badge <- function(badge_name, href, src) {
if (is.null(path)) {
ui_bullets(c(
"!" = "Can't find a README for the current project.",
"i" = "See {.fun usethis::use_readme_rmd} for help creating this file.",
"i" = "See {.fun usethis::use_readme_qmd} or {.fun usethis::use_readme_rmd} for help creating this file.",
"i" = "Badge link will only be printed to screen."
))
path <- "README"
Expand Down Expand Up @@ -224,5 +224,5 @@ badge_start <- "<!-- badges: start -->"
badge_end <- "<!-- badges: end -->"

find_readme <- function() {
path_first_existing(proj_path(c("README.Rmd", "README.md")))
path_first_existing(proj_path(c("README.qmd", "README.Rmd", "README.md")))
}
87 changes: 74 additions & 13 deletions R/readme.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@
#' * R code to install from GitHub, if GitHub usage detected
#' * a basic example
#'
#' Use `Rmd` if you want a rich intermingling of code and output. Use `md` for a
#' basic README. `README.Rmd` will be automatically added to `.Rbuildignore`.
#' The resulting README is populated with default YAML frontmatter and R fenced
#' code blocks (`md`) or chunks (`Rmd`).
#' Use `qmd` or `Rmd` if you want a rich intermingling of code and output.
#' Use `md` for a basic README. `README.qmd` and `README.Rmd` will be
#' automatically added to `.Rbuildignore`. The resulting README is populated
#' with default YAML frontmatter and R fenced code blocks (`md`) or
#' chunks (`qmd`, `Rmd`).
#'
#' If you use `Rmd`, you'll still need to render it regularly, to keep
#' `README.md` up-to-date. `devtools::build_readme()` is handy for this. You
#' could also use GitHub Actions to re-render `README.Rmd` every time you push.
#' An example workflow can be found in the `examples/` directory here:
#' If you use `qmd` or `Rmd`, you'll still need to render it regularly, to
#' keep `README.md` up-to-date. `devtools::build_readme()` is handy for
#' this. You could also use GitHub Actions to re-render `README.qmd` or
#' `README.Rmd` every time you push. An example workflow can be found in
#' the `examples/` directory here:
#' <https://github.com/r-lib/actions/>.
#'
#' If the current project is a Git repo, then `use_readme_rmd()` automatically
#' configures a pre-commit hook that helps keep `README.Rmd` and `README.md`,
#' synchronized. The hook creates friction if you try to commit when
#' `README.Rmd` has been edited more recently than `README.md`. If this hook
#' causes more problems than it solves for you, it is implemented in
#' If the current project is a Git repo, then `use_readme_qmd()` and
#' `use_readme_rmd()` automatically configure a pre-commit hook that helps
#' keep `README.md` synchronized with the source file. The hook creates
#' friction if you try to commit when `README.qmd` or `README.Rmd` has
#' been edited more recently than `README.md`. If this hook causes more
#' problems than it solves for you, it is implemented in
#' `.git/hooks/pre-commit`, which you can modify or even delete.
#'
#' @inheritParams use_template
Expand All @@ -31,6 +34,7 @@
#' @export
#' @examples
#' \dontrun{
#' use_readme_qmd()
#' use_readme_rmd()
#' use_readme_md()
#' }
Expand Down Expand Up @@ -65,6 +69,63 @@ use_readme_rmd <- function(open = rlang::is_interactive()) {
))
}

ui_bullets(c(
"_" = "Use {.fun devtools::build_readme} to render {.path {pth('README.Rmd')}}."
))

if (uses_git()) {
use_git_hook(
"pre-commit",
render_template("readme-rmd-pre-commit.sh")
)
}

invisible(TRUE)
}

#' @export
#' @rdname use_readme_rmd
use_readme_qmd <- function(open = rlang::is_interactive()) {
check_is_project()

is_pkg <- is_package()
repo_spec <- tryCatch(target_repo_spec(ask = FALSE), error = function(e) NULL)
nm <- if (is_pkg) "Package" else "Project"
data <- list2(
!!nm := project_name(),
on_github = !is.null(repo_spec),
github_spec = repo_spec
)

new <- use_template(
if (is_pkg) "package-README-qmd" else "project-README-qmd",
"README.qmd",
data = data,
ignore = is_pkg,
open = open
)
if (!new) {
return(invisible(FALSE))
}

if (is_pkg && !data$on_github) {
ui_bullets(c(
"_" = "Update {.path {pth('README.qmd')}} to include installation instructions."
))
}

if (file_exists(proj_path("README.Rmd"))) {
ui_bullets(c(
"!" = "A pre-existing {.path {pth('README.Rmd')}} was found.",
"_" = "Migrate its content to {.path {pth('README.qmd')}}.",
"_" = "Delete {.path {pth('README.Rmd')}} when the migration is done."
))
}

ui_bullets(c(
"_" = "Use {.fun devtools::build_readme} to render {.path {pth('README.qmd')}}."
))

if (uses_git()) {
use_git_hook(
"pre-commit",
Expand Down
3 changes: 2 additions & 1 deletion R/release.R
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ release_checklist <- function(version, on_cran, target_repo = NULL) {
has_news <- file_exists(proj_path("NEWS.md"))
has_pkgdown <- uses_pkgdown()
has_lifecycle <- proj_desc()$has_dep("lifecycle")
has_readme <- file_exists(proj_path("README.Rmd"))
has_readme <- file_exists(proj_path("README.Rmd")) ||
file_exists(proj_path("README.qmd"))
has_github_links <- has_github_links(target_repo)
is_posit_pkg <- is_posit_pkg()
milestone_num <- gh_milestone_number(target_repo, version)
Expand Down
2 changes: 1 addition & 1 deletion R/tidyverse.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ create_tidy_package <- function(path, copyright_holder = NULL) {
use_mit_license(copyright_holder)
use_tidy_description()

use_readme_rmd(open = FALSE)
use_readme_qmd(open = FALSE)
use_lifecycle_badge("experimental")
use_cran_badge()

Expand Down
8 changes: 6 additions & 2 deletions R/upkeep.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ upkeep_checklist <- function(target_repo = NULL) {
has_github_links <- has_github_links(target_repo)

bullets <- c(
todo("`usethis::use_readme_rmd()`", !file_exists(proj_path("README.Rmd"))),
todo(
"`usethis::use_readme_qmd()` or `usethis::use_readme_rmd()`",
!file_exists(proj_path("README.Rmd")) &&
!file_exists(proj_path("README.qmd"))
),
todo("`usethis::use_roxygen_md()`", !is_true(uses_roxygen_md())),
todo("`usethis::use_github_links()`", !has_github_links),
todo("`usethis::use_pkgdown_github_pages()`", !uses_pkgdown()),
Expand Down Expand Up @@ -161,7 +165,7 @@ tidy_upkeep_checklist <- function(
bullets,
"### Pre-history",
"",
todo("`usethis::use_readme_rmd()`"),
todo("`usethis::use_readme_qmd()` or `usethis::use_readme_rmd()`"),
todo("`usethis::use_roxygen_md()`"),
todo("`usethis::use_github_links()`"),
todo("`usethis::use_pkgdown_github_pages()`"),
Expand Down
71 changes: 71 additions & 0 deletions inst/templates/package-README-qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
format:
gfm:
default-image-extension: ""
---

<!-- README.md is generated from README.qmd. Please edit that file -->

```{r}
#| include: false
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```

# {{{ Package }}}

<!-- badges: start -->
<!-- badges: end -->

The goal of {{{ Package }}} is to ...

## Installation

{{#on_github}}
You can install the development version of {{{ Package }}} from [GitHub](https://github.com/) with:

``` r
# install.packages("pak")
pak::pak("{{{ github_spec }}}")
```
{{/on_github}}
{{^on_github}}
You can install the development version of {{{ Package }}} like so:

``` r
# FILL THIS IN! HOW CAN PEOPLE INSTALL YOUR DEV PACKAGE?
```
{{/on_github}}

## Example

This is a basic example which shows you how to solve a common problem:

```{r}
#| label: example
library({{Package}})
## basic example code
```

What is special about using `README.qmd` instead of just `README.md`? You can include R chunks like so:

```{r}
#| label: cars
summary(cars)
```

You'll still need to render `README.qmd` regularly, to keep `README.md` up-to-date. `devtools::build_readme()` is handy for this.

You can also embed plots, for example:

```{r}
#| label: pressure
#| echo: false
plot(pressure)
```

In that case, don't forget to commit and push the resulting figure files, so they display on GitHub and CRAN.
41 changes: 41 additions & 0 deletions inst/templates/project-README-qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
format:
gfm:
default-image-extension: ""
---

<!-- README.md is generated from README.qmd. Please edit that file -->

```{r}
#| include: false
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```

# {{{ Project }}}

<!-- badges: start -->
<!-- badges: end -->

The goal of {{{ Project }}} is to ...

What is special about using `README.qmd` instead of just `README.md`? You can include R chunks like so:

```{r}
#| label: cars
summary(cars)
```

You'll still need to render `README.qmd` regularly, to keep `README.md` up-to-date.

You can also embed plots, for example:

```{r}
#| label: pressure
#| echo: false
plot(pressure)
```

In that case, don't forget to commit and push the resulting figure files, so they display on GitHub.
8 changes: 4 additions & 4 deletions inst/templates/readme-rmd-pre-commit.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/bin/bash
README=($(git diff --cached --name-only | grep -Ei '^README\.[R]?md$'))
README=($(git diff --cached --name-only | grep -Ei '^README\.[qR]?md$'))
MSG="use 'git commit --no-verify' to override this check"

if [[ ${#README[@]} == 0 ]]; then
exit 0
fi

if [[ README.Rmd -nt README.md ]]; then
echo -e "README.md is out of date; please re-knit README.Rmd\n$MSG"
if [[ README.qmd -nt README.md ]] || [[ README.Rmd -nt README.md ]]; then
echo -e "README.md is out of date; please re-render README.qmd/README.Rmd\n$MSG"
exit 1
elif [[ ${#README[@]} -lt 2 ]]; then
echo -e "README.Rmd and README.md should be both staged\n$MSG"
echo -e "README.qmd/README.Rmd and README.md should be both staged\n$MSG"
exit 1
fi
4 changes: 2 additions & 2 deletions man/badges.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 20 additions & 13 deletions man/use_readme_rmd.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading