github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/etc/bash_completion.d/juju2 (about)

     1  # juju-core.bash_completion.sh: dynamic bash completion for juju cmdline,
     2  # from parsed (and cached) juju status output.
     3  #
     4  # Author: JuanJo Ciarlante <jjo@canonical.com>
     5  # Copyright 2013+, Canonical Ltd.
     6  # License: GPLv3
     7  #
     8  
     9  # Print (return) all machines
    10  _juju_machines_from_file() {
    11  python -c '
    12  import json, sys; j=json.load(sys.stdin)
    13  print "\n".join(j["machines"].keys());' < ${1?}
    14  }
    15  
    16  # Print (return) all units, each optionally postfixed by $2 (eg. 'myservice/0:')
    17  _juju_units_from_file() {
    18  python -c '
    19  trail="'${2}'"
    20  import json, sys; j=json.load(sys.stdin)
    21  all_units=[]
    22  for k,v in j["services"].items():
    23      if v.get("units"):
    24          all_units.extend(v.get("units",{}).keys())
    25  print "\n".join([unit + trail for unit in all_units])
    26  ' < ${1?}
    27  }
    28  
    29  # Print (return) all services
    30  _juju_services_from_file() {
    31  python -c '
    32  import json, sys; j=json.load(sys.stdin)
    33  print "\n".join(j["services"].keys());' < ${1?}
    34  }
    35  
    36  # Print (return) both services and units, currently used for juju status completion
    37  _juju_services_and_units_from_file() {
    38      _juju_services_from_file "$@"
    39      _juju_units_from_file "$@"
    40  }
    41  
    42  # Print (return) all juju commands
    43  _juju_list_commands() {
    44      juju help commands 2>/dev/null | awk '{print $1}'
    45  }
    46  
    47  # Print (return) flags for juju action, shamelessly excluding
    48  # -m/--model for cleaner completion for common usage cases
    49  # (e.g. juju ssh <TAB>, etc)
    50  _juju_flags_for() {
    51      test -z "${1}" && return 0
    52      juju help ${1} 2>/dev/null |egrep -o --  '(^|-)-[a-z-]+'|egrep -v -- '^(-m|--model)'|sort -u
    53  }
    54  
    55  # Print (return) guessed completion function for cmd.
    56  # Guessing is done by parsing 1st line of juju help <cmd>,
    57  # see case switch below.
    58  _juju_completion_func_for_cmd() {
    59      local action=${1} cword=${2}
    60      # if cword==1 or action==help, use _juju_list_commands
    61      if [ "${cword}" -eq 1 -o "${action}" = help ]; then
    62          echo _juju_list_commands
    63          return 0
    64      fi
    65      # parse 1st line of juju help <cmd>, to guess the completion function
    66      case $(juju help ${action} 2>/dev/null| head -1) in
    67          # special case for ssh, scp which have 'service' in 1st line of help:
    68          *\<unit*|*juju?ssh*|*juju?scp*)    echo _juju_units_from_file;;
    69          *\<service*)    echo _juju_services_from_file;;
    70          *\<machine*)    echo _juju_machines_from_file;;
    71          *pattern*)      echo _juju_services_and_units_from_file;; # e.g. status
    72          ?*)     echo true ;;  # help ok, existing command, no more expansion
    73          *)      echo false;;  # failed, not a command
    74      esac
    75  }
    76  
    77  # Print (return) filename from juju status cached output (if not expired),
    78  # create cache dirs if needed
    79  # - setups caching dir if non-existent
    80  # - caches juju status output, $cache_mins minutes max
    81  _juju_get_status_filename() {
    82      local cache_mins=60     # ttl=60 mins
    83      local cache_dir=$HOME/.cache/juju
    84      local juju_status_file=${cache_dir}/juju-status-${JUJU_MODEL:-default}
    85      # setup caching dir under ~/.cache/juju
    86      test -d ${cache_dir} || install -d ${cache_dir} -m 700
    87      # if can't find a fresh (age < $cache_mins) saved file, with a ~reasonable size ...
    88      if [[ -z $(find "${juju_status_file}" -mmin -${cache_mins} -a -size +32c 2> /dev/null) ]]; then
    89          # ... create it
    90          juju status --format=json > "${juju_status_file}".tmp && \
    91              mv "${juju_status_file}".tmp "${juju_status_file}"
    92          rm -f "${juju_status_file}".tmp
    93      fi
    94      if [ -r "${juju_status_file}" ]; then
    95          echo "${juju_status_file}"
    96      else
    97          return 1
    98      fi
    99  }
   100  # Main completion function wrap:
   101  # calls passed completion function, also adding flags for cmd
   102  _juju_complete_with_func() {
   103      local action="${1}" func=${2?}
   104      local cur
   105  
   106      # scp is special, as we want ':' appended to unit names,
   107      # and filename completion also.
   108      local postfix_str= compgen_xtra=
   109      if [ "${action}" = "scp" ]; then
   110          local orig_comp_wordbreaks="${COMP_WORDBREAKS}"
   111          COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}"
   112          postfix_str=':'
   113          compgen_xtra='-A file'
   114          compopt -o nospace
   115      fi
   116      juju_status_file=
   117      # if func name ends with 'from_file', set juju_status_file
   118      [[ ${func} =~ .*from_file ]] &&  juju_status_file=$(_juju_get_status_filename)
   119      # build COMPREPLY from passed function stdout, and _juju_flags_for $action
   120      cur="${COMP_WORDS[COMP_CWORD]}"
   121      COMPREPLY=( $( compgen ${compgen_xtra} -W "$(${func} ${juju_status_file} ${postfix_str}) $(_juju_flags_for "${action}")" -- ${cur} ))
   122      if [ "${action}" = "scp" ]; then
   123          COMP_WORDBREAKS="${orig_comp_wordbreaks}"
   124          compopt +o nospace
   125      fi
   126      return 0
   127  }
   128  
   129  # Not used here, available to the user for quick cache removal
   130  _juju_completion_cache_rm() {
   131      rm -fv $HOME/.cache/juju/juju-status-${JUJU_MODEL:-default}
   132  }
   133  
   134  # main completion function entry point
   135  _juju() {
   136      local action parsing_func
   137      action="${COMP_WORDS[1]}"
   138      COMPREPLY=()
   139      parsing_func=$(_juju_completion_func_for_cmd "${action}" ${COMP_CWORD})
   140      test -z "${parsing_func}" && return 0
   141      _juju_complete_with_func "${action}" "${parsing_func}"
   142      return $?
   143  }
   144  complete -F _juju juju
   145  # vim: ai et sw=2 ts=2