├── README.md ├── template.sh ├── generate └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | ![Bash Script Generator](https://cloud.githubusercontent.com/assets/9037816/22258834/0b837816-e231-11e6-971f-f2dd9b940e21.png) 2 | # Bash Script Generator 3 | Generates a Bash Script Template that handles Arguments and Flags Cleanly. 4 | 5 | This GitHub Repository is released under the GNU v3 License, so hack away as long as you keep it open-source. To access the generator script directly, a convenient short link is provided: [bit.ly/gen-bash-script](http://bit.ly/gen-bash-script). 6 | 7 | **Authored by: [Mad Robot](https://github.com/madrobot)** 8 | 9 | ## Features 10 | The following features are supported: 11 | 12 | - Single dash and double dash options (`-d` OR `--date`) 13 | - Boolean options (`-p` without a value) 14 | - Compounded options (`-dpi` translates to `-d`, `-p` and `-i`) 15 | - Multiple options exported in arrays (`--date foo1 -d foo2 --date foo3` exports to `"foo1", "foo2", "foo3"`) 16 | - Catch-all Method 17 | - Custom Methods 18 | - Parsed options are exported into `EXPORTS` 19 | - Parsed option values are exported to `OPTS_` 20 | - Parsed arguments are exported into `ARGS` also passed to custom methods as `${@}` 21 | - Autocompletion enabled with a generator method 22 | 23 | ## Running the Generator 24 | To run the generator you simply execute the command below from your terminal: 25 | 26 | ``` 27 | curl -Ls http://bit.ly/gen-bash-script | bash > ScriptFilename.sh 28 | ``` 29 | 30 | Or to customize your generated script, execute this command instead: 31 | 32 | ``` 33 | curl -Ls http://bit.ly/gen-bash-script | bash -s -- -n ScriptName -v ScriptVer -c yes > ScriptFilename.sh 34 | ``` 35 | 36 | The generator script has the following options: 37 | 38 | - `-n|--name` for Script Name 39 | - `-v|--version` for Script Version 40 | - `-c|--catch-all` for Catch All toggle 41 | 42 | The output will be directed to `stdout` so you can easily forward the output to a file stream. 43 | 44 | ## Configuring the Generated Template 45 | There will be a few options for you to configure the generated template, below is the reference: 46 | 47 | ### Script Name 48 | `SCRIPT_NAME` 49 | 50 | Displayed in the Help Message and Version Message. 51 | 52 | ### Script Version 53 | `SCRIPT_VER` 54 | 55 | Displayed in the Version Message. 56 | 57 | ### Script Options 58 | `SCRIPT_OPTS` 59 | 60 | This is where you will configure the script options/flags. This is provided by a compounded array `SCRIPT_OPTS`, where each array value contains the matching pattern and the variable name under which the provided value will be exported. 61 | 62 | **Options Format:** 63 | 64 | The `SCRIPT_OPTS` is an array who's values are as follows: `:` 65 | 66 | The first part before the colon is a standard Regex to match against the given options, i.e. `(-d|--date)` will match either `-d` or `--date` — you can append as many patterns as you want using the OR operator `|` and all of the patterns will be matched and mapped to the ``. 67 | 68 | The second part after the colon is the key used as the variable name. This name will be exported as `OPTS_`, i.e. `OPTS_DATE` in the case of a date option. 69 | 70 | A complete example of this: `(-d|--date):DATE` 71 | 72 | *Remember: Arrays in Bash are delimited with a space, i.e. `ARRAY=("foo" "bar" "baz")`* 73 | 74 | **Important:** Options that are provided as `boolean` flag, i.e. no value is provided other than the flag itself, will be exported with the value of variable name. For example `OPTS_PUBLISH` will have the value `"OPTS_PUBLISH"`, this will let you know when you're provided `true` vs the `boolean` flag alone. 75 | 76 | ### Script Catch All 77 | `SCRIPT_CATCHALL` 78 | 79 | This will enable/disable the catch all method. Normally, you'd have to specify a script method, i.e. `script [options] operation [args]` but you may also want to skip the `operation` and simply execute `script [options] [args]` in which case you'd enable the Catch-All Option. 80 | 81 | This will only accept `yes` or `no` for a value, otherwise, it defaults to disabling the Catch-All Method. 82 | 83 | ## Script Autocompletion 84 | This script is equipped with an autocomplete helper method. Simply execute ` generate-autocomplete` to generate an autocomplete script. This utilizes the ` methods` method to get a dynamic list of all available methods/operations, this is done automatically and will update the list of methods as you add more method definitions. 85 | 86 | ### Sourcing the Autocomplete Script 87 | For the autocomplete to function, you will need to source it into your bash session, best place to do this is in your `~/.profile` by simply including `source path/to/autocomplete/script` and restarting your bash session. You may also include it in `/etc/profile` to provide it to all users, although not recommended unless you know what you're doing. 88 | 89 | *Notice: For autocompletion to operate properly, you MUST NOT start your method names with an underscore (`_`) as they're considered internal methods and will be omitted from method list.* 90 | 91 | ## License and Disclaimer 92 | This software is provided as-is and no warranties or guaranties are provided by the author. Use at your own risk. Distributed under the GNU v3 Open Source License. 93 | -------------------------------------------------------------------------------- /template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | # Script Metadata & Description 5 | # 6 | # Options Format: 7 | # The SCRIPT_OPTS is an array who's keys are as follows, 8 | # : 9 | # 10 | # The first part before the colon is a standard Regex to match against 11 | # the given options, i.e. (-d|--date) 12 | # 13 | # The second part is the key used as the variable name. This name will be exported 14 | # as OPTS_, i.e. OPTS_DATE 15 | # 16 | # A complete example of this: (-d|--date):DATE 17 | # 18 | # @author: Mad Robot 19 | # @license: GNU v3 20 | # @date: March 12, 2016 21 | ## 22 | SCRIPT_NAME="" 23 | SCRIPT_FILE="${0}" 24 | SCRIPT_VER="" 25 | SCRIPT_OPTS=("") 26 | SCRIPT_CATCHALL="" # Must be either "yes" or "no", enables a '_catchall' method executed when no command given 27 | 28 | # Print Usage for CLI 29 | function _help () { 30 | echo -e "${SCRIPT_NAME}\n" 31 | echo -e "-v|--version To display script's version" 32 | echo -e "-h|--help To display script's help\n" 33 | echo -e "Available commands:\n" 34 | echo -e "methods To display script's methods" 35 | _available-methods 36 | exit 0 37 | } 38 | 39 | # Print CLI Version 40 | function _version () { 41 | echo -e "${SCRIPT_NAME}" 1>&2 42 | echo -en "Version " 1>&2 43 | echo -en "${SCRIPT_VER}" 44 | echo -e "" 1>&2 45 | exit 0 46 | } 47 | 48 | # List all the available public methods in this CLI 49 | function _available-methods () { 50 | METHODS=$(declare -F | grep -Eoh '[^ ]*$' | grep -Eoh '^[^_]*' | sed '/^$/d') 51 | if [ -z "${METHODS}" ]; then 52 | echo -e "No methods found, this is script has a single entry point." 1>&2 53 | else 54 | echo -e "${METHODS}" 55 | fi 56 | exit 0 57 | } 58 | 59 | # Dispatches CLI Methods 60 | function _handle () { 61 | METHOD=$(_available-methods 2>/dev/null | grep -Eoh "^${1}\$") 62 | if [ "x${METHOD}" != "x" ]; then ${METHOD} ${@:2}; exit 0 63 | else 64 | # Call a Catch-All method 65 | if [ "${SCRIPT_CATCHALL}" == "yes" ]; then _catchall ${@}; exit 0 66 | # Display usage options 67 | else echo -e "Method '${1}' is not found.\n"; _help; fi 68 | fi 69 | } 70 | 71 | # Generate Autocomplete Script 72 | function _generate-autocomplete () { 73 | SCRIPT="$(printf "%s" ${SCRIPT_NAME} | sed -E 's/[ ]+/-/')" 74 | ACS="function __ac-${SCRIPT}-prompt() {" 75 | ACS+="local cur" 76 | ACS+="COMPREPLY=()" 77 | ACS+="cur=\${COMP_WORDS[COMP_CWORD]}" 78 | ACS+="if [ \${COMP_CWORD} -eq 1 ]; then" 79 | ACS+=" _script_commands=\$(${SCRIPT_FILE} methods)" 80 | ACS+=" COMPREPLY=( \$(compgen -W \"\${_script_commands}\" -- \${cur}) )" 81 | ACS+="fi; return 0" 82 | ACS+="}; complete -F __ac-${SCRIPT}-prompt ${SCRIPT_FILE}" 83 | printf "%s" "${ACS}" 84 | } 85 | 86 | 87 | # 88 | # User Implementation Begins 89 | # 90 | # Catches all executions not performed by other matched methods 91 | function _catchall () { 92 | exit 0 93 | } 94 | 95 | # ... 96 | function some-method () { 97 | exit 0 98 | } 99 | 100 | 101 | # 102 | # User Implementation Ends 103 | # Do not modify the code below this point. 104 | # 105 | # Main Method Switcher 106 | # Parses provided Script Options/Flags. It ensures to parse 107 | # all the options before routing to a metched method. 108 | # 109 | # `