Skip to content

Commit 5f2d286

Browse files
committed
tweak quarto_remove_extensions
1 parent c651265 commit 5f2d286

File tree

7 files changed

+103
-85
lines changed

7 files changed

+103
-85
lines changed

NAMESPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export(quarto_preview_stop)
1212
export(quarto_publish_app)
1313
export(quarto_publish_doc)
1414
export(quarto_publish_site)
15-
export(quarto_remove_extension)
15+
export(quarto_remove_extensions)
1616
export(quarto_render)
1717
export(quarto_serve)
1818
export(quarto_update_extension)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Add several new wrapper function:
44
- `quarto_list_extensions()` to list installed extensions using `quarto list extensions`
5+
- `quarto_remove_extensions()` to remove an installed extension using `quarto remove extensions`
56

67
- `quarto_preview()` gains a `quiet` argument to suppress any output from R or Quarto CLI (thanks, @cwickham, #232.)
78

R/remove.R

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
#'
33
#' Remove an extension in this folder or project by running `quarto remove`
44
#'
5-
#' # Extension Trust
6-
#'
7-
#' Quarto extensions may execute code when documents are rendered. Therefore, if
8-
#' you do not trust the author of an extension, we recommend that you do not
9-
#' install or use the extension.
10-
#' By default `no_prompt = FALSE` which means that
11-
#' the function will ask for explicit approval when used interactively, or
12-
#' disallow installation.
13-
#'
145
#' @inheritParams quarto_render
156
#'
16-
#' @param extension The extension to remove, either an archive or a GitHub
17-
#' repository as described in the documentation
18-
#' <https://quarto.org/docs/extensions/managing.html>.
7+
#' @param extension The extension name to remove, as in `quarto remove <extension-name>`.
198
#'
209
#' @param no_prompt Do not prompt to confirm approval to download external extension.
2110
#'
11+
#'
12+
#' @return Returns invisibly `TRUE` if the extension was removed, `FALSE` otherwise.
13+
#'
14+
#' @seealso `quarto_add_extension()` and [Quarto Website](https://quarto.org/docs/extensions/managing.html).
15+
#'
2216
#' @examples
2317
#' \dontrun{
2418
#' # Remove an already installed extension
25-
#' quarto_remove_extension("quarto-ext/fontawesome")
19+
#' quarto_remove_extensions("quarto-ext/fontawesome")
2620
#' }
27-
#' @importFrom rlang is_interactive
28-
#' @importFrom cli cli_abort
2921
#' @export
30-
quarto_remove_extension <- function(
22+
quarto_remove_extensions <- function(
3123
extension = NULL,
3224
no_prompt = FALSE,
3325
quiet = FALSE,
3426
quarto_args = NULL
3527
) {
3628
rlang::check_required(extension)
3729

30+
installed_extensions <- quarto_list_extensions()
31+
if (is.null(installed_extensions)) {
32+
if (!quiet) {
33+
cli::cli_alert_warning("No extensions installed.")
34+
}
35+
return(invisible(FALSE))
36+
}
37+
3838
quarto_bin <- find_quarto()
3939

4040
# This will ask for approval or stop installation
@@ -46,10 +46,15 @@ quarto_remove_extension <- function(
4646

4747
if (approval) {
4848
args <- c(extension, "--no-prompt", if (quiet) cli_arg_quiet(), quarto_args)
49-
quarto_remove(args, quarto_bin = quarto_bin, echo = TRUE)
49+
quarto_remove(args, quarto_bin = quarto_bin, echo = FALSE)
50+
if (!quiet) {
51+
cli::cli_alert_success(
52+
"Extension {.code {extension}} successfully removed."
53+
)
54+
}
5055
}
5156

52-
invisible()
57+
invisible(TRUE)
5358
}
5459

5560
quarto_remove <- function(args = character(), ...) {

R/utils-prompt.R

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
check_extension_approval <- function(
1+
check_approval <- function(
22
no_prompt = FALSE,
33
what = "Something",
4-
see_more_at = NULL
4+
see_more_at = NULL,
5+
prompt_message = NULL,
6+
interactive_info = NULL # could use `{ what }` as used in `cli_inform()`
57
) {
68
if (no_prompt) return(TRUE)
79

@@ -14,54 +16,57 @@ check_extension_approval <- function(
1416
}
1517
))
1618
} else {
17-
cli::cli_inform(c(
18-
"{what} may execute code when documents are rendered. ",
19-
"*" = "If you do not trust the author(s) of this {what}, we recommend that you do not install or use this {what}."
20-
))
21-
prompt_value <- tolower(readline(sprintf(
22-
"Do you trust the authors of this %s (Y/n)? ",
23-
what
24-
)))
25-
if (!prompt_value %in% "y") {
26-
cli::cli_inform("{what} not installed.")
27-
return(invisible(FALSE))
28-
} else {
29-
return(invisible(TRUE))
19+
if (!is.null(interactive_info)) {
20+
cli::cli_inform(interactive_info)
21+
}
22+
prompt_value <- tolower(readline(prompt_message))
23+
if (!prompt_value %in% c("", "y")) {
24+
cli::cli_inform(paste0(what, " not installed."))
3025
}
31-
return(invisible(TRUE))
26+
return(invisible(FALSE))
3227
}
28+
return(invisible(TRUE))
3329
}
3430

35-
check_removal_approval <- function(
31+
check_extension_approval <- function(
3632
no_prompt = FALSE,
3733
what = "Something",
3834
see_more_at = NULL
3935
) {
40-
if (no_prompt) return(TRUE)
36+
interactive_info <- c(
37+
"{what} may execute code when documents are rendered. ",
38+
"*" = "If you do not trust the author(s) of this {what}, we recommend that you do not install or use this {what}."
39+
)
4140

42-
if (!is_interactive()) {
43-
cli::cli_abort(c(
44-
"{ what } requires explicit approval.",
45-
">" = "Set {.arg no_prompt = TRUE} if you agree.",
46-
if (!is.null(see_more_at)) {
47-
c(i = "See more at {.url {see_more_at}}")
48-
}
49-
))
50-
} else {
51-
prompt_value <- tolower(readline(sprintf(
52-
"? Are you sure you'd like to remove %s (Y/n)? ",
53-
what
54-
)))
55-
if (!prompt_value %in% "y") {
56-
return(invisible(FALSE))
57-
}
58-
return(invisible(TRUE))
59-
}
41+
prompt_message <- sprintf(
42+
"Do you trust the authors of this %s (Y/n)? ",
43+
what
44+
)
45+
46+
check_approval(
47+
no_prompt = no_prompt,
48+
what = what,
49+
see_more_at = see_more_at,
50+
prompt_message = prompt_message,
51+
interactive_info = interactive_info
52+
)
6053
}
6154

62-
# Add binding to base R function for testthat mocking
63-
readline <- NULL
64-
# Add binding to function from other package for mocking later on
65-
is_interactive <- function(...) {
66-
rlang::is_interactive(...)
55+
check_removal_approval <- function(
56+
no_prompt = FALSE,
57+
what = "Something",
58+
see_more_at = NULL
59+
) {
60+
prompt_message <- sprintf(
61+
"Are you sure you'd like to remove %s (Y/n)? ",
62+
what
63+
)
64+
65+
check_approval(
66+
no_prompt = no_prompt,
67+
what = what,
68+
see_more_at = see_more_at,
69+
prompt_message = prompt_message,
70+
interactive_info = NULL
71+
)
6772
}

man/quarto_remove_extension.Rd renamed to man/quarto_remove_extensions.Rd

Lines changed: 11 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/remove.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Removing an extension
2+
3+
Code
4+
expect_false(quarto_remove_extension("quarto-ext/fontawesome", no_prompt = TRUE))
5+
Message
6+
! No extensions installed.
7+
8+
---
9+
10+
Code
11+
expect_true(quarto_remove_extension("quarto-ext/fontawesome", no_prompt = TRUE))
12+
Message
13+
v Extension `quarto-ext/fontawesome` successfully removed.
14+

tests/testthat/test-remove.R

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ test_that("Removing an extension", {
33
skip_if_offline("github.com")
44
qmd <- local_qmd_file(c("content"))
55
withr::local_dir(dirname(qmd))
6-
expect_null(quarto_remove_extension(
6+
expect_snapshot(expect_false(quarto_remove_extension(
77
"quarto-ext/fontawesome",
8-
no_prompt = TRUE,
9-
quiet = TRUE
10-
))
8+
no_prompt = TRUE
9+
)))
1110
quarto_add_extension("quarto-ext/fontawesome", no_prompt = TRUE, quiet = TRUE)
1211
expect_true(dir.exists("_extensions/quarto-ext/fontawesome"))
13-
quarto_remove_extension(
12+
expect_snapshot(expect_true(quarto_remove_extension(
1413
"quarto-ext/fontawesome",
15-
no_prompt = TRUE,
16-
quiet = TRUE
17-
)
18-
expect_true(!dir.exists("_extensions/quarto-ext/fontawesome"))
14+
no_prompt = TRUE
15+
)))
16+
expect_false(dir.exists("_extensions"))
1917
})

0 commit comments

Comments
 (0)