#compdef dnf # Main dispatcher _dnf() { _arguments -s \ '(- *)'{-h,--help}'[show the help message]' \ '(-t --tolerant)'{-t,--tolerant}'[be tolerant of errors]' \ '(-C --cacheonly)'{-C,--cacheonly}'[run entirely from cache]' \ '(-c --config)'{-c,--config=}'[config file location]:config file:_files' \ '(-R --randomwait)'{-R,--randomwait=}'[maximum command wait time (in minutes)]:max wait time' \ '(-d --debuglevel)'{-d,--debuglevel=}'[debug level (0-10)]:debug level' \ '(-e --errorlevel)'{-e,--errorlevel=}'[error level (0-10)]:error level' \ '(-y --assumeyes)'{-y,--assumeyes}'[answer yes for all questions]' \ '--installroot=[set install root]:install root:_files -/' \ '*--enablerepo=[enable or or more repositories]:repos to enable:_dnf_disabled_repos_list' \ '*--disablerepo=[disable one or more repositories]:disable repos:_dnf_enabled_repos_list' \ {*-x,*--exclude=}'[exclude package(s) by name or glob]:exclude packages' \ '--version[show dnf version]' \ '--obsoletes[enable obsoletes processing during updates]' \ '--nogpgcheck[disable gpg signature checking]' \ '--noplugins[disable dnf plugins]' \ '--disablepresto[disable Presto plugin and don''''t download any deltarpms]' \ '*::dnf command:_dnf_command' } (( $+functions[_dnf_command] )) || _dnf_command() { local -a _dnf_cmds _dnf_cmds=( "install:install the latest version of a package or group of packages" "erase:remove an installed package (with its dependencies)" "remove:remove an installed package (with its dependencies)" "clean:clean local dnf cache" "check-update:check if any updates are available" "info:get description of available packages" "list:is used to list various information about packages" "groupinfo:get info on package groups" "groupinstall:install a package group or groups" "groupremove:remove a package group or groups" "grouplist:list package groups" "groupupdate:update a package group or groups" "localinstall:install packages with local rpm files" "localupdate:update packages with local rpm files" "makecache:makes a local dnf cache" "provides:find out which package provides some feature or file" "whatprovides:find out which package provides some feature or file" "search:find any packages matching pattern" "shell:enter the 'dnf shell'" "update:update one or more packages" "upgrade:upgrade one or more packages" ) if (( CURRENT == 1 )); then _describe -t commands 'dnf command' _dnf_cmds || compadd "$@" else local curcontext="$curcontext" cmd="${${_dnf_cmds[(r)$words[1]:*]%%:*}}" # Deal with any aliases case $cmd in remove) cmd="erase";; whatprovides) cmd="provides";; upgrade) cmd="update";; esac if (( $#cmd )); then curcontext="${curcontext%:*:*}:dnf-${cmd}:" local update_policy zstyle -s ":completion:${curcontext}:" cache-policy update_policy if [[ -z "$update_policy" ]]; then zstyle ":completion:${curcontext}:" cache-policy _dnf_caching_policy fi _call_function ret _dnf_$cmd || _message 'no more arguments' else _message "unknown dnf command: $words[1]" fi return ret fi } # Fills the all pkg cache _dnf_all_pkgs() { if ( [[ ${+_all_pkgs} -eq 0 ]] || _cache_invalid ALL ) && ! _retrieve_cache ALL; then _all_pkgs=( $(dnf -C list all | sed 's/\s.*//' | grep '\.' 2>/dev/null) ) _store_cache ALL _all_pkgs fi } # Fills the installed pkg cache _dnf_installed_pkgs() { if ( [[ ${+_installed_pkgs} -eq 0 ]] || _cache_invalid INSTALLED ) && ! _retrieve_cache INSTALLED; then _installed_pkgs=( $(dnf -C list installed | sed 's/\s.*//' | grep '\.' 2>/dev/null) ) _store_cache INSTALLED _installed_pkgs fi } # Fills the available pkg cache _dnf_available_pkgs() { if ( [[ ${+_available_pkgs} -eq 0 ]] || _cache_invalid AVAILABLE ) && ! _retrieve_cache AVAILABLE; then _available_pkgs=( $(dnf -C list available | sed 's/\s.*//' | grep '\.' 2>/dev/null) ) _store_cache AVAILABLE _available_pkgs fi } # Fills the upgrade pkg cache _dnf_upgrade_pkgs() { if ( [[ ${+_upgrade_pkgs} -eq 0 ]] || _cache_invalid UPGRADE ) && ! _retrieve_cache UPGRADE; then _upgrade_pkgs=( $(dnf -C list upgrade | sed 's/\s.*//' | grep '\.' 2>/dev/null) ) _store_cache UPGRADE _upgrade_pkgs fi } # Gets the list of defined repos __dnf_repos() { local trepo local -a tarray tarray=( $(egrep -h '(^\[.*\]|^enabled.*=)' /etc/dnf.repos.d/*.repo /etc/dnf.conf 2>/dev/null | sed -e 's/ //g' | sed -e 's/\[//g' | sed -e 's/\].*$//g' 2>/dev/null) ) local -i eindex=0 local -i dindex=0 for line in $tarray; do if [[ "$line" = "enabled=1" ]]; then enabled_dnf_repos+=($trepo) elif [[ "$line" = "enabled=0" ]]; then disabled_dnf_repos+=($trepo) elif [[ "$line" != "main" ]]; then trepo=$line fi done } (( $+functions[_dnf_disabled_repos_list] )) || _dnf_disabled_repos_list() { local -a enabled_dnf_repos disabled_dnf_repos __dnf_repos _sequence compadd "$@" - -a disabled_dnf_repos } (( $+functions[_dnf_enabled_repos_list] )) || _dnf_enabled_repos_list() { local -a enabled_dnf_repos disabled_dnf_repos __dnf_repos _sequence compadd "$@" - -a enabled_dnf_repos } # Completion function for erase|remove (( $+functions[_dnf_erase] )) || _dnf_erase() { _dnf_installed_pkgs compadd "$@" -a -- _installed_pkgs } # Completion function for install (( $+functions[_dnf_install] )) || _dnf_install() { if ! [[ $PREFIX == */* ]]; then _dnf_available_pkgs fi local ret=1 _tags files packages while _tags; do if _requested files; then compadd "$@" -a -- _available_pkgs fi if _requested packages; then _call_function - _dnf_localinstall fi (( ret )) || break done return ret } # Completion function for localinstall (( $+functions[_dnf_localinstall] )) || _dnf_localinstall() { _files -/ -g '(#i)*.rpm(-.)' } # Completion function for localupdate (( $+functions[_dnf_localupdate] )) || _dnf_localupdate() { _files -/ -g '(#i)*.rpm(-.)' } # Completion function for update/upgrade (( $+functions[_dnf_update] )) || _dnf_update() { _dnf_upgrade_pkgs compadd "$@" -a -- _upgrade_pkgs } _dnf_all() { _dnf_all_pkgs compadd "$@" -a -- _all_pkgs } _dnf_list_or_info() { local -a listlist listlist=( "all:all packages in repositories" "available:packages available in repositories" "updates:packages with updates available" "installed:installed packages" "extras:packages installed that are not available in any dnf repository" "obsoletes:packages installed that are obsoleted" "recent:packages recently added to repositories" ) if (( CURRENT == 2 )); then _describe -t dnf-list-subcmds "dnf info/list sub-commands" listlist || _dnf_all else local subcmd subcmd="${${listlist[(r)$words[2]:*]%%:*}}" # offer packages selected by the subcommand case $subcmd in all) _dnf_all;; installed) _dnf_erase;; available) _dnf_install;; updates) _dnf_update;; esac fi } # Completion function for list (( $+functions[_dnf_list] )) || _dnf_list() { _dnf_list_or_info } # Completion function for info (( $+functions[_dnf_info] )) || _dnf_info() { _dnf_list_or_info } # Completion function for provides|whatprovides (( $+functions[_dnf_provides] )) || _dnf_provides() { _files } # Completion function for clean (( $+functions[_dnf_clean] )) || _dnf_clean() { local -a cleanlist cleanlist=( "all:all cache" "cache:all cache" "dbcache:DB cache" "headers:cache headers" "packages:cache packages" "metadata:cache meta-data" ) if (( CURRENT == 2 )); then _describe -t dnf-clean-subcmds "dnf clean sub-commands" cleanlist fi } _dnf_caching_policy() { local _dnfrepomds local -a oldp # rebuild if cache is more than a week old oldp=( "$1"(mw+1) ) (( $#oldp )) && return 0 _dnfrepomds=( /var/cache/dnf/**/repomd.xml ) if (( $#_dnfrepomds )); then for repo in $_dnfrepomds; do [[ "$repo" -nt "$1" ]] && return 0 done fi return 1 } _dnf "$@"