1# dnf completion                                          -*- shell-script -*-
2#
3# This file is part of dnf.
4#
5# Copyright 2013 (C) Elad Alfassa <elad@fedoraproject.org>
6# Copyright 2014-2015 (C) Igor Gnatenko <i.gnatenko.brain@gmail.com>
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21# 02110-1301  USA
22
23__dnf_main_options="
24    -4 -6 -b -c -C -d -e -h -q -R -v -x -y
25    --advisory --advisories
26    --allowerasing --assumeno
27    --assumeyes
28    --best --bugfix
29    --bz
30    --cacheonly --config
31    --color --cve
32    --debuglevel --debugsolver
33    --disableexcludes --disableplugin
34    --disableexcludepkgs --disablerepo
35    --downloadonly --destdir
36    --downloaddir
37    --errorlevel --enableplugin
38    --enablerepo --enhancement
39    --exclude --excludepkgs
40    --help --help-cmd
41    --installroot
42    --newpackage --nodocs
43    --nogpgcheck --noplugins
44    --noautoremove
45    --obsoletes
46    --quiet
47    --randomwait --refresh
48    --releasever --repofrompath
49    --repo --repoid
50    --rpmverbosity
51    --sec-severity --secseverity
52    --security --setopt
53    --skip-broken --showduplicates
54    --verbose --version
55"
56
57__dnf_history_subcmds="info list redo rollback undo userinstalled"
58
59__dnf_secseverity_subcmds='Critical Important Low Moderate'
60
61__dnf_clean_subcmds="all dbcache expire-cache metadata packages"
62
63__dnf_module_subcmds="install remove update enable disable reset provides list info repoquery"
64
65__dnf_repoquery_subcmds="
66    -a -f -i -l -s
67    --all --arch
68    --archlist --available
69    --alldeps
70    --conflicts
71    --deplist --duplicates
72    --exactdeps --extras
73    --envra --enhances
74    --file
75    --groupmember
76    --installed --installonly
77    --info
78    --latest-limit --list
79    --location
80    --nevra  --nvr
81    --provides
82    --qf --queryformat
83    --querytags
84    --recent --requires-pre
85    --recommends --requires
86    --recursive --resolve
87    --source --suggests
88    --supplements --show-duplicates
89    --srpm
90    --tree
91    --upgrades --unneeded
92    --unsatisfied --userinstalled
93    --whatconflicts --whatobsoletes
94    --whatprovides --whatrequires
95    --whatrecommends --whatenhances
96    --whatsuggests --whatsupplements
97"
98
99__dnf_repopkgs_subcmds="
100    check-update
101    info install
102    list
103    move-to
104    remove-or-reinstall remove-or-distro-sync
105    reinstall reinstall-old
106    upgrade upgrade-to
107"
108
109__dnf_python_exec=
110_dnf_set_python_exec()
111{
112    if [[ "$( readlink /usr/bin/dnf )" == "dnf-2" ]]; then
113        __dnf_python_exec="/usr/bin/python2"
114    else
115        if [ -x /usr/libexec/platform-python ]; then
116            __dnf_python_exec="/usr/libexec/platform-python"
117        else
118            __dnf_python_exec="/usr/bin/python3"
119        fi
120    fi
121}
122
123_dnf_commands_helper()
124{
125    local helper_cmd="import sys; from dnf.cli import completion_helper as ch; ch.main(sys.argv[1:])"
126    local helper_opts="-d 0 -q -C --assumeno --nogpgcheck"
127    echo "$( ${__dnf_python_exec} -c "$helper_cmd" "$@" $helper_opts 2>/dev/null </dev/null )"
128}
129
130# decide "path-like?" per initial: dot (./f.rpm, ../b.rpm), / (full path) or ~
131_dnf_is_path()
132{
133    [[ "$1" = \.* ]] || [[ "$1" = \/* ]] || [[ "$1" = \~* ]]
134}
135
136_dnf_show_packages()
137{
138    local args cmd=$1
139    _count_args
140    # do not print packages if command wasnt chosen yet
141    # eg.: dnf inTAB
142    [[ "$args" -eq 1 ]] && return
143
144    # return when "-" follows command
145    # eg.: dnf up -
146    [[ "$cur" == -* ]] && return
147
148    shift
149
150    if ! _dnf_is_path "$cur"; then
151        COMPREPLY+=( $(compgen -W "$( _dnf_commands_helper $cmd "$@" "$cur" )") )
152    fi
153
154    [[ $COMPREPLY ]] && return
155
156    COMPREPLY+=( $(compgen -o default -f -X "!*.@(rpm)" -- "$cur" ) )
157}
158
159_dnf_get_first_command()
160{
161    local cmd i
162
163    for (( i=1; i < ${#COMP_WORDS[@]}; i++ )); do
164        if [[ "$1"  == *${COMP_WORDS[i]}* ]]; then
165            cmd=${COMP_WORDS[i]}
166            break
167        fi
168    done
169
170    echo "$cmd"
171}
172
173_dnf()
174{
175    _dnf_set_python_exec
176
177    local complete_commands complete_options extra_options command cmd_list
178    local cur prev words cword split
179    _init_completion -s || return
180
181    cmd_list="$( _dnf_commands_helper "_cmds" "" )"
182    command="$( _dnf_get_first_command "$cmd_list" )"
183
184    case $prev in
185    --version)
186       return ;;
187
188    -h|--help|--help-cmd)
189        [[ $cword -eq 3 ]] && return ;;
190
191    -d|--debuglevel|-e|--errorlevel)
192        COMPREPLY=( $( compgen -W '0 1 2 3 4 5 6 7 8 9 10' -- "$cur" ) )
193        return
194        ;;
195
196    --installroot)
197        _filedir -d
198        return ;;
199
200    --enablerepo)
201        COMPREPLY=( $(compgen -W "$( _dnf_commands_helper repolist disabled "$cur" )" -- "$cur") )
202        return ;;
203
204    --disablerepo)
205        COMPREPLY=( $(compgen -W "$( _dnf_commands_helper repolist enabled "$cur" )" -- "$cur") )
206        return ;;
207
208    --color)
209        COMPREPLY=( $(compgen -W "yes no true false 0 1" -- "$cur" ) )
210        return ;;
211
212    --destdir|--downloaddir)
213        _filedir -d
214        return ;;
215
216    --sec*severity)
217        COMPREPLY=( $( compgen -W "$__dnf_secseverity_subcmds" -- "$cur" ) )
218        return ;;
219    *)
220        ;;
221    esac
222
223    complete_commands=
224
225    case "$command" in
226    autoremove|autoremove-n*)
227        _dnf_show_packages list installed
228        ;;
229
230    check)
231        extra_options="--all --dependencies --duplicates --obsoleted --provides"
232        complete_commands="all dependencies duplicates obsoleted provides"
233        ;;
234
235    check-update|check-upgrade)
236        _dnf_show_packages list updates
237        ;;
238
239    clean)
240        complete_commands="$__dnf_clean_subcmds"
241        ;;
242
243    dup|dist-upgrade|dsync|distro*sync|distribution-synchronization)
244        _dnf_show_packages list installed
245        ;;
246
247    dg|downgrade)
248        _dnf_show_packages $command
249        ;;
250
251    group|groups|grouperase|groupinfo|groupinstall|grouplist|groupremove|groupupdate)
252        extra_options="--with-optional --hidden --installed --available"
253        ;;
254
255    help)
256        [[ $cword -eq 3 ]] && return 0
257        complete_commands="$cmd_list"
258        ;;
259
260    history)
261        complete_commands="$__dnf_history_subcmds"
262        ;;
263
264    info|list)
265        local subcmd="available installed updates upgrades
266                      --available --installed --updates --upgrades"
267        case "$( _dnf_get_first_command "$subcmd" )" in
268            --installed|installed)
269                _dnf_show_packages list installed ;;
270
271            --available|available)
272                _dnf_show_packages list available ;;
273
274            --updates|--upgrades|updates|upgrades)
275                _dnf_show_packages list updates ;;
276
277            *)
278                _dnf_show_packages list
279            ;;
280
281        esac
282
283        extra_options="--all --available --installed --extras --updates
284                       --upgrades --autoremove --recent"
285        ;;
286
287    info-*|list-*|updateinfo|summary-updateinfo)
288        extra_options="--summary --list --info"
289        complete_commands="summary list info"
290        ;;
291
292    in|install*|localinstall)
293        _dnf_show_packages $command
294        ;;
295
296    mark)
297        _dnf_show_packages list installed
298        ;;
299
300    mc|ref|makecache|refresh)
301        [[ "$prev" == *"timer" ]] && return
302        extra_options="--timer"
303        complete_commands="timer"
304        ;;
305
306    module)
307        extra_options="--enabled --disabled --installed --profile --available --all"
308        complete_commands="$__dnf_module_subcmds"
309        case $prev in
310            info)
311                extra_options="--profile"
312                ;;
313            remove)
314                extra_options="--all"
315                ;;
316            list)
317                extra_options="--all --enabled --disabled --installed"
318                ;;
319            repoquery)
320                extra_options="--available --installed"
321                ;;
322        esac
323        ;;
324
325    provides)
326        ;;
327
328    ri|rei|reinstall)
329        _dnf_show_packages $command
330        ;;
331
332    rm|remove*|erase*)
333        _dnf_show_packages $command
334        extra_options="--oldinstallonly --duplicates --duplicated"
335        ;;
336
337    repoinfo|repolist)
338        extra_options="--all --enabled --disabled"
339        case $prev in
340        enabled|--enabled)
341            complete_commands="$( _dnf_commands_helper $command enabled "$cur" )"
342            ;;
343        disabled|--disabled)
344            complete_commands="$( _dnf_commands_helper $command disabled "$cur" )"
345            ;;
346        all|--all|*)
347            complete_commands="$( _dnf_commands_helper $command all "$cur" )"
348        esac
349        ;;
350
351    repoquery*)
352        extra_options="$__dnf_repoquery_subcmds"
353        ;;
354
355    repo*-pkgs|repo*-packages)
356        complete_commands="$__dnf_repopkgs_subcmds"
357        ;;
358
359    se|search)
360        [[ "$prev" == *"all" ]] && return
361        extra_options="--all"
362        complete_commands="all"
363        ;;
364
365    sh|shell) ;;
366
367    swap) ;;
368
369    um|u-m|upgrade|upgrade-n*)
370        _dnf_show_packages $command
371        ;;
372
373    up|up-min|update|update-n*)
374        _dnf_show_packages $command
375        ;;
376
377    whatprovides) ;;
378
379    *)
380        complete_commands="$cmd_list"
381        ;;
382    esac
383
384    $split && return
385
386    case $cur in
387    -*)
388        complete_options="$__dnf_main_options $extra_options"
389        COMPREPLY=( $(compgen -W "$complete_options" -- "$cur" ))
390        ;;
391    *)
392        if [[ $cur == $command ]]; then
393            complete_commands="$cmd_list"
394        fi
395
396        if [[ "$complete_commands" ]]; then
397            COMPREPLY=( $(compgen -W "$complete_commands" -- "$cur" ))
398        fi
399    esac
400
401    [[ $COMPREPLY == *= ]] && compopt -o nospace
402    return 0
403}
404
405complete -F _dnf dnf dnf-2 dnf-3
406