Travis Swicegood | 8056192 | 2012-02-11 15:48:48 -0600 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # Bash completion support for Fabric (http://fabfile.org/) |
| 4 | # |
| 5 | # |
| 6 | # Copyright (C) 2011 by Konstantin Bakulin |
| 7 | # |
| 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy |
| 9 | # of this software and associated documentation files (the "Software"), to deal |
| 10 | # in the Software without restriction, including without limitation the rights |
| 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 12 | # copies of the Software, and to permit persons to whom the Software is |
| 13 | # furnished to do so, subject to the following conditions: |
| 14 | # |
| 15 | # The above copyright notice and this permission notice shall be included in |
| 16 | # all copies or substantial portions of the Software. |
| 17 | # |
| 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 24 | # THE SOFTWARE. |
| 25 | # |
| 26 | # Thanks to: |
| 27 | # - Adam Vandenberg, |
| 28 | # https://github.com/adamv/dotfiles/blob/master/completion_scripts/fab_completion.bash |
| 29 | # |
| 30 | # - Enrico Batista da Luz, |
| 31 | # https://github.com/ricobl/dotfiles/blob/master/bin/fab_bash_completion |
| 32 | # |
| 33 | |
| 34 | |
| 35 | # Use cache files for fab tasks or not. |
| 36 | # If set to "false" command "fab --shortlist" will be executed every time. |
| 37 | export FAB_COMPLETION_CACHE_TASKS=true |
| 38 | |
| 39 | # File name where tasks cache will be stored (in current dir). |
| 40 | export FAB_COMPLETION_CACHED_TASKS_FILENAME=".fab_tasks~" |
| 41 | |
| 42 | |
| 43 | # Set command to get time of last file modification as seconds since Epoch |
| 44 | case `uname` in |
| 45 | Darwin|FreeBSD) |
| 46 | __FAB_COMPLETION_MTIME_COMMAND="stat -f '%m'" |
| 47 | ;; |
| 48 | *) |
| 49 | __FAB_COMPLETION_MTIME_COMMAND="stat -c '%Y'" |
| 50 | ;; |
| 51 | esac |
| 52 | |
| 53 | |
| 54 | # |
| 55 | # Get time of last fab cache file modification as seconds since Epoch |
| 56 | # |
| 57 | function __fab_chache_mtime() { |
| 58 | ${__FAB_COMPLETION_MTIME_COMMAND} \ |
| 59 | $FAB_COMPLETION_CACHED_TASKS_FILENAME | xargs -n 1 expr |
| 60 | } |
| 61 | |
| 62 | |
| 63 | # |
| 64 | # Get time of last fabfile file/module modification as seconds since Epoch |
| 65 | # |
| 66 | function __fab_fabfile_mtime() { |
| 67 | local f="fabfile" |
| 68 | if [[ -e "$f.py" ]]; then |
| 69 | ${__FAB_COMPLETION_MTIME_COMMAND} "$f.py" | xargs -n 1 expr |
| 70 | else |
| 71 | # Suppose that it's a fabfile dir |
| 72 | find $f/*.py -exec ${__FAB_COMPLETION_MTIME_COMMAND} {} + \ |
| 73 | | xargs -n 1 expr | sort -n -r | head -1 |
| 74 | fi |
| 75 | } |
| 76 | |
| 77 | |
| 78 | # |
| 79 | # Completion for "fab" command |
| 80 | # |
| 81 | function __fab_completion() { |
| 82 | # Return if "fab" command doesn't exists |
| 83 | [[ -e `which fab 2> /dev/null` ]] || return 0 |
| 84 | |
| 85 | # Variables to hold the current word and possible matches |
| 86 | local cur="${COMP_WORDS[COMP_CWORD]}" |
| 87 | local opts=() |
| 88 | |
| 89 | # Generate possible matches and store them in variable "opts" |
| 90 | case "${cur}" in |
| 91 | -*) |
| 92 | if [[ -z "${__FAB_COMPLETION_LONG_OPT}" ]]; then |
| 93 | export __FAB_COMPLETION_LONG_OPT=$( |
| 94 | fab --help | egrep -o "\-\-[A-Za-z_\-]+\=?" | sort -u) |
| 95 | fi |
| 96 | opts="${__FAB_COMPLETION_LONG_OPT}" |
| 97 | ;; |
| 98 | |
| 99 | # Completion for short options is not nessary. |
| 100 | # It's left here just for history. |
| 101 | # -*) |
| 102 | # if [[ -z "${__FAB_COMPLETION_SHORT_OPT}" ]]; then |
| 103 | # export __FAB_COMPLETION_SHORT_OPT=$( |
| 104 | # fab --help | egrep -o "^ +\-[A-Za-z_\]" | sort -u) |
| 105 | # fi |
| 106 | # opts="${__FAB_COMPLETION_SHORT_OPT}" |
| 107 | # ;; |
| 108 | |
| 109 | *) |
| 110 | # If "fabfile.py" or "fabfile" dir with "__init__.py" file exists |
| 111 | local f="fabfile" |
| 112 | if [[ -e "$f.py" || (-d "$f" && -e "$f/__init__.py") ]]; then |
| 113 | # Build a list of the available tasks |
| 114 | if $FAB_COMPLETION_CACHE_TASKS; then |
| 115 | # If use cache |
| 116 | if [[ ! -s ${FAB_COMPLETION_CACHED_TASKS_FILENAME} || |
| 117 | $(__fab_fabfile_mtime) -gt $(__fab_chache_mtime) ]]; then |
| 118 | fab --shortlist > ${FAB_COMPLETION_CACHED_TASKS_FILENAME} \ |
| 119 | 2> /dev/null |
| 120 | fi |
| 121 | opts=$(cat ${FAB_COMPLETION_CACHED_TASKS_FILENAME}) |
| 122 | else |
| 123 | # Without cache |
| 124 | opts=$(fab --shortlist 2> /dev/null) |
| 125 | fi |
| 126 | fi |
| 127 | ;; |
| 128 | esac |
| 129 | |
| 130 | # Set possible completions |
| 131 | COMPREPLY=($(compgen -W "${opts}" -- ${cur})) |
| 132 | } |
| 133 | complete -o default -o nospace -F __fab_completion fab |