mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-20 14:04:03 +01:00
327 lines
11 KiB
Plaintext
327 lines
11 KiB
Plaintext
#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_<state>'. 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 `<state>' 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
|
|
|
|
_rpm () {
|
|
local curcontext="$curcontext" state lstate line nm="$compstate[nmatches]"
|
|
typeset -A opt_args
|
|
local ret=1
|
|
local -a tmp expl commonopts selectopts
|
|
|
|
commonopts=(
|
|
'(-v --verbose)--quiet[print as little as possible]'
|
|
'(--quiet)*'{-v,--verbose}'[verbose output]'
|
|
'--rcfile:resource file:_files'
|
|
'--ftpproxy:ftp proxy server:_hosts'
|
|
'--ftpport:ftp port number'
|
|
'--httpproxy:http proxy server:_hosts'
|
|
'--httpport:http port number'
|
|
{-\?,--help}'[print help information]'
|
|
'--version[print version number]'
|
|
'--pipe:pipe command:->command' \
|
|
)
|
|
|
|
# package selection options of which only one can be used
|
|
selectopts=(
|
|
{-a,--all}'[query all packages]'
|
|
{-f,--file}'[query packages that own specified files]'
|
|
{-p,--package}'[query uninstalled packages]'
|
|
{-g,--group}'[query packages in one of specified groups]'
|
|
--fileid --hdrid --pkgid --tid --querybynumber
|
|
'--triggeredby'
|
|
'--whatprovides'
|
|
'--whatrequires'
|
|
)
|
|
sopts=${selectopts%\[*}\ --specfile
|
|
selectopts=(
|
|
"(* $sopts)"${selectopts[1,2]}
|
|
"($sopts)"${selectopts[3,-1]}
|
|
'(-a --all)*: :->package-select'
|
|
)
|
|
|
|
pathopts=(
|
|
'--root:rpm root directory:_files -/'
|
|
'--dbpath:rpm database path:_files -/'
|
|
)
|
|
|
|
_arguments -C -s \
|
|
"${commonopts[@]}" \
|
|
{-q+,--query}'[query mode]:*:query:->query' \
|
|
'(-V -y --verify)'{-V+,-y+,--verify}'[verify mode]:*:verify:->verify' \
|
|
'--import:*:public key' \
|
|
'(-K --checksig)'{-K,--checksig}'[signature check mode]:*:sigcheck:->sigcheck' \
|
|
'(-i --install)'{-i+,--install}'[install mode]:*:install:->install' \
|
|
'(-U --upgrade)'{-U+,--upgrade}'[upgrade mode]:*:upgrade:->upgrade' \
|
|
'(-F --freshen)'{-F+,--freshen}'[freshen mode]:*:upgrade:->upgrade' \
|
|
'(-e --erase)'{-e+,--erase}'[uninstall mode]:*:uninstall:->uninstall' \
|
|
--{initdb,querytags,showrc} \
|
|
'--rebuilddb:*:rebuild:->rebuild' \
|
|
--{resign,addsign}':*:package:->package_file' \
|
|
'--setperms[set file permissions]:*:package:->setattrs' \
|
|
'--setugids[set file owner/group]:*:package:->setattrs' \
|
|
'-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' \
|
|
'--rmsource:*:spec file:->spec_files' \
|
|
--{rebuild,recompile}':*:source rpm file:->package_src' \
|
|
'--eval:macro:->macros' && 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 one of -{l,c,d}
|
|
# --triggers requires --script
|
|
_arguments -s \
|
|
\!{-q,--query} "${commonopts[@]}" "${selectopts[@]}" "${pathopts[@]}" \
|
|
"($sopts)--specfile[query specified spec file as if it were a package]" \
|
|
'(-i --info)'{-i,--info}'[display package information]' \
|
|
'--changelog[display change log]' \
|
|
'(-s --state -l --list --filesbypkg)'{-l,--list}'[display package file list]' \
|
|
'(-s --state -l --list --filesbypkg)'{-s,--state}'[show file states]' \
|
|
'(-s --state -l --list)--filesbypkg[list files with package names]' \
|
|
{-d,--docfiles}'[documentation files only]' \
|
|
{-c,--configfiles}'[configuration files only]' \
|
|
'--dump[show all information]' \
|
|
'--provides[show capabilities provided]' \
|
|
\*--{qf,queryformat}'[specify format for package information]:rpm query format:->tags' \
|
|
-{R,-requires}'[list dependencies]' \
|
|
'--scripts[show (un)install scripts]' \
|
|
{--triggers,--triggerscripts}'[show trigger scripts]' && ret=0
|
|
;;
|
|
setattrs)
|
|
_arguments -s --set{perm,ugids} "${selectopts[@]}" && ret = 0
|
|
;;
|
|
verify)
|
|
_arguments -s \!-{y,V} \
|
|
"${commonopts[@]}" "${selectopts[@]}" "${pathopts[@]}" \
|
|
--no{deps,files,scripts,digest,signature,linkto,md5,size,user,group,mtime,mode,rdev} && ret=0
|
|
;;
|
|
upgrade)
|
|
tmp=( '(--force)--oldpackage' )
|
|
;&
|
|
install)
|
|
_arguments -s \!-{i,U} "$tmp[@]" \
|
|
"${commonopts[@]}" "${pathopts[@]}" \
|
|
'--excludepath:file to exclude:_files -/' \
|
|
'--relocate:relocate:->relocate' \
|
|
'--prefix:package prefix directory:_files -/' \
|
|
'(-h --hash)'{-h,--hash} \
|
|
'(--replacepkgs --replacefiles --oldpackage)--force' \
|
|
'(--force)--'{replacefiles,replacepkgs} \
|
|
--{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,justdb,percent,repackage,test} \
|
|
--np{digest,signature,deps,suggest,order,pre,post,preun,postun,trigger{s,in,un,postun}} \
|
|
'(--nopre --nopost --nopreun --nopostun)--noscripts' \
|
|
'*:pkg file:->package_file' && ret=0
|
|
;;
|
|
uninstall)
|
|
_arguments -s \!-e \
|
|
"${commonopts[@]}" "${pathopts[@]}" \
|
|
--{allmatches,justdb,repackage,test} \
|
|
--no{deps,scripts,preun,postun,trigger{s,un,postun}} \
|
|
'*: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 \
|
|
"${commonopts[@]}" \
|
|
--no{gpg,pgp,md5,signature,digest} \
|
|
'*:package file:->package_file' && ret=0
|
|
;;
|
|
rebuild)
|
|
_arguments -s \
|
|
"${commonopts[@]}" "${pathopts[@]}" \
|
|
'*:source package file:->package_file' && ret=0
|
|
;;
|
|
package-select)
|
|
case "${opt_args[(i)${sopts// /|}]}" in
|
|
-f|--file) _files ;;
|
|
-p|--package) state=package_file ;;
|
|
-g|--group) state=groups ;;
|
|
--fileid|--pkgid) _message -e md5 md5 ;;
|
|
--hdrid) _message -e sha1 sha1 ;;
|
|
--querybynumber) _message -e value number ;;
|
|
--what*) state=capabilities ;;
|
|
--specfile) state=spec_files ;;
|
|
*) state=package ;;
|
|
esac
|
|
;;
|
|
macros)
|
|
local -a macros
|
|
local mfile
|
|
for mfile in {/usr/lib/rpm/{,redhat/}macros,/etc/rpm/macros,~/.rpmmacros}(N); do
|
|
macros+=( ${${(M)${(f)"$(<$mfile)"}:#%[^\{]*}%%[[:blank:]]*} )
|
|
done
|
|
if zstyle -t ":completion:${curcontext}:macros" prefix-hidden; then
|
|
macros=( ${macros#%} )
|
|
_wanted macros expl macro compadd -p '%' -a - macros
|
|
else
|
|
_wanted macros expl macro compadd -a - macros
|
|
fi
|
|
;;
|
|
command)
|
|
compset -q
|
|
_normal
|
|
;;
|
|
target)
|
|
_wanted targets expl 'target platform' compadd \
|
|
${${(M)${(f)"$(_call_programs targets rpm --showrc)"}:#compatible archs*}##*: } && ret=0
|
|
;;
|
|
groups)
|
|
if ( (( ! $+_rpm_groups )) || _cache_invalid rpm-groups ) &&
|
|
! _retrieve_cache rpm-groups
|
|
then
|
|
typeset -gaU _rpm_groups
|
|
_rpm_groups=(
|
|
${(f)"$(_call_program groups rpm -qa --queryformat '%\{group}\\n' 2>/dev/null)"}
|
|
)
|
|
_store_cache RPM-groups _rpm_groups
|
|
fi
|
|
_wanted groups expl 'group' _multi_parts / _rpm_groups && 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 'package' \
|
|
compadd -M 'r:|-=* r:|=*' - "$_rpms[@]" && ret=0
|
|
;;
|
|
spec_files)
|
|
_wanted specfiles expl 'spec file' \
|
|
_files -g '*.spec(-.)' && ret=0
|
|
;;
|
|
package_file)
|
|
_wanted files expl '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 '(#i)*.src.rpm(-.)' && ret=0
|
|
;;
|
|
tags)
|
|
local -a suf
|
|
if compset -P "*%*${${QIPREFIX:+{}:-\{}"; then
|
|
compset -S '(|\\)}*' || suf=( -qS ${${QIPREFIX:+\}}:-\\\}} )
|
|
_wanted tags expl 'rpm tag' compadd -M 'm:{a-z}={A-Z}' "$suf[@]" - \
|
|
"${(L@)${(@f)$(_call_program tags rpm --querytags 2>/dev/null)}#RPMTAG_}" && ret=0
|
|
else
|
|
_message -e formats 'rpm query format'
|
|
fi
|
|
;;
|
|
capabilities)
|
|
_wanted capabilities expl capability compadd \
|
|
${(f)"$(_call_program capabilities rpm -qa --queryformat '%\{requirename}\\n' 2>/dev/null)"}
|
|
;;
|
|
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 "$@"
|