| 1 | #!/usr/bin/env bash
 | 
| 2 | #
 | 
| 3 | # Common shell functions for task scripts.
 | 
| 4 | #
 | 
| 5 | # Usage:
 | 
| 6 | #   source $LIB_OSH/task-five.sh
 | 
| 7 | #
 | 
| 8 | #   test-foo() {  # define task functions
 | 
| 9 | #     echo foo
 | 
| 10 | #   }
 | 
| 11 | #   task-five "$@"
 | 
| 12 | 
 | 
| 13 | # Definition of a "task"
 | 
| 14 | #
 | 
| 15 | # - File invokes task-five "$@"
 | 
| 16 | #   - or maybe you can look at its source
 | 
| 17 | # - It's a shell function
 | 
| 18 | #   - Has ### docstring
 | 
| 19 | #   - Doesn't start with _
 | 
| 20 | 
 | 
| 21 | # List all functions defined in this file (and not in sourced files).
 | 
| 22 | _bash-print-funcs() {
 | 
| 23 |   ### Print shell functions in this file that don't start with _ (bash reflection)
 | 
| 24 | 
 | 
| 25 |   local funcs=($(compgen -A function))
 | 
| 26 |   # extdebug makes `declare -F` print the file path, but, annoyingly, only
 | 
| 27 |   # if you pass the function names as arguments.
 | 
| 28 |   shopt -s extdebug
 | 
| 29 |   declare -F "${funcs[@]}" | grep --fixed-strings " $0" | awk '{print $1}'
 | 
| 30 |   shopt -u extdebug
 | 
| 31 | }
 | 
| 32 | 
 | 
| 33 | _awk-print-funcs() {
 | 
| 34 |   ### Print shell functions in this file that don't start with _ (awk parsing)
 | 
| 35 | 
 | 
| 36 |   # Using gawk because it has match()
 | 
| 37 |   # - doesn't start with _
 | 
| 38 | 
 | 
| 39 |   # space     = / ' '* /
 | 
| 40 |   # shfunc    = / %begin
 | 
| 41 |   #               <capture !['_' ' '] ![' ']*>
 | 
| 42 |   #               '()' space '{' space
 | 
| 43 |   #               %end /
 | 
| 44 |   # docstring = / %begin
 | 
| 45 |   #               space '###' ' '+
 | 
| 46 |   #               <capture dot*>
 | 
| 47 |   #               %end /
 | 
| 48 |   awk '
 | 
| 49 |   match($0, /^([^_ ][^ ]*)\(\)[ ]*{[ ]*$/, m) {
 | 
| 50 |     print NR " shfunc " m[1]
 | 
| 51 |     #print m[0]
 | 
| 52 |   }
 | 
| 53 | 
 | 
| 54 |   match($0, /^[ ]*###[ ]+(.*)$/, m) {
 | 
| 55 |     print NR " docstring " m[1]
 | 
| 56 |   }
 | 
| 57 | ' $0
 | 
| 58 | }
 | 
| 59 | 
 | 
| 60 | _show-help() {
 | 
| 61 |   # TODO:
 | 
| 62 |   # - Use awk to find comments at the top of the file?
 | 
| 63 |   # - Use OSH to extract docstrings
 | 
| 64 | 
 | 
| 65 |   echo "Usage: $0 TASK_NAME ARGS..."
 | 
| 66 |   echo
 | 
| 67 |   echo "To complete tasks, run:"
 | 
| 68 |   echo "   source devtools/completion.bash"
 | 
| 69 |   echo
 | 
| 70 |   echo "Tasks:"
 | 
| 71 | 
 | 
| 72 |   if command -v column >/dev/null; then
 | 
| 73 |     _bash-print-funcs | column
 | 
| 74 |   else
 | 
| 75 |     _bash-print-funcs
 | 
| 76 |   fi
 | 
| 77 | }
 | 
| 78 | 
 | 
| 79 | task-five() {
 | 
| 80 |   if [[ $# -eq 0 || $1 =~ ^(--help|-h)$ ]]; then
 | 
| 81 |     _show-help
 | 
| 82 |     exit
 | 
| 83 |   fi
 | 
| 84 | 
 | 
| 85 |   if ! declare -f "$1" >/dev/null; then
 | 
| 86 |     echo "$0: '$1' isn't an action in this task file.  Try '$0 --help'"
 | 
| 87 |     exit 1
 | 
| 88 |   fi
 | 
| 89 | 
 | 
| 90 |   "$@"
 | 
| 91 | }
 |