diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Completion/Unix/Command/.distfiles | 1 | ||||
-rw-r--r-- | Completion/Unix/Command/_initctl | 181 |
3 files changed, 189 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index 2ab4972b6..b445f0c09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-25 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Bernhard Tittelbach: 29371: Completion/Unix/Command/_initctl: + completion for initctl and related system job management + utilities. + 2011-05-24 Barton E. Schaefer <schaefer@brasslantern.com> * 29368: Src/exec.c: do not restore xtrerr to stderr before @@ -14814,5 +14820,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5327 $ +* $Revision: 1.5328 $ ***************************************************** diff --git a/Completion/Unix/Command/.distfiles b/Completion/Unix/Command/.distfiles index 756ccec74..9b28418d5 100644 --- a/Completion/Unix/Command/.distfiles +++ b/Completion/Unix/Command/.distfiles @@ -95,6 +95,7 @@ _ifconfig _iftop _imagemagick _init_d +_initctl _ip _irssi _ispell diff --git a/Completion/Unix/Command/_initctl b/Completion/Unix/Command/_initctl new file mode 100644 index 000000000..08145b19e --- /dev/null +++ b/Completion/Unix/Command/_initctl @@ -0,0 +1,181 @@ +#compdef initctl start stop restart reload status +# Written by Bernhard Tittelbach +# based on completion script by Mildred + +local -a common_args +common_args=( + '--session[use D-Bus session bus to connect to init daemon (for testing)]' + '--system[talk via DBUS system bus instead of socket]' + '(-q --quiet)'{-q,--quiet}'[reduce output to errors only]' + '(-v --verbose)'{-v,--verbose}'[increase output to include informational messages]' + '--dest=[D-Bus name for init, defaults to com.ubuntu.Upstart]' + '--help[display help and exit]' + '--version[output version information and exit]' +) + +# don't overwrite work that we might have already done +if (( ${+_initctl_events_list} + ${+_initctl_eventargs_list} != 2 )); then + typeset -g -a -U _initctl_events_list _initctl_eventargs_list +fi + +# map each initctl function to a completion function +local -A cmd_completion_funcs +cmd_completion_funcs=( start startstop stop startstop restart startstop reload startstop show-config show-config status argjob emit emit check-config check-config ) + +# define fallback completion function +local cmd_completion_default=basic + +# run show-config -e and if possible parse out all events and KEY= argumnts +# otherwise provide some common values +_initctl_fillarray_events_args () +{ + setopt extendedglob + local showconfig="$(initctl show-config -e 2>| /dev/null)" + if [[ -n "$showconfig" ]]; then + _initctl_events_list=() + _initctl_eventargs_list=() + for cline in "${(f)showconfig}"; do + if [[ "$cline" == (#s)\ \ (stop\ on|start\ on|emit)\ (#b)([[:alpha:]-_]##)(*)(#e) ]]; then + _initctl_events_list+=($match[1]) + # this is a bit tricky, we take the string right of the matched event + # and parse for \sUPPERCASE=\S (in perl-re syntax) substrings until there are no more matches + # since we can't do multiple matches, we concatenated the remaing strings and try again + local stml="$match[2]" + while [[ "$stml" == (#b)(*)\ ([[:upper:]_]##\=)[^[:space:]](#b)(*) ]]; do + _initctl_eventargs_list+=($match[2]) + stml="$match[1] $match[3]" + done + unset stml + fi + done + else + _initctl_events_list=( socket login-session-start desktop-session-start virtual-filesystems local-filesystems remote-filesystems all-swaps filesystem mounting mounted net-device-up start-portmap runlevel unmounted-remote-filesystems ) + _initctl_eventargs_list=( PRIMARY_DEVICE_FOR_DISPLAY= EXIT_STATUS= EXIT_SIGNAL= RUNLEVEL= MOUNTPOINT= TYPE= INTERFACE= ) + fi + return 0 +} + +# list all upstart jobs, i.e. all files in /etc/init/ +_initctl_helper_jobs() +{ + _path_files -W "/etc/init/" -g "*.conf(.:r)" +} + +# list events, generate array if necessary +_initctl_known_events() +{ + [[ ${#_initctl_events_list} -eq 0 ]] && _initctl_fillarray_events_args + _values "Event" "$_initctl_events_list[@]" +} + +# list events, allow multiple choices, generate array if necessary +_initctl_multiple_known_events() +{ + [[ ${#_initctl_events_list} -eq 0 ]] && _initctl_fillarray_events_args + _values -s "," "Events" "$_initctl_events_list[@]" +} + +# list KEY= arguments, generate array if necessary +_initctl_known_eventargs() +{ + [[ ${#_initctl_eventargs_list} -eq 0 ]] && _initctl_fillarray_events_args + _values "Argument Keys" "$_initctl_eventargs_list[@]" +} + +# describe and offer commands for initctl, then call matching completion function +_initctl_command() +{ + local cmds + cmds=( + start:"Start jobs" + stop:"Stop jobs" + restart:"Restart jobs" + reload:"Send SIGHUP to process instance" + status:"Query status of jobs" + list:"List known jobs" + emit:"Emit an event" + reload-configuration:"tell init to reload config files (generally inotify is used)" + version:"Request the version of the init daemon" + log-priority:"Change the minimum priority of log messages from the init daemon" + show-config:"Show start/stop/emit for processes" + check-config:"Find jobs than can't be started" + help:"display list of commands" + ) + + if (( CURRENT == 1 )); then + _describe -t command "initctl Commands" cmds + fi + + local cmd=$words[1] + + local curcontext="${curcontext%:*}:initctl-${cmd}" + _call_function ret _initctl_${cmd_completion_funcs[${cmd}]-${cmd_completion_default}} +} + +# completion for start/stop/restart/reload i.e. anything that take one job and multiple KEY= arguments's +_initctl_startstop() +{ + _arguments \ + '--no-wait[do not wait for operation to complete before exiting]' \ + "${common_args[@]}" \ + ':Upstart Jobs:_initctl_helper_jobs' \ + '*::Argument Keys:_initctl_known_eventargs' +} + +# completion for anything that takes one job +_initctl_argjob() +{ + _arguments \ + "${common_args[@]}" \ + ':Upstart Jobs:_initctl_helper_jobs' \ + '*::' +} + +# completion for emit, providing options, one event and multiple KEY= arguments's +_initctl_emit() +{ + _arguments \ + '--no-wait[do not wait for event to finish before exiting]' \ + "${common_args[@]}" \ + ':Events:_initctl_known_events' \ + '*::Argument Keys:_initctl_known_eventargs' +} + +# the fallback, just the options +_initctl_basic() +{ + _arguments \ + "${common_args[@]}" +} + +# completion for show-config, additional option and one job +_initctl_show-config() +{ + _arguments \ + "(-e --enumerate)"{-e,--enumerate}"[enumerate emit lines]" \ + "${common_args[@]}" \ + '::Upstart Jobs:_initctl_helper_jobs' \ + '*::' +} + +# completion for show-config, additional options and one job +_initctl_check-config() +{ + _arguments \ + "(-i --ignore-events)"{-i,--ignore-events}"[list of comma-separated events to ignore]:Events:_initctl_multiple_known_events" \ + "(-w --warn)"{-w,--warn}"[treat any unknown jobs or events as error]" \ + "${common_args[@]}" \ + '::Upstart Jobs:_initctl_helper_jobs' \ + '*::' +} + +# depending on which command was used, call different completion funtions +case $service in + initctl) + _arguments "${common_args[@]}" '*::Initctl Commands:_initctl_command' + ;; + start|stop|restart|reload|status) + _call_function ret _initctl_${cmd_completion_funcs[${service}]-${cmd_completion_default}} + ;; + *) return 1 ;; +esac |