cli - Helpers for Developing Command Line Interfaces

- rOpenSci co-working session -

Athanasia Monika Mowinckel

2023-10-03

What is cli & why use it?

Prettify console output

Running analysis 1
- subsetting data
- submitting job #746
Finish 1
- outputing data
/path/to/file
── Running analysis 1 ──────────────────────────────────────────────────────────
✔ subsetting data
✔ submitting job #746
── Finishing up ──
outputing data to:
/path/to/file

Organise output

- cli_unicode_option : NULL
- symbol_charset     : UTF-8
- console_utf8       : TRUE
- latex_active       : FALSE
- num_colors         : 1
- console_width      : 80

Clear messages

n <- "boo"
cli_abort(c(
        "{.var n} must be a numeric vector",
  "x" = "You've supplied a {.cls {class(n)}} vector."
))
Error:
! `n` must be a numeric vector
✖ You've supplied a <character> vector.

Clear messages

len <- 26
idx <- 100
cli_abort(c(
        "Must index an existing element:",
  "i" = "There {?is/are} {len} element{?s}.",
  "x" = "You've tried to subset element {idx}."
))
Error:
! Must index an existing element:
ℹ There are 26 elements.
✖ You've tried to subset element 100.

Errors users can’t understand

subset <- function(df = data){
  if(missing(df))
    df <- data
  df$hello
}
subset()
Error in df$hello: object of type 'closure' is not subsettable

Errors users can understand, but are ugly

subset <- function(df = data){
  if(missing(df))
    df <- data
  if(!"hello" %in% names(df))
    stop("Column 'hello' not in the data")
  df$hello
}
subset()
Error in subset(): Column 'hello' not in the data

Errors users can understand, but are ugly

subset <- function(df, column){
  if(!column %in% names(df))
    stop(sprintf("Column '%s' not in the data",
                 column))
  df[, column]
}
subset(mtcars, column = "bla")
Error in subset(mtcars, column = "bla"): Column 'bla' not in the data

Errors users can understand, and are pretty

subset <- function(df, column){
  if(!column %in% names(df))
    cli::cli_abort("Column '{column}' not in the data")
  df[, column]
}
subset(mtcars, column = "bla")
Error in `subset()`:
! Column 'bla' not in the data