Table of Contents
- Table of Contents
- Installation
- Prerequisites
- What is Bashly
- Usage
- Examples
- Configuration Reference
- Real World Examples
- Contributing / Support
Installation
$ gem install bashly
or with Docker:
$ alias bashly='docker run --rm -it --volume "$PWD:/app" dannyben/bashly'
Prerequisites
The bash scripts generated by bashly require bash 4 or higher due to heavy use of associative arrays.
What is Bashly
Bashly is a command line application (written in Ruby) that lets you generate feature-rich bash command line tools.
The design intention is to let you focus on your specific code, without worrying about command line argument parsing, usage texts, error messages and other functions that are usually handled by a framework in any other programming language.
Bahsly is responsible for:
- Generating a single, standalone bash script.
- Generating usage texts and help screens, showing your tool's arguments, flags and commands (works for subcommands also).
- Parsing the user's command line and extracting:
- Optional or required positional arguments.
- Optional or required option flags (with or without flag arguments).
- Commands (and subcommands).
- Standard flags (like --help and --version).
- Providing you with a place to input your code for each of the functions your tool performs, and merging it back to the final script.
- Providing you with additional (optional) framework-style, standard
library functions:
- Color output.
- Config file management (INI format).
- YAML parsing.
- and more.
Usage
In an empty directory, create a sample configuration file by running
$ bashly init
# or, to generate a simpler configuration:
$ bashly init --minimal
This will create a sample src/bashly.yml
file.
You can edit this file to specify which arguments, flags and commands you
need in your bash script.
Then, generate an initial bash script and function placeholder scripts by running
$ bashly generate
This will:
- Create the bash executable script.
- Create files for you to edit in the
src
folder.
Finally, edit the files in the src
folder. Each of your script's commands
get their own file. Once you edit, run bashly generate
again to merge the
content from your functions back into the script.
Using the input arguemnts in your code
In order to access the parsed arguments in any of your partial scripts, you
may simply access the $args
associative array.
For example:
- Generate a minimal configuration with
bashly init --minimal
- Generate the bash script with
bashly generate
- Run the script with
./download hello --force
You will notice that all the arguments of the associative array are printed
on screen. This is done by the inspect_args
function that was inserted into
the generated partial script src/root_command.sh
.
You can now access these variables by modifying sec/root_command.sh
like
this:
# src/root_command.sh
source_url=${args[source]}
force=${args[--force]}
if [[ $force ]]; then
echo "downloading $source_url with --force"
else
echo "downloading $source_url"
fi
After editing the file, run bashly generate
(or bashly g
for short) and
run:
$ ./download a --force
downloading a with --force
Examples
The bashly.yml
file can be set up to generate two types of scripts:
- Script with commands (for example, like
docker
orgit
). - Script without commands (for example, like
ls
)
This is detected automatically by the contents of the configuration: If it
contains a commands
definition, it will generate a script with commands.
Sample configuraiton for a script without commands
- Generate this script by running
bashly generate --minimal
- See the initial sample bashly.yml file
- See the generated bash script
Sample configuraiton for a script with commands
- Generate this script by running
bashly generate
- See the initial sample bashly.yml file
- See the generated bash script
See the examples folder for more examples.
Configuration Reference
The bashly.yml
configuration file consists of these types:
- Command - defines the root command as well as any subcommand.
- Argument - defines positional arguments.
- Flag - defines option flags.
- Environment Variable - defines environment variables required (or desired) by your script.
Command options
Unless otherwise specified, these definitiona can be used for both the root
command and subcommands (under the commands
definition).
Option | Description |
---|---|
name |
The name of the script or subcommand. |
short |
An additional, optional pattern - usually used to denote a one letter variation of the command name. You can add * as a suffix, to denote a "starts with" pattern - for example short: m* . Applicable only in subcommands. |
help |
The header text to display when using --help . This option can have multiple lines. In this case, the first line will be used as summary wherever appropriate. |
version |
The string to display when using --version . Applicable only in the main command. |
default |
Setting this to yes on any command, will make unrecognized command line arguments to be passed to this command. Applicable only in subcommands. |
examples |
Specify an array of examples to show when using --help . Each example can have multiple lines. |
environment_variables |
Specify an array of environment variables needed by your script. |
commands |
Specify the array of commands. Each command will have its own args and flags. Note: if commands is provided, you cannot specify flags or args at the same level. |
args |
Specify the array of positional arguments this script needs. |
flags |
Specify the array of option flags this script needs. |
dependencies |
Specify an array of any required external dependencies (commands). The script execution will be halted with a friendly error unless all dependency commands exist. |
group |
In case you have many commands, use this option to specify a caption to display before this command. This option is purely for display purposes, and needs to be specified only for the first command in each group. |
Argument options
The argument's value will be available to you as ${args[user]}
in your
bash function.
Option | Description |
---|---|
name |
The name of the argument. |
help |
The message to display when using --help . Can have multiple lines. |
required |
Specify if this argument is required. Note that once you define an optional argument (without required: true) then you cannot define required arguments after it. |
default |
The value to use in case it is not provided by the user. Implies that this argument is optional. |
Flag options
The flag's value will be available to you as ${args[--output]}
in your
bash function (regardless of whether the user provided it with the long or
short form).
Option | Description |
---|---|
long |
The long form of the flag. |
short |
The short form of the flag. |
help |
The text to display when using --help . Can have multiple lines. |
arg |
If the flag requires an argument, specify its name here. |
required |
Specify if this flag is required. |
default |
The value to use in case it is not provided by the user. Implies that this flag is optional, and only makes sense when the flag has an argument. |
Special handling for -v and -h
The -v
and -h
flags will be used as the short options for --version
and
--help
respectively only if you are not using them in any of your own
flags.
Environment Variable options
The below configuration generates this environment variable usage text:
If an environment variable is defined as required (false by default), the execution of the script will be halted with a friendly error if it is not set.
Option | Description |
---|---|
name |
The name of the variable (it will be automatically capitalized). |
help |
The message to display when using --help. Can have multiple lines. |
required |
Specify if this variable is required. |
Real World Examples
- Rush - a Personal Package Manager
- Alf - a generator for bash aliases and sub-aliases
- git-changelog - a change log generator
Contributing / Support
If you experience any issue, have a question or a suggestion, or if you wish to contribute, feel free to open an issue.