Skip to main content

script_wizard/
lib.rs

1//! script-wizard is a shell script (Bash) helper program, to delegate
2//! the responsibility of asking questions to the user, asking for
3//! confirmation, making selections, etc. The normalized response is
4//! printed to stdout for the script to consume.
5//!
6//! This is a single binary application written in Rust and it
7//! utilizes the
8//! [inquire](https://docs.rs/inquire/latest/inquire/index.html)
9//! library for providing a nicer user interface than the typical
10//! shell script is capable of.
11//!
12//! # Source code
13//! The source code is hosted at github [EnigmaCurry/script-wizard](https://github.com/EnigmaCurry/script-wizard)
14//! # Install with cargo
15//!
16//! ```bash
17//! cargo install script_wizard
18//! ```
19//!
20//! # Install without cargo
21//! [Grab the latest release from github](https://github.com/EnigmaCurry/script-wizard/releases) or run this command to download and install automatically:
22//! ```bash
23//! cd ~/Downloads
24//! ARCHIVE=script-wizard-$(uname -s)-$(uname -m).tar.gz
25//! curl -LO https://github.com/Enigmacurry/script-wizard/releases/latest/download/${ARCHIVE}
26//! tar xfv ${ARCHIVE}
27//! sudo install script-wizard /usr/local/bin/script-wizard
28//! ```
29//!
30//! Or, install with this curlbomb:
31//! ```bash
32//! bash <(curl https://raw.githubusercontent.com/EnigmaCurry/script-wizard/refs/heads/master/install.sh) ~/.local/bin
33//! ```
34//!
35//! ## Examples in Bash
36//! 
37//! ### ask
38//! 
39//! Ask the user a question and capture the response:
40//! 
41//! ```bash
42//! # Set the alias to make it easier to use:
43//! alias ask='script-wizard ask'
44//! 
45//! # Record the user's response into the NAME variable:
46//! NAME=$(ask "What is your name?")
47//! ```
48//! 
49//! ### confirm
50//! 
51//! Ask the user a yes/no question, with a prepared default response (eg.
52//! `yes` is the default here) :
53//! 
54//! ```bash
55//! # Set the alias to make it easier to use:
56//! alias confirm='script-wizard confirm'
57//! 
58//! # Confirm returns an exit code: 0=yes 1=no :
59//! if confirm "Do you like Linux?" yes; then
60//!   echo "Tux is great!"
61//! else
62//!   echo "Well, thats ok."
63//! fi
64//! 
65//! # But maybe you want to record a literal "true" or "false" into a variable?:
66//! LIKES_LINUX=$(confirm "Do you like Linux?" yes && echo "true" || echo "false")
67//! ```
68//! 
69//! ### choose
70//! 
71//! Present a list of options to the user and have them select a *single*
72//! response from the list:
73//! 
74//! ```bash
75//! # Set the alias to make it easier to use:
76//! alias choose='script-wizard choose'
77//! 
78//! CHOSEN=$(choose "Select your character class" "Rogue" "Wizard" "Paladin" "Cleric" "Bard")
79
80//! # You can use an option from a bash array too:
81//! options=("red" "blue" "greenish orange" "purple")
82//! COLOR=$(choose "Choose a color" "${options[@]}")
83//! ```
84//! 
85//! ### select
86//! 
87//! Present a list of options to the user and have them select *multiple*
88//! responses (zero or more) from the list:
89//! 
90//! ```bash
91//! readarray -t SELECTED < <(script-wizard select "Which games do you like?" "Rocket League" "Portal" "Quake" "Magic the Gathering")
92//! 
93//! echo "These are the games you said you like:"
94//! # Use printf to print one per line (echo would merge into one line):
95//! printf '%s\n' "${SELECTED[@]}"
96//! ```
97//! 
98//! ### date
99//! 
100//! Present a date picker to the user:
101//! 
102//! ```bash
103//! # Pick a date between 2023/10/01 and 2023/10/20:
104//! DATE=$(script-wizard date "Enter a date" --week-start monday --format "%Y-%m-%d" --min-date "2023-10-01" --max-date "2023-10-20" --help-message "yadda yadda")
105//! ```
106//! 
107//! ### editor
108//! 
109//! Present a full text editor entry to the user:
110//! 
111//! ```bash
112//! BIOGRAPHY=$(script-wizard editor "Tell me alllll about yourself" --default "# Describe yourself" --json | sed 's/^[^\"]*//')
113//! ```
114//! 
115//! Watch out: There is a potential bug here if your editor prints
116//! anything to stdout. (In the case of emacsclient, it undesirably
117//! captures the text "Waiting for Emacs...".) Using `--json` will wrap
118//! the correct editor text in double quotes, and pipeing the output
119//! through `sed 's/^[^\"]*//'` will remove the text before the first
120//! double quote.)
121//! 
122//! Set the common `EDITOR` environment variable to choose the editor it
123//! launches.
124//! 
125//! ### menu
126//! 
127//! Present a menu of command entries that the user can select and
128//! execute. The entries must be specified in the format: `ENTRY =
129//! COMMAND` where `ENTRY` is the text line of the menu entry, and
130//! `COMMAND` is the shell command to run if the entry is selected:
131//! 
132//! ```bash
133//! script-wizard menu --once "main menu" "print username = whoami"  "print all users = cat /etc/passwd | cut -d ':' -f 1"
134//! ```
135//!
136//! ## Babashka pod
137//!
138//! script-wizard can run as a [Babashka](https://github.com/babashka/babashka)
139//! [pod](https://github.com/babashka/pods), providing a native Clojure API
140//! for all commands (`ask`, `confirm`, `choose`, `select`, `date`, `editor`,
141//! and `menu`):
142//!
143//! ```clojure
144//! (require '[babashka.pods :as pods])
145//! (pods/load-pod ["script-wizard" "pod"])
146//! (require '[pod.enigmacurry.script-wizard :as sw])
147//!
148//! (sw/ask "What is your name?" :default "World")
149//! (sw/confirm "Continue?" :default :yes)
150//! (sw/choose "Pick one" ["a" "b" "c"])
151//! ```
152//!
153//! ## Common options
154//! 
155//!  * `--json` - the default is to print raw text even if it spans
156//!    multiple lines. If you specify `--json` it will print it as compact
157//!    JSON on a single line, splitting lines into lists of strings, or as
158//!    a quoted string if its just supposed to be one line, depending on
159//!    the subcommand.
160pub mod ask;