You can install the development version of clix from GitHub with:
# install.packages("remotes")
remotes::install_github("rappster/clix")
A custom CLI implementation that bundles
- messages (in the broader sense)
- querying for user input
- executing the implications of a given user input
When developing a new package I often find myself developing the “same little CLI helpers” (a mix of messages, user input and implications of that input) over and over again.
So this is primarily just a means of “DRY” for my own work.
But of course I also hope it’s useful for someone else out there.
The main functions all start with ask_*()
.
These bundle
- messages (in the broader sense)
- querying for user input
- executing the implications of a given user input
I felt like even with superb CLI tooling such as {cli} those out-of-the-box bundles are typically still missing - or I just didn’t find them yet 😉
Currently, there’s only on of these implemented yet: ask_dir_create()
I often run into situations where I might expect a directory to already exist (because I might have created it while developing something). However, in “clean start” scenarios (which might be the case when using your package in production context) this might not be the case.
So here’s a CLI-based way to handle such situations.
Let’s create a temporary directory first.
path <- fs::path(tempdir(), "a/b/c")
Then we’ll load the package
library(clix)
path <- ask_dir_create(dir = path)
# ── Directory check ──────────────────────────────────────────
# Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# does not exist yet.
#
# Do you want to create it?
#
# Answering Yes implies the following:
# • Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# will be created
#
#
# 1: Yes
# 2: No
# 3: Let me start over
# 4: Exit
Answer with 1: Yes
# Selection: 1
# ✓ Directory /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c created.
path %>% fs::dir_exists()
ask_dir_create(dir = path)
# Directory /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/RtmpnxbKca/a/b/c already
# exists.
#
#
# 1: Keep
# 2: Reset
# 3: Let me start over
# 4: Exit
You can reset an existing directory to its “original state” in the sense
that the all subdirectories (but not the directory itself) are
deleted by answering with 2: Reset
Let’s make sure the temp dir is deleted again before moving on
path %>% fs::dir_delete()
Answer with 2: No
ask_dir_create(dir = path)
# ── Directory check ──────────────────────────────────────────
# Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# does not exist yet.
#
# Do you want to create it?
#
# Answering Yes implies the following:
# • Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# will be created
#
#
# 1: Yes
# 2: No
# 3: Let me start over
# 4: Exit
# Selection: 2
# ! Directory '/var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c' was not created
# Warning message:
# In throw_warning(., .console = TRUE) :
# Directory '/var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c' was not created
Answer with 3: Let me start over
ask_dir_create(dir = path)
# ── Directory check ──────────────────────────────────────────
# Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# does not exist yet.
#
# Do you want to create it?
#
# Answering Yes implies the following:
# • Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# will be created
#
#
# 1: Yes
# 2: No
# 3: Let me start over
# 4: Exit
# Selection: 3
# Starting over...
#
# 1: Yes
# 2: No
# 3: Let me start over
# 4: Exit
Answer with “Exit” (input = 4)
ask_dir_create(dir = path)
# ── Directory check ──────────────────────────────────────────
# Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# does not exist yet.
#
# Do you want to create it?
#
# Answering Yes implies the following:
# • Directory
# /var/folders/r1/_3hsv89s6rq2vl9nm31jjk700000gn/T/Rtmpyl8rUK/a/b/c
# will be created
#
#
# 1: Yes
# 2: No
# 3: Let me start over
# 4: Exit
# Selection: 4
# Exiting