Skip to content

Commit fc8472c

Browse files
jennybcolivroy
andauthored
Use cli (#1956)
* Init article on the conversion task * Build up the cli-based UI in one place * Introduce ui_cli_bullets() * author.R * Factor out the path-processing logic into ui_path_impl() * addin.R * ui_bullets() is better because shorter * badge.R * ui_abort() feels more consistent with everything else * Introduce ui_code_snippet() * block.R * Some testing improvements * Test ui_code_snippet() * Replace all calls to ui_code_block() * Typo * Update conversion article * browse.R * Eliminate usage of ui_warn() * ci.R * code_of_conduct.R * course.R * coverage.R * cpp11.R * Single quote inline .field if no color * create.R * data.R * description.R * directory.R * edit.R * git-default-branch.R * git.R * Test bulletize() and usethis_map_cli() * github-actions.R * .val seems like a better default for usethis * github-labels.R * github-pages.R * github.R + check_current_branch() * github_token.R * Remove hd_line() which is not used anywhere at this point * Notes * Modernize kv_line() + other changes to improve git_sitrep() * github_token.R * helpers.R * issue.R * license.R * lifecycle.R * logo.R * news.R * package.R * pkgdown.R * Provide default bullets in ui_abort() * pr.R * proj-desc.R * proj.R * rcpp.R * readme.R * release.R * rename-files.R * revdep.R * roxygen.R * rprofile.R * rstudio.R * sitrep.R * spelling.R * template.R * test.R * tibble.R * tidyverse.R * upkeep.R * use_github_file.R * use_import_fun.R * usethis-defunct.R * Rename to ui_legacy_bullet(); catch up on note-taking * utils-git.R * utils.R * version.R * vignette.R * write.R * utils-github.R * Add snapshot tests for remote GitHub configurations * Finish converting UI around GitHub remote configurations * Refactor flaky test * Better organization * Catch up on note-taking * Work on making the article actually render the way I want * Mark ui_*() functions as superseded * Mark ui_yeah() and ui_no() as superseded * Work on kv_line() * Use ui_yep() and ui_nah() everywhere * Re-align filenames re: legacy ui * OMG I don't want people to depend on usethis for ui functions * Switch to ui_nah() , for real * Make sure I don't call into the legacy file * Deal with stragglers that are not TODOs * Update principles.md * NEWS bullet * Yet another straggler * Deal with utils::menu() prep and other unusual stuff * Make test less sensitive to local conditions * Article needs asciicast * Increase width to forcibly prevent snapshot diff due to linebreaks I guess temp paths vary in length, even across separate runs on the same platform? * Organize the articles * Update README * Make the width even larger??? * Apply suggestions from code review Co-authored-by: olivroy <[email protected]> * Update snapshot * How about cli.width????? * YOLO * `.run` fixups * These run afoul of the `.run` rules, so why bother * Better captures the intent --------- Co-authored-by: olivroy <[email protected]>
1 parent ce6ed46 commit fc8472c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3631
-1485
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Suggests:
5353
spelling (>= 1.2),
5454
styler (>= 1.2.0),
5555
testthat (>= 3.1.8)
56-
Config/Needs/website: tidyverse/tidytemplate, xml2
56+
Config/Needs/website: r-lib/asciicast, tidyverse/tidytemplate, xml2
5757
Config/testthat/edition: 3
5858
Config/testthat/parallel: TRUE
5959
Config/testthat/start-first: github-actions, release

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
S3method(format,github_remote_config)
44
S3method(print,github_remote_config)
55
S3method(print,sitrep)
6+
S3method(usethis_map_cli,"NULL")
7+
S3method(usethis_map_cli,character)
8+
S3method(usethis_map_cli,default)
69
export(browse_circleci)
710
export(browse_cran)
811
export(browse_github)

NEWS.md

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

3+
* The `ui_*()` functions have been marked as
4+
[superseded](https://lifecycle.r-lib.org/articles/stages.html#superseded).
5+
External users of these functions are encouraged to use the
6+
[cli package](https://cli.r-lib.org/) instead.
7+
The cli package did not have the required functionality when the
8+
`usethis::ui_*()` functions were first created, but it does now and it's the
9+
superior option.
10+
There is a cli vignette about how to make this transition:
11+
`vignette("usethis-ui", package = "cli")`.
12+
13+
usethis no longer uses the `ui_*()` functions internally, in favor of new
14+
cli-based helpers that are not exported.
15+
316
# usethis 2.2.3
417

518
* Patch release with changes to `.Rd` files requested by CRAN.

R/addin.R

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ use_addin <- function(addin = "new_addin", open = rlang::is_interactive()) {
1515
if (!file_exists(addin_dcf_path)) {
1616
create_directory(proj_path("inst", "rstudio"))
1717
file_create(addin_dcf_path)
18-
ui_done("Creating {ui_path(addin_dcf_path)}")
18+
ui_bullets(c("v" = "Creating {.path {pth(addin_dcf_path)}}"))
1919
}
2020

2121
addin_info <- render_template("addins.dcf", data = list(addin = addin))
2222
addin_info[length(addin_info) + 1] <- ""
2323
write_utf8(addin_dcf_path, addin_info, append = TRUE)
24-
ui_done("Adding binding to {ui_code(addin)} to addins.dcf.")
24+
ui_bullets(c(
25+
"v" = "Adding binding to {.fun {addin}} to {.path addins.dcf}"
26+
))
2527

2628
if (open) {
2729
edit_file(addin_dcf_path)

R/author.R

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ use_author <- function(given = NULL, family = NULL, ..., role = "ctb") {
6060
author <- utils::person(given = given, family = family, role = role, ...)
6161
aut_fmt <- format(author, style = 'text')
6262
if (authors_at_r_already) {
63-
ui_done("
64-
Adding to {ui_field('Authors@R')} in DESCRIPTION:
65-
{aut_fmt}")
63+
ui_bullets(c(
64+
"v" = "Adding to {.field Authors@R} in DESCRIPTION:",
65+
" " = "{aut_fmt}"
66+
))
6667
} else {
67-
ui_done("
68-
Creating {ui_field('Authors@R')} field in DESCRIPTION and adding:
69-
{aut_fmt}")
68+
ui_bullets(c(
69+
"v" = "Creating {.field Authors@R} field in DESCRIPTION and adding:",
70+
" " = "{aut_fmt}"
71+
))
7072
}
7173
d$add_author(given = given, family = family, role = role, ...)
7274

@@ -84,17 +86,17 @@ challenge_legacy_author_fields <- function(d = proj_desc()) {
8486
return(invisible())
8587
}
8688

87-
ui_oops("
88-
Found legacy {ui_field('Author')} and/or {ui_field('Maintainer')} field \\
89-
in DESCRIPTION.
90-
usethis only supports modification of the {ui_field('Authors@R')} field.")
91-
ui_info("
92-
We recommend one of these paths forward:
93-
* Delete these fields and rebuild with {ui_code('use_author()')}.
94-
* Convert to {ui_field('Authors@R')} with {ui_code('desc::desc_coerce_authors_at_r()')},
95-
then delete the legacy fields.")
96-
if (ui_yeah("Do you want to cancel this operation and sort that out first?")) {
97-
ui_stop("Cancelling.")
89+
ui_bullets(c(
90+
"x" = "Found legacy {.field Author} and/or {.field Maintainer} field in
91+
DESCRIPTION.",
92+
" " = "usethis only supports modification of the {.field Authors@R} field.",
93+
"i" = "We recommend one of these paths forward:",
94+
"_" = "Delete the legacy fields and rebuild with {.fun use_author}; or",
95+
"_" = "Convert to {.field Authors@R} with
96+
{.fun desc::desc_coerce_authors_at_r}, then delete the legacy fields."
97+
))
98+
if (ui_yep("Do you want to cancel this operation and sort that out first?")) {
99+
ui_abort("Cancelling.")
98100
}
99101
invisible()
100102
}
@@ -108,10 +110,10 @@ check_author_is_novel <- function(given = NULL, family = NULL, d = proj_desc())
108110
})
109111
if (any(m)) {
110112
aut_name <- glue("{given %||% ''} {family %||% ''}")
111-
usethis_abort(c(
112-
"{.val {aut_name}} already appears in {.val Authors@R}.",
113-
"Please make the desired change directly in DESCRIPTION or call the \\
114-
desc package directly."
113+
ui_abort(c(
114+
"x" = "{.val {aut_name}} already appears in {.field Authors@R}.",
115+
" " = "Please make the desired change directly in DESCRIPTION or call the
116+
{.pkg desc} package directly."
115117
))
116118
}
117119
invisible()
@@ -129,10 +131,11 @@ challenge_default_author <- function(d = proj_desc()) {
129131
)
130132

131133
if (any(m)) {
132-
ui_info("
133-
{ui_field('Authors@R')} appears to include a placeholder author:
134-
{format(default_author, style = 'text')}")
135-
if(is_interactive() && ui_yeah("Would you like to remove it?")) {
134+
ui_bullets(c(
135+
"i" = "{.field Authors@R} appears to include a placeholder author:",
136+
" " = "{format(default_author, style = 'text')}"
137+
))
138+
if(is_interactive() && ui_yep("Would you like to remove it?")) {
136139
# TODO: Do I want to suppress this output?
137140
# Authors removed: First Last, NULL NULL.
138141
do.call(d$del_author, unclass(default_author)[[1]])

R/badge.R

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,25 @@ NULL
4343
use_badge <- function(badge_name, href, src) {
4444
path <- find_readme()
4545
if (is.null(path)) {
46-
ui_oops("
47-
Can't find a README for the current project.
48-
See {ui_code('usethis::use_readme_rmd()')} for help creating this file.
49-
Badge link can only be printed to screen.
50-
")
46+
ui_bullets(c(
47+
"!" = "Can't find a README for the current project.",
48+
"i" = "See {.fun usethis::use_readme_rmd} for help creating this file.",
49+
"i" = "Badge link will only be printed to screen."
50+
))
5151
path <- "README"
5252
}
5353
changed <- block_append(
54-
glue("{ui_field(badge_name)} badge"),
54+
glue("{badge_name} badge"),
5555
glue("[![{badge_name}]({src})]({href})"),
5656
path = path,
5757
block_start = badge_start,
5858
block_end = badge_end
5959
)
6060

6161
if (changed && path_ext(path) == "Rmd") {
62-
ui_todo("Re-knit {ui_path(path)} with {ui_code('devtools::build_readme()')}")
62+
ui_bullets(c(
63+
"_" = "Re-knit {.path {pth(path)}} with {.fun devtools::build_readme}."
64+
))
6365
}
6466
invisible(changed)
6567
}
@@ -153,10 +155,10 @@ use_posit_cloud_badge <- function(url) {
153155
img <- "https://img.shields.io/badge/launch-posit%20cloud-447099?style=flat"
154156
use_badge("Launch Posit Cloud", url, img)
155157
} else {
156-
usethis_abort("
157-
{.fun usethis::use_posit_cloud_badge} requires a link to an \\
158-
existing Posit Cloud project of the form \\
159-
{.val https://posit.cloud/content/<project-id>} or \\
158+
ui_abort("
159+
{.fun usethis::use_posit_cloud_badge} requires a link to an
160+
existing Posit Cloud project of the form
161+
{.val https://posit.cloud/content/<project-id>} or
160162
{.val https://posit.cloud/spaces/<space-id>/content/<project-id>}.")
161163
}
162164

R/block.R

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ block_append <- function(desc, value, path,
1616
}
1717

1818
if (is.null(block_lines)) {
19-
ui_todo("
20-
Copy and paste the following lines into {ui_path(path)}:")
21-
ui_code_block(c(block_prefix, block_start, value, block_end, block_suffix))
19+
ui_bullets(c(
20+
"_" = "Copy and paste the following lines into {.path {pth(path)}}:"
21+
))
22+
ui_code_snippet(c(block_prefix, block_start, value, block_end, block_suffix))
2223
return(FALSE)
2324
}
2425

25-
ui_done("Adding {desc} to {ui_path(path)}")
26+
ui_bullets(c("v" = "Adding {.val {desc}} to {.path {pth(path)}}."))
2627

2728
start <- block_lines[[1]]
2829
end <- block_lines[[2]]
@@ -54,8 +55,10 @@ block_replace <- function(desc, value, path,
5455
}
5556

5657
if (is.null(block_lines)) {
57-
ui_todo("Copy and paste the following lines into {ui_value(path)}:")
58-
ui_code_block(c(block_start, value, block_end))
58+
ui_bullets(c(
59+
"_" = "Copy and paste the following lines into {.path {pth(path)}}:"
60+
))
61+
ui_code_snippet(c(block_start, value, block_end))
5962
return(invisible(FALSE))
6063
}
6164

@@ -67,7 +70,7 @@ block_replace <- function(desc, value, path,
6770
return(invisible(FALSE))
6871
}
6972

70-
ui_done("Replacing {desc} in {ui_path(path)}")
73+
ui_bullets(c("v" = "Replacing {desc} in {.path {pth(path)}}."))
7174

7275
lines <- c(
7376
lines[seq2(1, start - 1L)],
@@ -99,10 +102,11 @@ block_find <- function(lines, block_start = "# <<<", block_end = "# >>>") {
99102
}
100103

101104
if (!(length(start) == 1 && length(end) == 1 && start < end)) {
102-
ui_stop(
103-
"Invalid block specification.
104-
Must start with {ui_code(block_start)} and end with {ui_code(block_end)}"
105-
)
105+
ui_abort(c(
106+
"Invalid block specification.",
107+
"Must start with {.code {block_start}} and end with
108+
{.code {block_end}}."
109+
))
106110
}
107111

108112
c(start + 1L, end - 1L)

R/browse.R

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ browse_package <- function(package = NULL) {
7777
grl <- set_names(grl$url, nm = grl$remote)
7878
parsed <- parse_github_remotes(grl)
7979
urls <- c(urls, glue_data(parsed, "https://{host}/{repo_owner}/{repo_name}"))
80-
details <- c(details, map(parsed$name, ~ glue("{ui_value(.x)} remote")))
80+
details <- c(
81+
details,
82+
map(parsed$name, ~ cli::cli_fmt(cli::cli_text("{.val {.x}} remote")))
83+
)
8184
}
8285

8386
desc_urls_dat <- desc_urls(package, include_cran = TRUE)
@@ -86,11 +89,11 @@ browse_package <- function(package = NULL) {
8689
details,
8790
map(
8891
desc_urls_dat$desc_field,
89-
~ if (is.na(.x)) "CRAN" else glue("{ui_field(.x)} field in DESCRIPTION")
92+
~ if (is.na(.x)) "CRAN" else cli::cli_fmt(cli::cli_text("{.field {.x}} field in DESCRIPTION"))
9093
)
9194
)
9295
if (length(urls) == 0) {
93-
ui_oops("Can't find any URLs")
96+
ui_bullets(c(x = "Can't find any URLs."))
9497
return(invisible(character()))
9598
}
9699

@@ -171,15 +174,17 @@ github_url <- function(package = NULL) {
171174

172175
if (is.null(desc_urls_dat)) {
173176
if (is.null(package)) {
174-
ui_stop("
175-
Project {ui_value(project_name())} has no DESCRIPTION file and \\
176-
has no GitHub remotes configured
177-
No way to discover URLs")
177+
ui_abort(c(
178+
"Project {.val {project_name()}} has no DESCRIPTION file and
179+
has no GitHub remotes configured.",
180+
"No way to discover URLs."
181+
))
178182
} else {
179-
ui_stop("
180-
Can't find DESCRIPTION for package {ui_value(package)} locally \\
181-
or on CRAN
182-
No way to discover URLs")
183+
ui_abort(c(
184+
"Can't find DESCRIPTION for package {.pkg {package}} locally
185+
or on CRAN.",
186+
"No way to discover URLs."
187+
))
183188
}
184189
}
185190

@@ -191,13 +196,13 @@ github_url <- function(package = NULL) {
191196
}
192197

193198
if (is.null(package)) {
194-
ui_stop("
195-
Project {ui_value(project_name())} has no GitHub remotes configured \\
196-
and has no GitHub URLs in DESCRIPTION")
199+
ui_abort("
200+
Project {.val {project_name()}} has no GitHub remotes configured
201+
and has no GitHub URLs in DESCRIPTION.")
197202
}
198-
ui_warn("
199-
Package {ui_value(package)} has no GitHub URLs in DESCRIPTION
200-
Trying the GitHub CRAN mirror")
203+
cli::cli_warn(c(
204+
"!" = "Package {.val {package}} has no GitHub URLs in DESCRIPTION.",
205+
" " = "Trying the GitHub CRAN mirror."))
201206
glue_chr("https://github.com/cran/{package}")
202207
}
203208

R/ci.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ use_circleci_badge <- function(repo_spec = NULL) {
8282

8383
circleci_activate <- function(owner, browse = is_interactive()) {
8484
url <- glue("https://circleci.com/add-projects/gh/{owner}")
85-
ui_todo("Turn on CircleCI for your repo at {url}")
85+
ui_bullets(c(
86+
"_" = "Turn on CircleCI for your repo at {.url {url}}."
87+
))
8688
if (browse) {
8789
utils::browseURL(url)
8890
}

R/code-of-conduct.R

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
#' @export
2424
use_code_of_conduct <- function(contact, path = NULL) {
2525
if (missing(contact)) {
26-
ui_stop("
27-
{ui_code('use_code_of_conduct()')} requires contact details in \\
28-
first argument")
26+
ui_abort("
27+
{.fun use_code_of_conduct} requires contact details in first argument.")
2928
}
3029

3130
new <- use_coc(contact = contact, path = path)
@@ -35,13 +34,16 @@ use_code_of_conduct <- function(contact, path = NULL) {
3534
href <- sub("/$", "", href)
3635
href <- paste0(href, "/CODE_OF_CONDUCT.html")
3736

38-
ui_todo("You may also want to describe the code of conduct in your README:")
39-
ui_code_block("
37+
ui_bullets(c(
38+
"_" = "You may also want to describe the code of conduct in your README:"
39+
))
40+
ui_code_snippet("
4041
## Code of Conduct
4142
4243
Please note that the {project_name()} project is released with a \\
4344
[Contributor Code of Conduct]({href}). By contributing to this project, \\
44-
you agree to abide by its terms."
45+
you agree to abide by its terms.",
46+
language = ""
4547
)
4648

4749
invisible(new)

0 commit comments

Comments
 (0)