1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-31 18:10:56 +01:00
zsh/Completion/Redhat/Command/_dnf
Jun-ichi Takimoto b70b241cc5 53238 (+53239 Mikael): support dnf5
some options etc for dnf4 are also updated
2024-11-21 12:26:51 +09:00

590 lines
24 KiB
Text

#compdef dnf dnf-2 dnf-3 dnf4
# based on dnf-4.21.1
# avoid 'dnf --version' since it's rather slow for dnf4
if [[ $service = dnf && $commands[dnf]:P = */dnf5 ]]; then
_dnf5 "$@" && return 0
return 1
fi
_dnf_helper() {
# Get the pathname of the python executable from the 1st line of dnf-2/dnf-3.
# Probably /usr/bin/python{2,3} or /usr/libexec/platform-python.
local shebang
read -u0 shebang < $(readlink -f /usr/bin/dnf)
local python_exec=${${shebang##\#! #}%% *}
local -a helper_script=(
'import sys'
'from dnf.cli.completion_helper import main'
'main(sys.argv[1:])'
)
$python_exec -c ${(j.;.)helper_script} "$@" "$PREFIX" \
-d 0 -q -C --assumeno --nogpgcheck 2>/dev/null </dev/null
}
_dnf_query_db() {
# $1: table name in the database ('available' or 'installed')
sqlite3 -batch -init /dev/null "$cache_file" \
"select pkg from $1 WHERE pkg LIKE '$PREFIX%$SUFFIX'"
}
_dnf_repositories() {
# required option: -T (all|disabled|enabled)
local selected expl
zparseopts -D -E - T:=selected
selected=$selected[2]
_wanted $selected-repositories expl "$selected repository" \
compadd "$@" - $(_dnf_helper repolist --$selected)
}
_dnf_packages() {
# required option: -T (all|available|installed|upgradable)
local selected pkgs expl
zparseopts -D -E - T:=selected
selected=$selected[2]
if [[ $selected = upgradable ]]; then
pkgs=( $(_dnf_helper upgrade) )
elif [[ -r $cache_file ]]; then
local table=$selected
# 'available' table contains both 'available' and 'installed' packages
[[ $selected = all ]] && table=available
pkgs=( $(_dnf_query_db $table) )
if [[ $selected = available ]]; then
local inst=( $(_dnf_query_db installed) )
pkgs=( ${pkgs:|inst} ) # remove installed packages
fi
else
pkgs=( $(_dnf_helper list --$selected) )
fi
_wanted $selected-packages expl "$selected package" compadd "$@" -a pkgs
}
_dnf_rpm_files() {
local expl
_wanted rpm-files expl 'rpm file' _files -g '(#i)*.rpm(-.)'
}
_dnf_packages_or_rpms() {
if [[ "$words[CURRENT]" = (*/*|\~*) ]]; then # if looks like a path name
_dnf_rpm_files
else
_dnf_packages "$@"
fi
}
_dnf_groups() {
# optional option: -T (available|installed)
local selected line groups section=none
zparseopts -D -E - T:=selected
selected=$selected[2]
[[ -z $selected ]] && selected=all
# XXX hidden groups are not included.
# --installed and --available can't be specified with --hidden
for line in ${(f)"$(_call_program package-groups
$service group list --$selected -qCv 2>/dev/null)"}; do
# a line for each group is of the following form:
# ' description of the group (group-id)'
if [[ $line = \ ##(#b)(*)\(([-_[:alnum:]]#)\) ]]; then
groups+=( "${match[2]}:${match[1]}" )
fi
done
_describe -t groups "$selected group" groups
}
_dnf_repoquery() {
local _h=''
# 'dnf deplist' is an alias for 'dnf repoquery --deplist'
[[ $words[1] = deplist ]] && _h='!'
local -a opts=( '(- *)--querytags[list tags recognized by --queryformat]' )
# Select options
opts+=(
'(-a --all)'{-a,--all}'[query all packages]'
'--arch=[limit results to specified architectures]:list of archs: '
'--available[limit results to available packages]'
'--disable-modular-filtering[include packages of inactive module streams]'
'(-f --file)'{-f+,--file=}'[limit results to packages which own specified file]:file:_files'
'--latest-limit=[limit results to latest packages of specified number]:number: '
'--recent[limit results to recently edited packages]'
'(--exactdeps)--alldeps[with --what{depends,requires}, also check non-explicit dependencies]'
'(--alldeps)--exactdeps[with --what{depends,requires}, check only explicit dependencies]'
'*--repo=[limit result to packages from the specified repo]: : _sequence _dnf_repositories -T all'
'--srpm[operate on the corresponding source RPM]'
'--whatdepends=[limit result to packages that require, enhance, recommend, suggest or supplement specified capability]:capability: '
)
for v in conflict enhance obsolete provide recommend require suggest supplement; do
opts+=( "--what${v}s=[limit result to packages that $v specified capability]:capability: " )
done
# Query options
opts+=(
'--location[show a location where package could be downloaded from]'
'--tree[display recursive tree of packages]'
$_h'--deplist[display list of all direct dependencies and their providers]'
'--recursive[query packages recursively]'
'--resolve[resolve capabilities to originating package(s)]'
)
# mutually exclusive Select options
opts+=(
+ '(pkg_filter)'
'--duplicates[limit results to installed duplicate packages]'
'--installonly[limit results to installed installonly packages]'
'--unsatisfied[limit results to installed packages with unsatisfied dependencies]'
+ '(list_group)'
'--installed[limit results to installed packages]'
'--extras[limit results to extra packages (not in any repos)]'
'--upgrades[limit results to upgrades for installed packages]'
'--unneeded[limit results to packages which are no longer needed]'
'--userinstalled[limit results to packages installed by user]'
)
# mutually exclusive Query options
opts+=(
+ '(output_format)'
{-i,--info}'[show detailed info about the package]'
{-l,--list}'[show list of files in the packages]'
{-s,--source}'[show source RPM name]'
'--changelogs[print package changelogs]'
'--nvr[show found packages in name-version-release format]'
'--nevra[show found packages in name-epoch:version-release.architecture format]'
'--envra[show found packages in epoch:name-version-release.architecture format]'
{--qf=,--queryformat=}'[specify custom output format]:format: '
'--groupmember[display groups in which the package belongs]'
+ '(pkg_attr)'
'--conflicts[display capabilities that the package conflicts with]'
'--depends[display capabilities that the package depends on, enhances, recommends, suggests or supplements]'
'--enhances[display capabilities that the package enhance]'
'--provides[display capabilities that the package provides]'
'--recommends[display capabilities that the package recommends]'
'--requires[display capabilities that the package depends on]'
'--requires-pre[display capabilities that the package depends on for running %pre script]'
'--suggests[display capabilities that the package suggests]'
'--supplements[display capabilities that the package supplements]'
'--obsoletes[display capabilities that the package obsoletes]'
)
_arguments : '*: : _dnf_packages -T all' $opts
}
_dnf_repository_packages() {
if (( CURRENT == 2 )); then
_dnf_repositories -T all
elif (( CURRENT == 3 )); then
local -a subcmds=(
'check-update:check if updates are available in the repository'
'info:list description of packages in the repository'
'install:install all packages in the repository'
'list:list packages in the repository'
'move-to:reinstall all packages that are available in the repository'
'reinstall:run reinstall-old, or move-to if it fails'
'reinstall-old:reinstall all packages that were installed from the repository'
'remove:remove all packages installed from the repository'
'remove-or-distro-sync:sync packages with other repo if available there, or remove otherwise'
'remove-or-reinstall:reinstall packages if available in other repo, or remove otherwise'
'upgrade:update all packages in the repository'
)
_describe -t subcommands 'subcommand' subcmds
elif [[ $words[3] = (info|list) ]]; then
if (( CURRENT == 4 )); then
_wanted options expl "option" compadd - --all --installed --available \
--extras --obsoletes --recent --upgrades
else
_dnf_packages -T all
fi
elif [[ $words[3] = install ]]; then
_dnf_packages -T available
elif [[ $words[3] = upgrade* ]]; then
_dnf_packages -T upgradable
else
_dnf_packages -T installed
fi
}
_dnf4() {
local cache_file="/var/cache/dnf/packages.db"
local -a opts=(
'(-6)-4[resolve to IPv4 addresses only]'
'(-4)-6[resolve to IPv6 addresses only]'
'*--advisory=[include packages for specified advisory]:advisory: '
'--allowerasing[allow erasing installed packages to resolve dependencies]'
'(-y --assumeyes)--assumeno[answer no for all questions]'
'(-b --best)'{-b,--best}'[try the best available package version]'
'--bugfix[include bugfix relevant packages]'
'*'{--bz=,--bzs=}'[include packages needed to fix the specified Bugzilla]:BZ ID: '
'(-C --cacheonly)'{-C,--cacheonly}"[run entirely from system cache, don't update cache]"
'--color=[control whether color is used]:when:(always never auto)'
'--comment=[add comment to transaction history]:comment: '
'(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files'
'*'{--cve=,--cves=}'[include packages needed to fix the specified CVE]:CVE ID: '
'(-d --debuglevel)'{-d+,--debuglevel=}'[specify debugging output level]:level (0-10): '
'--debugsolver[dump detailed solving results in file ./debugdata]'
'*--disableexcludes=[disable config file excludes]: : _alternative "sections\:section\:(all main)" "repositories\:repository\:_dnf_repositories -T all"'
'(--disable --set-disabled)'{--disable,--set-disabled}'[disable repos with config-manager command]'
'*--disableplugin=[disable specified plugins]:list of plugin names: '
'(--repo)*--disablerepo=[disable specified repos]: : _sequence _dnf_repositories -T enabled'
'(--downloaddir --destdir)'{--downloaddir=,--destdir=}'[redirect downloaded packages to the specified dir]:directory:_files -/'
'--downloadonly[only download the resolved packages]'
'(-e --errorlevel)'{-e+,--errorlevel=}'[specify error output level]:level (0-10): '
'(--enable --set-enabled)'{--enable,--set-enabled}'[enable repos with config-manager command]'
'--enableplugin=[enable specified plugins]:list of plugin names: '
'*--enablerepo=[enable additional repos]: : _sequence _dnf_repositories -T disabled'
'--enhancement[include enhancement relevant packages]'
'*'{-x+,--exclude=}'[exclude specified packages]: : _sequence _dnf_packages -T all'
'--forcearch=[force the use of the specified arch]:arch: '
'(-)'{-h,--help}'[show the help message]'
'--installroot=[set install root]:directory:_files -/ -g "/*"'
'--newpackage[include newpackage relevant packages]'
'--noautoremove[disable removal of dependencies that are no longer used]'
'--nobest[do not limit transactions to best candidates]'
'--nodocs[do not install documentation]'
'--nogpgcheck[skip checking GPG signatures on packages]'
'--noplugins[disable all plugins]'
'--obsoletes[enable obsoletes processing logic]'
'(-q --quiet)'{-q,--quiet}'[show just the relevant content]'
'(-R --randomwait)'{-R+,--randomwait=}'[maximum command wait time]:max wait time (minutes): '
'--refresh[set metadata as expired before running the command]'
'--releasever=[configure DNF for another release]:release: '
'*--repofrompath=[specify additional repos]:repository_label,path_or_url: '
'(--disablerepo)*'{--repo=,--repoid=}'[enable just the specified repo]: : _sequence _dnf_repositories -T all'
'--rpmverbosity=[set RPM debug scriptlet output level]:debug level:(critical emergency error warn info debug)'
'*--sec-severity=[include security relevant packages matching specified severity]:severity:(Critical Important Moderate Low)'
'--security[include security relevant packages]'
'*--setopt=[override config option]:repoid.option=value: '
'--skip-broken[resolve depsolve problems by skipping packages]'
'--showduplicates[show duplicate packages in repos]'
'(-v --verbose)'{-v,--verbose}'[set verbose, show debug messages]'
'(- *)--version[show dnf version]'
'(-y --assumeyes --assumeno)'{-y,--assumeyes}'[answer yes for all questions]'
)
_arguments -s : $opts '*::dnf command:_dnf_command'
}
_dnf_command() {
local -a dnf_cmds=(
'alias:define and manage aliases'
"autoremove:automatically remove no longer required packages"
'check:report problems in local packagedb if any'
"check-update:check for available package upgrades"
"clean:remove cached data"
'deplist:alias for "repoquery --deplist"'
"distro-sync:synchronize installed packages to the latest available versions"
"downgrade:downgrade a package"
"group:display, or use, the groups information"
"help:display a helpful usage message"
"history:display, or use, the transaction history"
"info:display details about a package or group of packages"
"install:install a package or packages on your system"
"list:list a package or groups of packages"
"makecache:generate the metadata cache"
"mark:mark or unmark installed packages as installed by user"
'module:interact with modules'
"provides:find what package provides the given value"
"reinstall:reinstall a package"
"remove:remove a package or packages from your system"
"repolist:display the configured software repositories"
'repoquery:search repos for packages and display info about them'
"repository-packages:run commands on top of all packages in given repository"
"search:search package details for the given string"
'shell:open an interactive shell'
'swap:replace a package by another'
"updateinfo:display advisories about packages"
"upgrade:upgrade a package or packages on your system"
'upgrade-minimal:upgrade only bugfix, enhancement or security fix'
)
if (( CURRENT == 1 )); then
_describe -t dnf-commands 'dnf command' dnf_cmds
else
local cur=$words[CURRENT] cmd=$words[1] tmp expl ret=1
# Deal with aliases (not comprehensive)
case $cmd in
check-updgrade) cmd=check-update;;
distrosync|dsync) cmd=distro-sync;;
dg) cmd=downgrade;;
dsync) cmd=distro-sync;;
erase|rm) cmd=remove;;
groups|grp) cmd=group;;
hist) cmd=history;;
in) cmd=install;;
if) cmd=info;;
ls) cmd=list;;
mc) cmd=makecache;;
prov|whatprovides|wp) cmd=provides;;
rei) cmd=reinstall;;
repoinfo) cmd=repolist;;
rq) cmd=repoquery;;
se) cmd=search;;
sh) cmd=shell;;
update|up) cmd=upgrade;;
update-minimal|up-min) cmd=upgrade-minimal;;
upif) cmd=updateinfo;;
esac
local curcontext="${curcontext%:*:*}:dnf-${cmd}:"
case $cmd in
alias)
if (( CURRENT == 2 )); then
_wanted subcommands expl 'subcommand' \
compadd - list add delete && ret=0
elif [[ $words[2] = add ]]; then
_message "name='value'" && ret=0
else
_message "alias name" && ret=0
fi
;;
autoremove|downgrade|reinstall)
_dnf_packages_or_rpms -T installed && ret=0
;;
check)
tmp=(
'--all:show all problems (default)'
'--dependencies:show dependency problems'
'--duplicates:show duplicate problems'
'--obsoleted:show obsoleted packages'
'--provides:show problems with provides'
)
_describe -t options 'option' tmp && ret=0
;;
check-update)
_arguments : \
'--changelogs[also print changelog delta of packages]' \
'*: :_dnf_packages -T installed' && ret=0
;;
clean)
tmp=(
'dbcache:remove cache files generated from the repository metadata'
'expire-cache:mark the repository metadata expired'
'metadata:remove the repository metadata'
'packages:remove any cached packages'
'all:clean all'
)
_describe -t targets 'clean target' tmp && ret=0
;;
distro-sync)
_dnf_packages -T installed && ret=0
;;
group)
if (( CURRENT == 2 )); then
tmp=(
"summary:display groups overview"
"info:display package lists of a group"
"install:install packages from a group"
"list:list all matching groups"
"remove:remove packages in a group not used by other groups"
"upgrade:upgrade the group and its packages"
"mark:mark a group for installation or removal"
)
_describe -t subcommands 'subcommand' tmp && ret=0
else
case $words[2] in
summary)
_arguments : '--hidden' '2: :_dnf_groups' && ret=0
;;
info)
_dnf_groups && ret=0
;;
install)
_arguments : '--with-optional[also include optional packages]' \
'*: :_dnf_groups -T available' && ret=0
;;
list)
_arguments : \
'(--installed)--available[show only available groups]' \
'(--available)--installed[show only installed groups]' \
'--hidden[show also hidden groups]' \
{--ids,-v}'[show also ID of groups]' \
'*: :_dnf_groups' && ret=0
;;
remove|upgrade)
_dnf_groups -T installed && ret=0
;;
mark)
if (( CURRENT == 3 )); then
_wanted subcommands expl 'subcommand' \
compadd - install remove && ret=0
else
_dnf_groups && ret=0
fi
;;
esac
fi
;;
help)
if (( CURRENT == 2 )); then
_wanted commands expl 'dnf command or alias' \
compadd - $(_dnf_helper '_cmds') && ret=0
fi
;;
history)
if (( CURRENT == 2 )); then
tmp=(
"list:list transactions"
"info:describe the given transactions"
"redo:repeat the specified transaction"
"replay:replay transaction stored in the specified file"
"rollback:undo all since the given transaction"
"store:store the specified transaction in file"
"undo:undo transactions"
"userinstalled:list all packages installed by users"
)
_describe -t subcommands 'subcommand' tmp && ret=0
else
case $words[2] in
list)
_arguments : '--reverse[output history in reverse order]' \
'*:transaction ID or ID..ID: ' && ret=0 ;;
info)
_message 'transaction ID or ID..ID' && ret=0 ;;
redo|rollback|undo)
_message 'transaction or package' && ret=0 ;;
replay)
_arguments : \
"--ignore-installed[don't check for installed packages being in the same state as recorded in transaction]" \
"--ignore-extras[don't check for extra packages pulled into the transaction on the target system]" \
'--skip-unavailable[skip packages that are in transaction but not in target system]' \
'2:transaction file:_files' && ret=0 ;;
store)
_arguments : {-o+,--output=}'[store in specified file]: :_files' \
'2:transaction: ' && ret=0 ;;
esac
fi
;;
info|list)
if (( CURRENT == 2 )); then
if [[ $cur = -* ]]; then
tmp=( --all --available --installed --extras
--obsoletes --upgrades --autoremove --recent )
_wanted options expl 'option' compadd -a tmp && ret=0
else
_dnf_packages -T all && ret=0
fi
elif [[ $words[2] == --(all|recent) ]]; then
_dnf_packages -T all && ret=0
elif [[ $words[2] == --available ]]; then
_dnf_packages -T available && ret=0
elif [[ $words[2] == --upgrades ]]; then
_dnf_packages -T upgradable && ret=0
else
_dnf_packages -T installed && ret=0
fi
;;
install)
_dnf_packages_or_rpms -T available && ret=0
;;
makecache)
if (( CURRENT == 2 )); then
_describe -t options 'option' \
'(--timer:"be more resource-aware")' && ret=0
fi
;;
mark)
if (( CURRENT == 2 )); then
_wanted subcommands expl 'mark as' \
compadd - install remove group && ret=0
else
_dnf_packages -T installed && ret=0
fi
;;
module)
if (( CURRENT == 2 )); then
tmp=(
'install:install a module profile including its packages'
'update:update packages associated with an active module stream'
'switch-to:switch to a module stream and change versions of installed packages'
'remove:remove installed module profiles and their packages'
'enable:enable a module stream'
'disable:disable a module with all its streams'
'reset:reset module state, no longer enabled or disabled'
'provides:list modular packages, with modules they belong to'
'list:list all (or selected) module streams, profiles and states'
'info:print detailed information about a module'
'repoquery:list packages belonging to a module'
)
_describe -t subcommands 'subcommand' tmp && ret=0
elif (( CURRENT == 3 )) && [[ $cur = -* ]]; then
if [[ $words[2] = remove ]]; then
tmp=( --all )
elif [[ $words[2] = list ]]; then
tmp=( --all --enabled --disabled --installed )
elif [[ $words[2] = info ]]; then
tmp=( --profile )
elif [[ $words[2] = repoquery ]]; then
tmp=( --available --installed )
fi
_wanted options expl 'option' compadd -a tmp && ret=0
else
# TODO: complete module name or spec
if [[ $words[2] = provides ]]; then
_dnf_packages -T all && ret=0
elif [[ $words[2] = (disable|reset|list) ]]; then
_message 'module name' && ret=0
else
_message 'module spec' && ret=0
fi
fi
;;
provides)
_files && ret=0
;;
remove)
if (( CURRENT == 2 )) && [[ $cur = -* ]]; then
_wanted options expl 'option' \
compadd - --duplicates --oldinstallonly && ret=0
elif [[ $words[2] != -* ]]; then
_dnf_packages_or_rpms -T installed && ret=0
fi
;;
repolist)
if (( CURRENT == 2 )); then
_wanted options expl 'option' \
compadd - --enabled --disabled --all && ret=0
fi
;;
repoquery|deplist)
_dnf_repoquery && ret=0
;;
repository-packages)
_dnf_repository_packages && ret=0
;;
search)
if [[ $cur = -* ]]; then
_wanted options expl 'option' compadd - --all && ret=0
else
_message 'keywords' && ret=0
fi
;;
shell)
if (( CURRENT == 2 )); then
_wanted script-files expl 'script file' _files && ret=0
fi
;;
swap)
case $CURRENT in
2) _dnf_packages -T installed && ret=0 ;;
3) _dnf_packages -T available && ret=0 ;;
esac
;;
updateinfo)
tmp=(
'--with-cve[print only advisories referencing CVE]'
'--with-bz[print only advisories referencing bugzilla]'
+ '(output-type)'
'--summary[display just counts of advisories of each type]'
'--list[display list of advisories]'
'--info[display detailed information of advisories]'
+ '(availability)'
'-all[include advisories about any versions of installed packages]'
'--available[limit to advisories about newer versions of installed packages]'
'--installed[limit to advisories about equal or older versions of installed packages]'
'--updates[limit to advisories about newer and available versions of installed packages]'
)
_arguments '*: : _dnf_packages -T installed' $tmp && ret=0
;;
upgrade)
_dnf_packages_or_rpms -T upgradable && ret=0
;;
upgrade-minimal)
_dnf_packages -T upgradable && ret=0
;;
esac
return ret
fi
}
_dnf4 "$@"