#compdef rpm # This uses `_arguments' in a state-machine kind of way. These states # have names and before executing the default action for such a state # we try to call a function with the name `_rpm_'. If such a # function exists, we return with its return status immediately. This # allows users to override the default completions by simply defining # these functions. # The states (and possible values for the `' above) are: # # query # complete for `rpm -q' query # verify # complete for `rpm --verify' # install # complete for `rpm -i' or `rpm --install' # upgrade # complete for `rpm -U' or `rpm --upgrade' # uninstall # complete for `rpm -e' or `rpm --erase' # build_b # complete for `rpm -bx' (the stage `x' is already completed) # build_t # complete for `rpm -tx' (the stage `x' is already completed) # sigcheck # complete for `rpm --sigcheck' # rebuild # complete for `rpm --rebuild' # package # complete a RPM package name # package_file # complete a RPM package file name # package_or_file # the previous two together # tags # complete a tag name # capability # complete a capability # relocate # complete a `old=new' pair of paths # Used by `_arguments', made local here. _rpm () { local curcontext="$curcontext" state lstate line nm="$compstate[nmatches]" typeset -A opt_args state='' local ret=1 local -a tmp expl commonopts packageopts commonopts=( '*-v[verbose mode]' '--rcfile:resource file:_files' '--ftpproxy:FTP proxy server:_hosts' '--ftpport:FTP port number:' '--httpproxy:HTTP proxy server:_hosts' '--httpport:HTTP port number:' ) packageopts=( '-a[query all packages]' '-p[query uninstalled package file]:*:RPM package file:->package_file' '-f[specify file to query owner of]:file:_files' '--triggeredby:RPM package:->package' '--whatprovides:RPM capability:->capability' '--whatrequires:RPM capability:->capability' ) pathopts=( '--root:RPM root directory:_files -/' '--dbpath:RPM database path:_files -/' ) # Do simple completions or get the first state. _arguments -C -s \ '--help[print help message]' \ '--version[print version number]' \ "${commonopts[@]}" \ '-q+[query mode]:*:query:->query' \ --{querytags,initdb,showrc} \ '--pipe:pipe command:_command_names -e' \ -{V,y}'[verify mode]:*:verify:->verify' \ '--verify[verify mode]:*:verify:->verify' \ '--setperms[set file permissions]:*:package:->setattrs' \ '--setugids[set file owner/group]:*:package:->setattrs' \ '(--install)-i+[install mode]:*:install:->install' \ '(-i)--install:*:install:->install' \ '(--upgrade)-U+[upgrade mode]:*:upgrade:->upgrade' \ '(-U)--upgrade:*:upgrade:->upgrade' \ '(--freshen)-F+[freshen mode]:*:upgrade:->upgrade' \ '(-F)--freshen:*:upgrade:->upgrade' \ '(--erase)-e+[uninstall mode]:*:uninstall:->uninstall' \ '(-e)--erase:*:uninstall:->uninstall' \ '-b+[build mode (spec file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_b' \ '(-b)-t+[build mode (tar file)]:build stage:((p\:execute\ \%prep\ stage l\:do\ a\ list\ check c\:execute\ build\ stage i\:execute\ install\ stage b\:build\ a\ binary\ package a\:build\ binary\ and\ source\ packages)):*:build:->build_t' \ --{resign,addsign}':*:RPM package:->package_file' \ '--rmsource:*:spec file:->spec_file' \ --{rebuild,recompile}':*:Src RPM files:->package_src' \ '(--checksig)-K+[signature check mode]:*:sigcheck:->sigcheck' \ '(-K)--checksig:*:sigcheck:->sigcheck' \ '--rebuilddb:*:rebuild:->rebuild' && ret=0 # As long as we have a state name... while [[ -n "$state" ]]; do # First try to call a user-defined function. _call_function ret _rpm_$state && return ret # Copy the state and reset `state', to simplify the test above. lstate="$state" state='' tmp=() # Dispatch... case "$lstate" in query) # --dump requires on of -{l,c,d} # --triggers requires --script _arguments -s \ -q "${commonopts[@]}" "${packageopts[@]}" "${pathopts[@]}" \ '--queryformat:RPM query format:->tags' \ '-i[display package information]' \ '--changelog[display change log]' \ '-l[display package file list]' \ '-s[show file states]' \ '-d[documentation files only]' \ '-c[configuration files only]' \ '--dump[show all information]' \ --provides \ -{R,-requires}'[list dependencies]' \ '--scripts[show (un)install scripts]' \ '--triggers[show trigger scripts]' \ '*:RPM package:->package_or_file' && ret=0 ;; setattrs) _arguments -s --set{perm,ugids} "${packageopts[@]}" && ret = 0 ;; verify) _arguments -s \ '(-y --verify)-V' '(-V --verify)-y' '(-y -V)--verify' \ "${commonopts[@]}" "${packageopts[@]}" "${pathopts[@]}" \ --no{deps,md5,files} \ '*:RPM package:->package_or_file' && ret=0 ;; upgrade) tmp=( '(--upgrade)-U' '(-U)--upgrade' '(--force)--oldpackage' ) ;& install) (( $#tmp )) || tmp=( '(--install)-i' '(-i)--install' ) _arguments -s "$tmp[@]" \ "${commonopts[@]}" "${pathopts[@]}" \ '--excludepath:exclude files in following path:_files -/' \ '--relocate:relocate:->relocate' \ '--prefix:package prefix directory:_files -/' \ '(-h)--hash' '(--hash)-h' \ '(--replacepkgs --replacefiles --oldpackage)--force' \ '(--force)--'{replacefiles,replacepkgs} \ --{badreloc,excludedocs,allfiles,ignorearch,ignoreos,includedocs,justdb,nodeps,noorder,noscripts,notriggers,percent,test} \ '*:pkg file:->package_file' && ret=0 ;; uninstall) _arguments -s \ '(-e)--erase' '(--erase)-e' \ "${commonopts[@]}" "${pathopts[@]}" \ --{allmatches,justdb,nodeps,noorder,noscripts,notriggers} \ '*:RPM package:->package' && ret=0 ;; build_b) tmp=( '*:spec file:_files -g \*.spec' ) ;& build_t) (( $#tmp )) || tmp=( '*:tar file:_files -g \*.\(\#i\)tar\(.\*\|\)' ) _arguments -s \ "${commonopts[@]}" "${pathopts[@]}" \ --{short-circuit,clean,nobuild,rmsource,sign,test} \ '--target:specify a build target:->target'\ '--buildroot:build root directory:_files -/' \ '--buildarch:architecture for which to build:->target' \ '--buildos:operating system for which to build:' \ '--timecheck:time check (seconds):' "$tmp[1]" && ret=0 ;; sigcheck) _arguments -s \ '(-K)--checksig' '(--checksig)-K' \ "${commonopts[@]}" \ --no{gpg,pgp,md5} \ '*:RPM package file:->package_file' && ret=0 ;; rebuild) _arguments -s \ "${commonopts[@]}" "${pathopts[@]}" \ '*:RPM source package file:->package_file' && ret=0 ;; target) _wanted target expl 'Target platforms' \ compadd $(_call_program target rpm --showrc 2> /dev/null |grep 'compatible archs'|sed 's/.*: //') && ret=0 ;; package_or_file) state=package_file ;& package) if ( [[ ${+_rpms} -eq 0 ]] || _cache_invalid RPMs ) && ! _retrieve_cache RPMs; then _rpms=( $(_call_program packages rpm -qa 2>/dev/null) ) _store_cache RPMs _rpms fi _wanted packages expl 'RPM package' \ compadd -M 'r:|-=* r:|=*' - "$_rpms[@]" && ret=0 ;; spec_file) _wanted specfiles expl 'spec file' \ _files -g \*.spec && ret=0 ;; package_file) _wanted files expl 'RPM package file' \ _files -g '*.(#i)rpm' && ret=0 if [[ -prefix 1 (f|ht)tp:// ]]; then _wanted urls expl 'URL of RPM package file' \ _urls -f -g '*.(#i)rpm' "${expl[@]}" && ret=0 else _wanted urls expl 'URL of RPM package file' \ compadd -S '' "${expl[@]}" ftp:// http:// && ret=0 fi ;; package_src) _files -g \*.src\(\#i\).rpm ;& tags) if compset -P '*%*\{'; then _wanted tags expl 'RPM tag' \ compadd -M 'm:{a-z}={A-Z}' -S '\}' - \ "${(@)${(@f)$(_call_program tags rpm --querytags 2> /dev/null)}#RPMTAG_}" && ret=0 else _message -e formats 'RPM format' fi ;; capability) _message -e capabilities 'RPM capability' ;; relocate) if compset -P '*='; then _description directories expl 'new path' else _description directories expl 'old path' fi _files "$expl[@]" -/ && ret=0 ;; esac [[ ret -eq 0 || $nm -ne $compstate[nmatches] ]] && return 0 done return ret } # set a sensible default caching policy local update_policy zstyle -s ":completion:*:*:rpm:*" cache-policy update_policy if [[ -z "$update_policy" ]]; then zstyle ":completion:*:*:rpm:*" cache-policy _rpms_caching_policy fi _rpms_caching_policy () { # rebuild if cache is more than a week old oldp=( "$1"(mw+1) ) (( $#oldp )) && return 0 pkg_indices=( /var/lib/rpm/{packages.rpm,Packages}(N) ) for pkg_index in $pkg_indices; do [[ "$pkg_index" -nt "$1" ]] && return 0 done } _rpm "$@"