Skip to content

Commit

Permalink
Update bash completion for 2.* instead of 2.0 only
Browse files Browse the repository at this point in the history
  • Loading branch information
nskaggs committed Feb 3, 2017
1 parent b135c7a commit 4754155
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 85 deletions.
162 changes: 81 additions & 81 deletions etc/bash_completion.d/juju-2.0 → etc/bash_completion.d/juju-2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# juju-core.bash_completion.sh: dynamic bash completion for juju 2.0 cmdline,
# juju-core.bash_completion.sh: dynamic bash completion for juju 2 cmdline,
# from parsed (and cached) juju status output.
#
# Author: JuanJo Ciarlante <[email protected]>
Expand All @@ -13,16 +13,16 @@
#

# Print (return) cache filename for "juju status"
_juju_2_0_juju_status_cache_fname() {
_JUJU_2_juju_status_cache_fname() {
local model=$(_get_current_model)
local juju_status_file=${cache_dir}/juju-status-"${model}"
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} \
echo ${_juju_cmd_JUJU_2_0?} status --model "${model}" --format json
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} \
echo ${_juju_cmd_JUJU_2?} status --model "${model}" --format json
return $?
}
# Print (return) all machines
_juju_2_0_machines_from_status() {
local cache_fname=$(_juju_2_0_juju_status_cache_fname)
_JUJU_2_machines_from_status() {
local cache_fname=$(_JUJU_2_juju_status_cache_fname)
[ -n "${cache_fname}" ] || return 0
${_juju_cmd_PYTHON?} -c '
import json, sys
Expand All @@ -33,8 +33,8 @@ print ("\n".join(j.get("machines", {}).keys()));
}

# Print (return) all units, each optionally postfixed by $2 (eg. 'myservice/0:')
_juju_2_0_units_from_status() {
local cache_fname=$(_juju_2_0_juju_status_cache_fname)
_JUJU_2_units_from_status() {
local cache_fname=$(_JUJU_2_juju_status_cache_fname)
[ -n "${cache_fname}" ] || return 0
${_juju_cmd_PYTHON?} -c '
trail = "'${2}'"
Expand All @@ -49,8 +49,8 @@ print ("\n".join([unit + trail for unit in all_units]))
}

# Print (return) all applications
_juju_2_0_applications_from_status() {
local cache_fname=$(_juju_2_0_juju_status_cache_fname)
_JUJU_2_applications_from_status() {
local cache_fname=$(_JUJU_2_juju_status_cache_fname)
[ -n "${cache_fname}" ] || return 0
${_juju_cmd_PYTHON?} -c '
import json, sys
Expand All @@ -61,12 +61,12 @@ print ("\n".join(j.get("applications", {}).keys()))
}

# Print (return) all actions IDS from (cached) "juju show-action-status" output
_juju_2_0_action_ids_from_action_status() {
_JUJU_2_action_ids_from_action_status() {
local model=$(_get_current_model)
local juju_status_file=${cache_dir}/juju-status-"${model}"
local cache_fname=$(
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} \
echo ${_juju_cmd_JUJU_2_0?} show-action-status --model "${model}" --format json
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} \
echo ${_juju_cmd_JUJU_2?} show-action-status --model "${model}" --format json
) || return $?
[ -n "${cache_fname}" ] || return 0
${_juju_cmd_PYTHON?} -c '
Expand All @@ -78,12 +78,12 @@ print ("\n".join([x["id"] for x in json.load(sys.stdin).get("actions", {})]))

# Print (return) all storage IDs from (cached) "juju list-storage" output
# Caches "juju list-storage" output, print(return) cache filename
_juju_2_0_storage_ids_from_list_storage() {
_JUJU_2_storage_ids_from_list_storage() {
local model=$(_get_current_model)
local juju_status_file=${cache_dir}/juju-status-"${model}"
local cache_fname=$(
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} \
echo ${_juju_cmd_JUJU_2_0?} list-storage --model "${model}" --format json
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} \
echo ${_juju_cmd_JUJU_2?} list-storage --model "${model}" --format json
) || return $?
[ -n "${cache_fname}" ] || return 0
${_juju_cmd_PYTHON?} -c '
Expand All @@ -94,29 +94,29 @@ print ("\n".join(json.load(sys.stdin).get("storage", {}).keys()))
}

# Print (return) both applications and units, currently used for juju status completion
_juju_2_0_applications_and_units_from_status() {
_juju_2_0_applications_from_status
_juju_2_0_units_from_status
_JUJU_2_applications_and_units_from_status() {
_JUJU_2_applications_from_status
_JUJU_2_units_from_status
}

# Print (return) both units and machines
_juju_2_0_units_and_machines_from_status() {
_juju_2_0_units_from_status
_juju_2_0_machines_from_status
_JUJU_2_units_and_machines_from_status() {
_JUJU_2_units_from_status
_JUJU_2_machines_from_status
}

# Print (return) all juju commands
_juju_2_0_list_commands() {
${_juju_cmd_JUJU_2_0?} help commands 2>/dev/null | awk '{print $1}'
_JUJU_2_list_commands() {
${_juju_cmd_JUJU_2?} help commands 2>/dev/null | awk '{print $1}'
}

# Print (return) flags for juju action
_juju_2_0_flags_for() {
_JUJU_2_flags_for() {
[ -n "${1}" ] || return 0
${_juju_cmd_JUJU_2_0?} help ${1} 2>/dev/null |egrep -o -- '(^|-)-[a-z-]+'|sort -u
${_juju_cmd_JUJU_2?} help ${1} 2>/dev/null |egrep -o -- '(^|-)-[a-z-]+'|sort -u
}

_juju_2_0_list_controllers_from_stdin() {
_JUJU_2_list_controllers_from_stdin() {
sed '1s/^$/{}/' |\
${_juju_cmd_PYTHON?} -c '
import json, sys
Expand All @@ -125,7 +125,7 @@ print ("\n".join(
json.load(sys.stdin).get("controllers", {}).keys())
)'
}
_juju_2_0_list_models_from_stdin() {
_JUJU_2_list_models_from_stdin() {
sed '1s/^$/{}/' |\
${_juju_cmd_PYTHON?} -c '
import json, sys
Expand All @@ -135,45 +135,45 @@ print ("\n".join(
))'
}
# List all controllers
_juju_2_0_list_controllers_noflags() {
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} cat \
${_juju_cmd_JUJU_2_0?} list-controllers --format json | \
_juju_2_0_list_controllers_from_stdin
_JUJU_2_list_controllers_noflags() {
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} cat \
${_juju_cmd_JUJU_2?} list-controllers --format json | \
_JUJU_2_list_controllers_from_stdin
}
# Print:
# - list of controllers as: <controller>:<current_model>
# - list of models under current controller
_juju_2_0_list_controllers_models_noflags() {
_JUJU_2_list_controllers_models_noflags() {
# derive cur_controller from fully specified current model: CONTROLLER:MODEL
local cur_controller=$(_get_current_model)
cur_controller=${cur_controller%%:*}

# List all controller:models
local controllers=$(_juju_2_0_list_controllers_noflags 2>/dev/null)
local controllers=$(_JUJU_2_list_controllers_noflags 2>/dev/null)
[ -n "${controllers}" ] || { echo "ERROR: no valid controller found (current: ${cur_controller})" >&2; return 0 ;}
local controller=
for controller in ${controllers};do
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} cat \
${_juju_cmd_JUJU_2_0?} list-models --controller ${controller} --format json |\
_juju_2_0_list_models_from_stdin "${controller}:"
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} cat \
${_juju_cmd_JUJU_2?} list-models --controller ${controller} --format json |\
_JUJU_2_list_models_from_stdin "${controller}:"
# early break, specially if user hit Ctrl-C
[ $? -eq 0 ] || return 1
done

# List all models under current controller
_juju_2_0_cache_cmd ${_juju_2_0_cache_TTL} cat \
${_juju_cmd_JUJU_2_0?} list-models --controller ${cur_controller} --format json |\
_juju_2_0_list_models_from_stdin
_JUJU_2_cache_cmd ${_JUJU_2_cache_TTL} cat \
${_juju_cmd_JUJU_2?} list-models --controller ${cur_controller} --format json |\
_JUJU_2_list_models_from_stdin
}

# Print (return) guessed completion function for cmd.
# Guessing is done by parsing 1st line of juju help <cmd>,
# see case switch below.
_juju_2_0_completion_func_for_cmd() {
_JUJU_2_completion_func_for_cmd() {
local action=${1} cword=${2}
# if cword==1 or action==help, use _juju_2_0_list_commands
# if cword==1 or action==help, use _JUJU_2_list_commands
if [ "${cword}" -eq 1 -o "${action}" = help ]; then
echo _juju_2_0_list_commands
echo _JUJU_2_list_commands
return 0
fi
# normally prev_word is just that ...
Expand All @@ -185,42 +185,42 @@ _juju_2_0_completion_func_for_cmd() {
[[ ${COMP_WORDS[cword-1]} == : ]] && prev_word=${COMP_WORDS[cword-3]}
case "${prev_word}" in
--controller|-c)
echo _juju_2_0_list_controllers_noflags; return 0;;
echo _JUJU_2_list_controllers_noflags; return 0;;
--model|-m)
echo _juju_2_0_list_controllers_models_noflags; return 0;;
echo _JUJU_2_list_controllers_models_noflags; return 0;;
--application)
echo _juju_2_0_applications_from_status; return 0;;
echo _JUJU_2_applications_from_status; return 0;;
--unit)
echo _juju_2_0_units_from_status; return 0;;
echo _JUJU_2_units_from_status; return 0;;
--machine)
echo _juju_2_0_machines_from_status; return 0;;
echo _JUJU_2_machines_from_status; return 0;;
esac
# parse 1st line of juju help <cmd>, to guess the completion function
# order below is important (more specific matches 1st)
case $(${_juju_cmd_JUJU_2_0?} help ${action} 2>/dev/null| head -1) in
case $(${_juju_cmd_JUJU_2?} help ${action} 2>/dev/null| head -1) in
# special case for ssh, scp:
*bootstrap*)
echo true ;; # help ok, existing command, no more expansion
*juju?ssh*|*juju?scp*)
echo _juju_2_0_units_and_machines_from_status;;
echo _JUJU_2_units_and_machines_from_status;;
*\<unit*)
echo _juju_2_0_units_from_status;;
echo _JUJU_2_units_from_status;;
*\<service*)
echo _juju_2_0_applications_from_status;;
echo _JUJU_2_applications_from_status;;
*\<application*)
echo _juju_2_0_applications_from_status;;
echo _JUJU_2_applications_from_status;;
*\<machine*)
echo _juju_2_0_machines_from_status;;
echo _JUJU_2_machines_from_status;;
*\<action*)
echo _juju_2_0_action_ids_from_action_status;;
echo _JUJU_2_action_ids_from_action_status;;
*show-storage*)
echo _juju_2_0_storage_ids_from_list_storage;;
echo _JUJU_2_storage_ids_from_list_storage;;
*pattern*|*application-or-unit*)
echo _juju_2_0_applications_and_units_from_status;; # e.g. status
echo _JUJU_2_applications_and_units_from_status;; # e.g. status
*\<controller*:*\<model*|*--model*)
echo _juju_2_0_list_controllers_models_noflags;;
echo _JUJU_2_list_controllers_models_noflags;;
*\<controller?name*)
echo _juju_2_0_list_controllers_noflags;;
echo _JUJU_2_list_controllers_noflags;;
?*)
echo true ;; # help ok, existing command, no more expansion
*)
Expand All @@ -238,17 +238,17 @@ _get_current_model() {
model="${model// /}"
fi
if [ -z "${model}" ];then
model=${JUJU_MODEL:-$(${_juju_cmd_JUJU_2_0?} switch)}
model=${JUJU_MODEL:-$(${_juju_cmd_JUJU_2?} switch)}
fi
echo "$model"
}
# Generic command cache function: caches cmdline output, called as:
# _juju_2_0_cache_cmd TTL ACTION cmd args ...
# _JUJU_2_cache_cmd TTL ACTION cmd args ...
# TTL: cache expiration in mins
# ACTION: what to do with cached filename:
# - cat (return content)
# - echo (return cache filename, think "pointer")
_juju_2_0_cache_cmd() {
_JUJU_2_cache_cmd() {
local cache_ttl="${1:?missing TTL}" # TTL in mins
local ret_action=${2:?missing what to return: "echo" or "cat"}
shift 2
Expand Down Expand Up @@ -282,7 +282,7 @@ _juju_2_0_cache_cmd() {

# Main completion function wrap:
# calls passed completion function, also adding flags for cmd
_juju_2_0_complete_with_func() {
_JUJU_2_complete_with_func() {
local action="${1}" func=${2?}
# scp is special, as we want ':' appended to unit names,
# and filename completion also.
Expand All @@ -293,12 +293,12 @@ _juju_2_0_complete_with_func() {
compopt -o nospace
fi

# build COMPREPLY from passed function stdout, and _juju_2_0_flags_for $action
# build COMPREPLY from passed function stdout, and _JUJU_2_flags_for $action
# don't clutter with cmd flags for functions named *_noflags
local flags
case "${func}" in
*_noflags) flags="";;
*) flags=$(_juju_2_0_flags_for "${action}");;
*) flags=$(_JUJU_2_flags_for "${action}");;
esac

#echo "** comp=$(set|egrep ^COMP) ** func=$func **" >&2
Expand All @@ -319,34 +319,34 @@ _juju_2_0_complete_with_func() {
}

# Not used here, available to the user for quick cache removal
_juju_2_0_rm_completion_cache() {
_JUJU_2_rm_completion_cache() {
rm -fv $HOME/.cache/juju/juju-status-*
}

# main completion function entry point
_juju_complete_2_0() {
_juju_complete_2() {
local action parsing_func
action="${COMP_WORDS[1]}"
COMPREPLY=()
parsing_func=$(_juju_2_0_completion_func_for_cmd "${action}" ${COMP_CWORD})
parsing_func=$(_JUJU_2_completion_func_for_cmd "${action}" ${COMP_CWORD})
test -n "${parsing_func}" && \
_juju_2_0_complete_with_func "${action}" "${parsing_func}"
_JUJU_2_complete_with_func "${action}" "${parsing_func}"
return $?
}
# _juju_2_0_cache_TTL [mins]
export _juju_2_0_cache_TTL=2
# _JUJU_2_cache_TTL [mins]
export _JUJU_2_cache_TTL=2

# All above completion is juju-2.0 specific, uses $_juju_cmd_JUJU_2_0
# All above completion is juju-2 specific, uses $_juju_cmd_JUJU_2

# Detect juju built from source (highest priority)
if [ -x "$GOPATH/bin/juju" ]; then
export _juju_cmd_JUJU_2_0="$GOPATH/bin/juju"
# Detect installed juju-2.0 binary (next highest priority)
elif [ -x "/usr/bin/juju-2.0" ]; then
export _juju_cmd_JUJU_2_0="/usr/bin/juju-2.0"
export _juju_cmd_JUJU_2="$GOPATH/bin/juju"
# Detect installed juju-2 binary (next highest priority)
elif [ -x "/usr/bin/juju-2" ]; then
export _juju_cmd_JUJU_2="/usr/bin/juju-2"
# Use /usr/bin/juju as a last resort.
else
export _juju_cmd_JUJU_2_0="/usr/bin/juju"
export _juju_cmd_JUJU_2="/usr/bin/juju"
fi

# Select python3, else python2
Expand All @@ -355,14 +355,14 @@ for _juju_cmd_PYTHON in /usr/bin/python{3,2};do
[ -x ${_juju_cmd_PYTHON?} ] && break
done

# Add juju-2.0 completion
complete -F _juju_complete_2_0 juju-2.0
# Add juju-2 completion
complete -F _juju_complete_2 juju-2

# Also hook "juju" (without version) to make this file "self" sufficient.
#
# Note that in a normal install will be overridden later by
# /etc/bash_completion.d/juju-version which does runtime detection
# of 1.x or 2.0 autocompletion.
complete -F _juju_complete_2_0 juju
# of 1.x or 2 autocompletion.
complete -F _juju_complete_2 juju

# vim: ai et sw=2 ts=2
8 changes: 4 additions & 4 deletions etc/bash_completion.d/juju-version
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# "run"time juju completion by version
_juju_complete_ver() {
case "$(juju version)" in
2.0*)
# See /etc/bash_completion.d/juju-2.0
_juju_complete_2_0 "$@"
2.*)
# See /etc/bash_completion.d/juju-2
_juju_complete_2 "$@"
return $?
;;
1.*)
Expand All @@ -17,7 +17,7 @@ _juju_complete_ver() {
# Hook _juju_complete_ver for 'juju' cmd
# If juju-1 is also installed, it'll override it's completion
# as this "juju-version" named file will be loaded after
# "juju-2.0" and "juju-core".
# "juju-2" and "juju-core".
complete -F _juju juju-1
complete -F _juju_complete_ver juju

Expand Down

0 comments on commit 4754155

Please sign in to comment.