Learn to Write Command Line Utilities in R - part 7

Check out the first post in this series for an index of all the other posts.

In this post, we’re going to look at extending the work we’ve done earlier by adding another flag into the mix. We’ll use that to improve the way the output of the tool looks when it runs.

First of all, we need to add our new flag to the argparser config.

# Add a pretty printing flag
p <- add_argument(p, "--pretty", help="pretty print the output", flag=TRUE)

And we’ll also need a new function to handle those inputs.

pretty_print <- function(...){
  if (isTRUE(argv$pretty)){
    debug_msg("Pretty printing is enabled")
    cli::cat_boxx(...)
  } else {
    debug_msg("Pretty printing is not enabled")
    cat(...,"\n")
  }
}

This function will be used to print our output to the console. If the -p flag is not set it will use cat(). If it is though, it will use cat_boxx() from the cli package. You’ll need to make sure cli is installed before running it.

The cli package is a collection of tools for building attractive command line interfaces. The function we’ve chosen here draws a box around our output.

Lastly we need to change the way we output text at the end of our script to use our new function instead of cat().

if ( isTRUE(argv$short)){
  pretty_print(house)
} else {
  pretty_print(paste0("Hello ", argv$name, ", you can join ", house, "!"))
}

When you put it all together with what we’ve done so far, you should end up with something like this:

#!/usr/bin/env Rscript --vanilla
library(methods)
library(argparser)

p <- arg_parser("The Sorting Hat")
# Add a positional argument
p <- add_argument(p, "name", help="Name of the person to sort")
# Add a debug flag
p <- add_argument(p, "--debug", help="enable debug mode", flag=TRUE)
# Add a short output flag
p <- add_argument(p, "--short", help="output only the house", flag=TRUE)
# Add a pretty printing flag
p <- add_argument(p, "--pretty", help="pretty print the output", flag=TRUE)
argv <- parse_args(p)


# function to display debug output
debug_msg <- function(...){
  if (isTRUE(argv$debu)){
    cat(paste0("DEBUG: ",...,"\n"))
  }
}

debug_msg("Debug option is set")

debug_msg("Your name is - ", argv$name)

houses <- c("0" = "Hufflepuff",
            "1" = "Gryffindor",
            "2" = "Ravenclaw",
            "3" = "Slytherin",
            "4" = "Hufflepuff",
            "5" = "Gryffindor",
            "6" = "Ravenclaw",
            "7" = "Slytherin",
            "8" = "Hufflepuff",
            "9" = "Gryffindor",
            "a" = "Ravenclaw",
            "b" = "Slytherin",
            "c" = "Hufflepuff",
            "d" = "Gryffindor",
            "e" = "Ravenclaw",
            "f" = "Slytherin"
            )

name_hash <- digest::sha1(tolower(argv$name))

debug_msg("The name_hash is - ", name_hash)

house_index <- substr(name_hash, 1, 1)

debug_msg("The house_index is - ", house_index)

house <- houses[house_index]

pretty_print <- function(...){
  if (isTRUE(argv$pretty)){
    debug_msg("Pretty printing is enabled")
    cli::cat_boxx(...)
  } else {
    debug_msg("Pretty printing is not enabled")
    cat(...,"\n")
  }
}

if ( isTRUE(argv$short)){
  pretty_print(house)
} else {
  pretty_print(paste0("Hello ", argv$name, ", you can join ", house, "!"))
}

Running our command line utility

Windows

Don’t forget, if you’re using git-bash (see the first article for more info), you need to follow the instructions for Linux/MacOS.

To avoid duplication, please follow the same steps as for MacOS/Linux, but remember to replace ./sortinghat.R for sortinghat.

MacOS/Linux/git-bash

Remember to type everything after the ‘$’ symbol and feel free to replace ‘sellorm’ with a name of your choosing. You should see output similar to that displayed below.

First with the pretty printing flag set:

$ ./sortinghat.R -p sellorm
┌────────────────────────────────────────────┐
│                                            │
│   Hello sellorm, you can join Ravenclaw!   │
│                                            │
└────────────────────────────────────────────┘

The box around the text output is the result of cli::cat_boxx().

Then with debug and short set as well:

$ ./sortinghat.R -p -s -d sellorm
DEBUG: Debug option is set
DEBUG: Your name is - sellorm
DEBUG: The name_hash is - e9d883753fd4742672f4e7df6b93d367640e33bf
DEBUG: The house_index is - e
DEBUG: Pretty printing is enabled
┌───────────────┐
│               │
│   Ravenclaw   │
│               │
└───────────────┘

Feel free to experiment with other flag combinations, and check out the other tools in the cli package.

Wrapping up

This was intentionally a short post, just to demonstrate how easy it is to add additional flags and handle the new input as well as to point out the cli package.

In the next post we’ll take a look a providing environment specific defaults to some of these options.