Skip to content

Commit 7a71a95

Browse files
authored
Add a {test} for ui_escape_glue() helper (#2171)
* Escape curly braces in pr_title Added a simple helper to escape curly braces for glue (`ui_escape_glue()` in `utils-ui.R`), then applied it in the relevant `pr_*()` functions. I used Positron Assistant and Google Gemini as a test on this, then revised their fixes significantly. Do you want to add a test for this in `manual-pr-functions.R`? Or I could automate this stuff with mocked github API calls if you want to go that far. Fixes #2107 * Do the escape once in the sub-function toward the end. * Add a {test} for `ui_escape_glue()` helper And implicitly test the curly brace thing. * Don't escape in un-glued bullets. * Add NEWS.md bullet. @jennybc I added the `Fixes #2107` to the description, but it didn't retroactively link to the issue, so make sure that's showing in Development to auto-close.
1 parent 3eb88fc commit 7a71a95

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# usethis (development version)
22

3+
* `pr_resume()` (without a specific `branch`) and `pr_fetch()` (without a specific `number`) no longer error when a branch name contains curly braces (#2107, @jonthegeek).
4+
35
# usethis 3.2.1
46

57
* `create_quarto_project()` exits early if the Quarto CLI does not appear to be

R/pr.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ choose_branch <- function(exclude = character()) {
944944
)
945945
at_user <- glue("@{pr_user}")
946946
template <- ui_pre_glue(
947-
"{pretty_name} {cli::symbol$arrow_right} <<href_number>> ({.field <<at_user>>}): {.val <<pr_title>>}"
947+
"{pretty_name} {cli::symbol$arrow_right} <<href_number>> ({.field <<at_user>>}): {.val <<ui_escape_glue(pr_title)>>}"
948948
)
949949
cli::format_inline(template)
950950
}
@@ -988,14 +988,15 @@ choose_pr <- function(tr = NULL, pr_dat = NULL) {
988988
function(pr_number, pr_html_url, pr_user, pr_state, pr_title) {
989989
href_number <- ui_pre_glue("{.href [PR #<<pr_number>>](<<pr_html_url>>)}")
990990
at_user <- glue("@{pr_user}")
991+
pr_title_escaped <- ui_escape_glue(pr_title)
991992
if (some_closed) {
992993
template <- ui_pre_glue(
993-
"<<href_number>> ({.field <<at_user>>}, {pr_state}): {.val <<pr_title>>}"
994+
"<<href_number>> ({.field <<at_user>>}, {pr_state}): {.val <<pr_title_escaped>>}"
994995
)
995996
cli::format_inline(template)
996997
} else {
997998
template <- ui_pre_glue(
998-
"<<href_number>> ({.field <<at_user>>}): {.val <<pr_title>>}"
999+
"<<href_number>> ({.field <<at_user>>}): {.val <<pr_title_escaped>>}"
9991000
)
10001001
cli::format_inline(template)
10011002
}

R/utils-ui.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ ui_pre_glue <- function(..., .envir = parent.frame()) {
162162
glue(..., .open = "<<", .close = ">>", .envir = .envir)
163163
}
164164

165+
ui_escape_glue <- function(x) {
166+
gsub("([{}])", "\\1\\1", x)
167+
}
168+
169+
165170
bulletize <- function(x, bullet = "*", n_show = 5, n_fudge = 2) {
166171
n <- length(x)
167172
n_show_actual <- compute_n_show(n, n_show, n_fudge)

tests/testthat/test-utils-ui.R

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,17 @@ cli::test_that_cli(
267267
},
268268
configs = c("plain", "fancy")
269269
)
270+
271+
test_that("ui_escape_glue() doubles curly braces", {
272+
expect_equal(ui_escape_glue("no braces"), "no braces")
273+
expect_equal(ui_escape_glue("one { brace"), "one {{ brace")
274+
expect_equal(ui_escape_glue("one } brace"), "one }} brace")
275+
expect_equal(
276+
ui_escape_glue("A {brace_set} in text"),
277+
"A {{brace_set}} in text"
278+
)
279+
expect_equal(
280+
ui_escape_glue("{multiple} {brace} {sets}"),
281+
"{{multiple}} {{brace}} {{sets}}"
282+
)
283+
})

0 commit comments

Comments
 (0)