Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
moebrowne committed Jul 10, 2016
2 parents 49bb2c1 + 20a30c4 commit 30cf457
Show file tree
Hide file tree
Showing 5 changed files with 400 additions and 114 deletions.
82 changes: 62 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
# BASH Argument Parser

Takes arguments passed in nearly any format to a bash script and allows easy access to them and their values
Takes arguments passed to a bash script in nearly any format and allows easy access to them and their values

## Use

### How To Use

Just include the library in the head of script, define all the arguments you need and call the parser function
Just define all the arguments you need and include the library in the head of script, that's it.

```bash
# Include the Argument Parser library
source ./my/lib/path/argument-parser.sh

# Define the expected arguments
declare -A argExpected
argExpected['test']="argName - This is a short description of the argument and what it does"
argExpected['R']="secondArgName - This is another argument that can be passed"

# Parse any arguments
argParse
# Include and run the Argument Parser library
source ./my/lib/path/argument-parser.sh
```

### Defining Expected Arguments

The argument parser can take an array of arguments to expect, it has the following format:
The argument parser takes an array of arguments to expect, it has the following format:

```bash
# Define argExpected as an associative array
# This must occur once before you build the array of argument definitions
declare -A argExpected

# Define the -r argument
argExpected['r']="argumentName - Argument description"

Expand All @@ -41,17 +43,30 @@ argExpected['a|A']="argumentName - Argument description"
argExpected['d|deamon|D']="argumentName - Argument description"
```

The `argumentName` part of the definition is the name given to the argument and what should be passed to the `argValue` and `argExists` functions, see below.
The `argumentName` part of the definition is the name given to the argument and what should be passed to the `argValue` and `argPassed` functions, see below. The argument name is case sensitive and must not contain spaces or an equals sign.

By default if an argument is passed that hasn't been defined an error will be thrown and the script will exit.
This feature can be turned off by setting `ARG_MUST_BE_DEFINED` to `false`, note that the argument names will default to the argument its self, without the preceding hyphen(s).

### Defining Argument Default Values

You can define a default value that will be used if the argument isn't passed:

```bash
# Set the -e arguments default value to 900
argExpected['e']="argumentName=900 - Argument description"
```

Now if the script is called and the `-e` argument is omitted `argValue "argumentName"` will return `900`
The default value can also be set to an empty string (`argExpected['e']="argumentName= - Argument description"`)

### Get An Arguments Value

There is a helper function named `argValue()` which takes the name of
an argument as its only parameter and returns the value given to the argument.

If the argument doesn't have a value or hasn't been passed nothing is returned.
If the argument doesn't have a value or hasn't been passed nothing is returned
unless it's been given a default, in which case the default value will be returned.

```bash
# -a 'some text'
Expand Down Expand Up @@ -86,30 +101,32 @@ esac

### Check If An Argument Has Been Passed

There is a helper function named `argExists()` which takes the name of
There is a helper function named `argPassed` which takes the name of
an argument as its only parameter and returns a boolean.

`argPassed` will return false if the argument has fallen back to its default value*

```bash
# -v
if argExists 'v'; then
if argPassed 'v'; then
echo "The -v argument has been passed"
fi

# -rMd
argExists 'r' && echo "The -r argument was passed"
argPassed 'r' && echo "The -r argument was passed"

# --long-argument-name
if argExists 'long-argument-name'; then
if argPassed 'long-argument-name'; then
# Do something awesome
fi

# --protocol=HTTP
if argExists 'protocol'; then
if argPassed 'protocol'; then
# Do something awesome
fi

# -O 43
argExists 'O' && echo "Found the -O argument"
argPassed 'O' && echo "Found the -O argument"
```

## Supported Argument Formats
Expand Down Expand Up @@ -169,10 +186,35 @@ The order the arguments are passed on the command line makes a difference
### Examples

* Calling `my-script.sh -f first -f last` will cause `argValue "f"` to return the value `last`
* Calling `my-script.sh -g 345 -g` will mean cause `argValue "g"` to return nothing
* Calling `my-script.sh --size 512 --size=1024` will mean cause `argValue "size"` to return `1024`
* Calling `my-script.sh -g 345 -g` will cause `argValue "g"` to return nothing
* Calling `my-script.sh --size 512 --size=1024` will cause `argValue "size"` to return `1024`

## Passing Additional Non-Arguments Strings

If you need to pass in non-argument stings along side your arguments you just need to add the end of arguments marker `--` and anything that follows wont be parsed as an argument but instead will be assigned to a numbered positional argument:

For example running: `./script.sh --arg1 --arg2 -- file1 file2 -f file5`

Will be parsed as:

* Argument: `--arg1`
* Argument: `--arg2`
* Non-Argument: `file1` (accessible via `$1`)
* Non-Argument: `file2` (accessible via `$2`)
* Non-Argument: `-f` (accessible via `$3`)
* Non-Argument: `file5` (accessible via `$4`)

This way you can define arguments along side an arbitrary number of strings you may want to operate on at the same time!

## Debug Mode

There is a debug mode that can be enabled by setting the `ARG_DEBUG` variable to `true` right before calling `argParse`.
This will cause the script to dump out information about which flags it finds and of what kind etc
There is a debug mode that can be enabled by setting the `ARG_DEBUG` variable to `true` right before including the library.
This will cause the script to dump out information about which flags it finds and of what kind etc

## Testing

There is a rudimentary test suite included with the project that can be used to check that changes haven't broken any other part of the code.

### Running Tests

It's as simple as executing `test.sh` in the `tests` directory, if you see any red blips there is a problem, if it's all green then everything should be ok
Loading

0 comments on commit 30cf457

Please sign in to comment.