2
# juju.autocomp: dynamic bash completion for juju cmdline
4
# Author: JuanJo Ciarlante <jjo@canonical.com>
5
# Copyright 2013+, Canonical Ltd.
8
# DISCLAIMER: using bash completion is great,
9
# cleanly implementing it is ... impossible ?.
13
_juju_machines_from_file() {
14
python -c 'import json, sys;j=json.load(sys.stdin);print "\n".join(j["machines"].keys());' < ${1?}
17
# Show all units, each optionally postfixed by $2 (eg. 'myservice/0:')
18
_juju_units_from_file() {
22
j=json.load(sys.stdin)
24
for k,v in j["services"].items():
26
all_units.extend(v.get("units",{}).keys())
27
print "\n".join([unit + s for unit in all_units])
32
_juju_services_from_file() {
33
python -c 'import json, sys;j=json.load(sys.stdin);print "\n".join(j["services"].keys());' < ${1?}
36
# Show 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 "$@"
42
# Main completion function:
43
# - setups caching dir if non-existent
44
# - caches juju status output, $cache_mins minutes max
45
# - parses cached status file with passed func
46
# - optionally adds compgen_xtra options, words_xtra
47
_juju_complete_cached() {
48
local func=${1?} postfix_str="${2}" compgen_xtra="${3}" words_xtra="${4}"
51
local cache_dir=$HOME/.cache/juju
52
local juju_status_file=${cache_dir}/juju-status-${JUJU_ENV:-default}
53
cur="${COMP_WORDS[COMP_CWORD]}"
54
# setup caching dir under ~/.cache/juju
55
test -d ${cache_dir} || install -d ${cache_dir} -m 700
56
if [[ -z $(find "${juju_status_file}" -mmin -${cache_mins} -a -size +32c 2> /dev/null) ]]; then
57
juju status --format=json > "${juju_status_file}".tmp && \
58
mv "${juju_status_file}".tmp "${juju_status_file}"
59
rm -f "${juju_status_file}".tmp
61
# if a postfix_str is passed (eg ':'), allow nospace
62
if [ -n "${postfix_str}" ]; then
67
[[ -r "${juju_status_file}" ]] || return 0
68
# build COMPREPLY from passed function stdout
69
COMPREPLY=( $( compgen ${compgen_xtra} -W "${words_xtra} $(${func} ${juju_status_file} ${postfix_str})" -- ${cur} ))
73
# Not used here, available to the user for quick cache removal
74
_juju_completion_cache_rm() {
75
rm -fv $HOME/.cache/juju/juju-status-${JUJU_ENV?}
78
# Get juju commands from its help
81
local cur prev options files targets
83
cur="${COMP_WORDS[COMP_CWORD]}"
84
prev="${COMP_WORDS[COMP_CWORD-1]}"
85
actions=$(juju help commands 2>/dev/null | awk '{print $1}')
86
COMPREPLY=( $( compgen -W "${actions}" -- ${cur} ) )
90
# Entry completion function
93
local orig_comp_wordbreaks="${COMP_WORDBREAKS}"
94
prev="${COMP_WORDS[COMP_CWORD-1]}"
97
# non dynamic completions:
102
_juju_complete_cached _juju_services_and_units_from_file;;
103
upgrade-charm|*expose|*-service|*-constraints|set|get)
104
_juju_complete_cached _juju_services_from_file;;
106
_juju_complete_cached _juju_services_from_file "" "" "-n --to";;
108
ssh|remove-unit|debug-hooks)
109
_juju_complete_cached _juju_units_from_file;;
111
# tmp remove ':' from as word separator
112
COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}"
113
# append ':' to units, also complete filenames
114
_juju_complete_cached _juju_units_from_file ":" "-A file";;
116
_juju_complete_cached _juju_units_from_file "" "" "-r";;
118
_juju_complete_cached _juju_services_from_file;;
121
_juju_complete_cached _juju_machines_from_file;;
124
if [ -z "${COMPREPLY}" ]; then
125
# another case switch, for actions requiring completion for >3rd
126
# argument, e.g.: add-relation srv1 srv2
127
local juju_action="${COMP_WORDS[1]}"
128
case "${juju_action}" in
129
# non-dynamic actions (simplified)
131
local words="--constraints --series --source --upload-tools"
132
COMPREPLY=( $( compgen -W "${words}" -- ${COMP_WORDS[COMP_CWORD]} ));;
134
local words="--dev --series --upload-tools --version"
135
COMPREPLY=( $( compgen -W "${words}" -- ${COMP_WORDS[COMP_CWORD]} ));;
137
local words="--format -o"
138
COMPREPLY=( $( compgen -W "${words}" -- ${COMP_WORDS[COMP_CWORD]} ));;
141
_juju_complete_cached _juju_services_from_file;;
142
# (some) actions with optional switches:
144
COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}"
145
_juju_complete_cached _juju_units_from_file ":" "-A file";;
147
_juju_complete_cached _juju_units_from_file;;
149
_juju_complete_cached _juju_services_from_file;;
153
COMP_WORDBREAKS="${orig_comp_wordbreaks}"
156
complete -F _juju juju
157
# vim: ai et sw=2 ts=2