Skip to content

Commit

Permalink
Merge pull request #2 from richbl/dev
Browse files Browse the repository at this point in the history
updated per idiomatic bash scripting patterns
  • Loading branch information
richbl authored Dec 13, 2021
2 parents e72fd8b + 1fc04a7 commit 6f68b02
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 86 deletions.
132 changes: 69 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# A-Bash-Template
**A-Bash-Template** (`bash_template.sh`) is a [bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) script that really does nothing at all. **It's a template.** But it does make scripting much easier...

**A-Bash-Template** (`bash_template.sh`) is a [bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) script that really does nothing at all. **It's a template.** But it does make scripting much easier and more consistent.

<p align="center">
<img src="https://user-images.githubusercontent.com/10182110/145758715-b127adfc-710b-49d3-9ede-151adc83ae76.png" width="400" />
Expand All @@ -9,20 +10,22 @@

**A-Bash-Template** is designed to make script development and command line argument management more robust, easier to implement, and easier to maintain and update/upgrade. This BaT includes the following features:

- **Dependencies Checker**: a routine that checks all external file and program dependencies (*e.g.*, [jq](https://stedolan.github.io/jq/))
- **Dependencies Checker**: a routine that checks all external file and program dependencies (*e.g.*, this script relies on [jq](https://stedolan.github.io/jq/) for JSON parsing, and its availability is checked on script execution)
- **Configuration Details in JSON**: Arguments and script details--such as script description and syntax--are stored in the [JSON](http://www.json.org/) file format (*i.e.*, `config.json`)
- **JSON Wrapper Functions**: JSON queries (using [jq](https://stedolan.github.io/jq/)) handled through template wrapper functions
- **Automated Script Banner**: A script banner function automates banner generation, reading directly from `config.json`
- **Automated Arguments Management**: Command line arguments are automatically parsed and tested for completeness using both short and long-format argument syntax (*e.g.*, `-u|--username`)
- **Support for Optional Arguments**: Optional command line arguments are permissible and managed through the JSON configuration file
- **Structured Modular Library**: Template functions organized into libraries to minimize code footprint in the main script, and permits easier maintenance and extensions/add-ons support
- **Support for [Optional] Arguments**: Optional command line arguments are permissible and managed through the JSON configuration file
- **Structured Modular Library**: Template functions organized into libraries (see the [bash-lib](https://github.com/richbl/bash-lib) project for specific library details) to minimize code footprint in the main script and permit easier maintenance and extensions/add-ons support

### Dependencies Checker

The dependencies checker is a routine that checks that all external file and program dependencies are met. For example, `bash_template.sh` itself relies on one external program for proper execution: [jq](https://stedolan.github.io/jq/), used for parsing its own JSON configuration file (`config.json`).

In this instance, to configure dependency checking in `bash_template.sh`, the array variable `REQ_PROGRAMS` is set to `('jq')`. The script then calls into the `check_dependencies` function in the `args` library (found in the `./lib` folder).

### Script Configuration in JSON

Script details, such as the script description, version and script syntax, and all command line argument options--both required and optional--are stored in a single JSON file called `config.json` located in the `./data` folder.

The JSON file used in **A-Bash-Template** is displayed below:
Expand All @@ -32,7 +35,7 @@ The JSON file used in **A-Bash-Template** is displayed below:
{
"title": "A bash template (BaT) to ease argument parsing and management",
"syntax": "bash_template.sh -a alpha -b bravo [-c charlie] -d delta",
"version": "0.2.0"
"version": "1.1.0"
},
"arguments":
[
Expand Down Expand Up @@ -67,125 +70,128 @@ The JSON file used in **A-Bash-Template** is displayed below:
]
}


### Automated Script Banner
The informational banner that displays details about how to use the script is generated using configuration details held in the JSON file. A call to `display_banner` in the `./lib/general` library displays the following:

The informational banner that displays details about how to use the script is generated using configuration details held in the JSON file. A call to `display_banner` in the `./lib/general` library displays the following:

|
| A bash template (BaT) to ease argument parsing and management
| 0.2.0
| 1.1.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|

By default, `display_banner` is called when the script is first run.

### Command Line Parsing and Completeness Testing

When **A-Bash-Template** is first run, it parses the command line to identify command line argument values (*e.g.*, `--password = pass123`), and also check to see whether all required arguments have been set. If command line arguments are missing, the script will report it:

$ ./bash_template.sh -a one

|
| A bash template (BaT) to ease argument parsing and management
| 0.2.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|
|
| A bash template (BaT) to ease argument parsing and management
| 1.1.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|

Error: bravo argument (-b|--bravo) missing.
Error: delta argument (-d|--delta) missing.

> **Note**: The optional argument (-c|--charlie) did not get flagged as an omission, since it's an optional argument, and not a required argument.

## Requirements

- An operational [bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) environment (bash 4.3.2 used during development)
- One additional external program:
+ [jq](https://stedolan.github.io/jq/), used for parsing the `config.json` file

While this package was written and tested under Linux (Ubuntu 15.10), there should be no reason why this won't work under other Unix-like operating systems.
- An operational [bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) environment (bash 4.3.2 used during initial development)
- One additional external program:
- [jq](https://stedolan.github.io/jq/), used for parsing the `config.json` file

While this package was originally written and tested under Linux (Ubuntu 15.10), there should be no reason why this won't work with other shells, or other Unix-like operating systems.

## Basic Usage

**A-Bash-Template** is run through a command line interface, so all of the command options are made available there.

Here's the default response when running `bash_template.sh` with no arguments:

$ ./bash_template.sh

|
| A bash template (BaT) to ease argument parsing and management
| 0.2.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|
|
| A bash template (BaT) to ease argument parsing and management
| 1.1.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|

Error: bravo argument (-a|--alpha) missing.
Error: bravo argument (-b|--bravo) missing.
Error: delta argument (-d|--delta) missing.


In this example, the program responds by indicating that the required script arguments must be set before proper operation.
In this example, the program responds by indicating that the required script arguments must be set before proper operation.

> **Note**: The optional argument (-c|--charlie) did not get flagged as an omission, since it's an optional argument, and not a required argument.
When arguments are correctly passed, the script provides feedback on the success (or failure) of the script:

$ ./bash_template.sh -a one -b two -c three -d four

|
| A bash template (BaT) to ease argument parsing and management
| 0.2.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|
|
| A bash template (BaT) to ease argument parsing and management
| 1.1.0
|
| Usage:
| bash_template.sh -a alpha -b bravo [-c charlie] -d delta
|
| -a, --alpha alpha (something descriptive)
| -b, --bravo bravo (something descriptive)
| -c, --charlie charlie (this is optional)
| -d, --delta delta (something descriptive)
|

alpha is one
bravo is two
charlie is three
delta is four

## Custom Configuration: Look for `[user-config]`
## Custom Configuration: Look for `[user-config]`

Since **A-Bash-Template** is a BaT, the real value is to permit custom code to become well-integrated to complete whatever is the required intent of the script run. The design and structure of the template accounts for this, and only localized changed are necessary.

To make custom configuration changes, search for the comment string `[user-config]` throughout the script sources (there are only a few). These comments provide guidance on what should be changed and why.

## Yes, We Are [Dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) A-Bash-Template
## Yes, We Are [Dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) the A-Bash-Template Project

Of course we are! Otherwise, what value does a BaT offer if it doesn't get used often enough to warrant the time to develop a BaT?

Here are some of our own *useful* scripts that use **A-Bash-Template**:
Here are some of our own *useful* scripts that use **A-Bash-Template**:

- **[remote-folder-copy](https://github.com/richbl/remote-folder-copy)**
- **[postgres-db_dump](https://github.com/richbl/postgresql-db-dump)**
- **[photography-gallery-generator](https://github.com/richbl/photography-gallery-generator)**

## IMPORTANT! This Project Uses Git Submodules

- **[remote-folder-copy](https://github.com/richbl/remote-folder-copy)**
- **[postgres-db_dump](https://github.com/richbl/postgresql-db-dump)**
- **[photography-gallery-generator](https://github.com/richbl/photography-gallery-generator)**
> If you're about to clone this project, read this
## A Note on Cloning: This Project Uses Git Submodules
This project uses a Git [submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) project, specifically the `bash-lib` folder to keep the **A-Bash-Template** project up-to-date without manual intervention.

So, be sure to clone this project with the `--recursive` switch (`git clone --recursive https://github.com/richbl/a-bash-template`) so any submodule project(s) will be automatically cloned as well. If you clone into this project without this switch, you'll likely see empty submodule project folders (depending on your version of Git).
2 changes: 1 addition & 1 deletion bash-lib
Submodule bash-lib updated 3 files
+28 −3 README.md
+44 −51 args
+28 −28 general
53 changes: 32 additions & 21 deletions bash_template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# -----------------------------------------------------------------------------
# Copyright (C) Business Learning Incorporated (businesslearninginc.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License at
# <http://www.gnu.org/licenses/> for more details.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License at <http://www.gnu.org/licenses/> for
# more details.
# -----------------------------------------------------------------------------
#
# A bash template (BaT)
Expand All @@ -32,18 +32,14 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#
# NOTE:
# The string '[user-config]' is an indication that some user configuration
# may be needed to customize this bash template
# may be needed to customize this script
#

# -----------------------------------------------------------------------------
# script declarations
# script library sources and declarations
#
shopt -s extglob
EXEC_DIR="$(dirname "$0")"
# shellcheck source=bash-lib/args
source "${EXEC_DIR}/bash-lib/args"
# shellcheck source=bash-lib/general
source "${EXEC_DIR}/bash-lib/general"
. "$(cd "$(dirname "$0")" && pwd)/bash-lib/args"
. "$(cd "$(dirname "$0")" && pwd)/bash-lib/general"

# [user-config] set any external program dependencies here
declare -a REQ_PROGRAMS=('jq')
Expand All @@ -60,7 +56,22 @@ check_for_args_completeness
# [user-config] any code from this point on is custom code, using
# the sevices and variables available through the template
#
printf "%s\n" "alpha is $(get_config_arg_value alpha)"
printf "%s\n" "bravo is $(get_config_arg_value bravo)"
printf "%s\n" "charlie is $(get_config_arg_value charlie)"
printf "%s\n" "delta is $(get_config_arg_value delta)"

# declare arguments
ARG_ALPHA="$(get_config_arg_value alpha)"
ARG_BRAVO="$(get_config_arg_value bravo)"
ARG_CHARLIE="$(get_config_arg_value charlie)"
ARG_DELTA="$(get_config_arg_value delta)"
readonly ARG_ALPHA
readonly ARG_BRAVO
readonly ARG_CHARLIE
readonly ARG_DELTA

printf "%s\n" "alpha is $ARG_ALPHA"
printf "%s\n" "bravo is $ARG_BRAVO"

if [ -n "${ARG_CHARLIE}" ]; then
printf "%s\n" "charlie is $ARG_CHARLIE"
fi

printf "%s\n" "delta is $ARG_DELTA"
2 changes: 1 addition & 1 deletion data/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"title": "A bash template (BaT) to ease argument parsing and management",
"syntax": "bash_template.sh -a alpha -b bravo [-c charlie] -d delta",
"version": "0.3.0"
"version": "1.1.0"
},
"arguments":
[
Expand Down

0 comments on commit 6f68b02

Please sign in to comment.