diff --git a/etc/bash_completion.d/tdnf-completion.bash b/etc/bash_completion.d/tdnf-completion.bash index 4e480404..21b1edce 100644 --- a/etc/bash_completion.d/tdnf-completion.bash +++ b/etc/bash_completion.d/tdnf-completion.bash @@ -1,5 +1,4 @@ -_tdnf__process_if_prev_is_option() -{ +_tdnf__process_if_prev_is_option() { local prev opts prev="${COMP_WORDS[COMP_CWORD-1]}" case $prev in @@ -12,26 +11,26 @@ _tdnf__process_if_prev_is_option() COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 ;; - --downloaddir) + --downloaddir|--download-path) COMPREPLY=( $(compgen -d -- $cur) ) return 0 ;; --enablerepo) - opts=`tdnf repolist disabled | awk '{if (NR > 1) print $1}'` + opts=$(tdnf repolist disabled 2>/dev/null | awk '{if (NR > 1) print $1}') COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 ;; --disablerepo) - opts=`tdnf repolist enabled | awk '{if (NR > 1) print $1}'` + opts=$(tdnf repolist enabled 2>/dev/null | awk '{if (NR > 1) print $1}') COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 ;; - --installroot) + -i|--installroot) COMPREPLY=( $(compgen -d -- $cur) ) return 0 ;; - --repo|repoid) - opts=`tdnf repolist all | awk '{if (NR > 1) print $1}'` + --repo|--repoid) + opts=$(tdnf repolist all 2>/dev/null | awk '{if (NR > 1) print $1}') COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 ;; @@ -40,12 +39,68 @@ _tdnf__process_if_prev_is_option() COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 ;; + --forcearch) + opts="x86_64 aarch64" + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + return 0 + ;; + --releasever) + COMPREPLY=( $(compgen -W "4.0 5.0" -- $cur) ) + return 0 + ;; + --sec-severity) + opts="Critical Important Moderate Low" + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + return 0 + ;; + --exclude|--disableplugin|--enableplugin) + COMPREPLY=( $(compgen -W "" -- $cur) ) + return 0 + ;; + --repofrompath|--repofromdir) + COMPREPLY=( $(compgen -d -- $cur) ) + return 0 + ;; + --file) + COMPREPLY=( $(compgen -f -- $cur) ) + return 0 + ;; + --arch) + opts="x86_64 aarch64 noarch" + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + return 0 + ;; + --metadata-path) + COMPREPLY=( $(compgen -d -- $cur) ) + return 0 + ;; + --whatdepends|--whatrequires|--whatprovides|--whatobsoletes|--whatconflicts|--whatrecommends|--whatsuggests|--whatsupplements|--whatenhances) + opts=$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1) + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + return 0 + ;; + --qf) + COMPREPLY=( $(compgen -W "" -- $cur) ) + return 0 + ;; + --to|--from) + opts=$(tdnf history list | awk '{if (NR > 1) print $1}') + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + return 0 + ;; + --setopt) + COMPREPLY=( $(compgen -W "" -- $cur) ) + return 0 + ;; + --rpmdefine) + COMPREPLY=( $(compgen -W "" -- $cur) ) + return 0 + ;; esac return 1 } -_tdnf__process_if_cmd() -{ +_tdnf__process_if_cmd() { local cmd opts cmd="${COMP_WORDS[$1]}" [[ " $__cmds " =~ " $cmd " ]] || return 1 @@ -56,44 +111,110 @@ _tdnf__process_if_cmd() return 0 ;; clean) - [ $1 -eq $(($COMP_CWORD - 1)) ] && + if [ $1 -eq $(($COMP_CWORD - 1)) ]; then opts="packages metadata dbcache plugins expire-cache all" + else + return 0 + fi ;; downgrade) - opts=$(tdnf list --downgrades | awk '{print $1}' | cut -d'.' -f1) + opts=$(tdnf list --downgrades 2>/dev/null | awk '{print $1}' | cut -d'.' -f1) ;; autoerase|autoremove|erase|reinstall|remove) - opts=$(tdnf list --installed | awk '{print $1}' | cut -d'.' -f1) + opts=$(tdnf list --installed 2>/dev/null | awk '{print $1}' | cut -d'.' -f1) ;; history) - [ $1 -eq $(($COMP_CWORD - 1)) ] && + if [ $1 -eq $(($COMP_CWORD - 1)) ]; then opts="init update list rollback undo redo" + else + return 0 + fi + ;; + count) + return 0 + ;; + distro-sync) + opts=$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1) ;; install) - opts="$(tdnf list --available | awk '{print $1}' | cut -d'.' -f1) $(compgen -d -G '*.rpm')" + opts=$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1) ;; mark) - [ $1 -eq $(($COMP_CWORD - 1)) ] && + if [ $1 -eq $(($COMP_CWORD - 1)) ]; then opts="install remove" + else + return 0 + fi ;; repolist) - [ $1 -eq $(($COMP_CWORD - 1)) ] && + if [ $1 -eq $(($COMP_CWORD - 1)) ]; then opts="all enabled disabled" + else + return 0 + fi + ;; + repoquery) + # After repoquery, offer both repoquery-specific options and package names + local repoquery_opts="--available --duplicates --extras --file --installed --userinstalled --upgrades --whatconflicts --whatdepends --whatenhances --whatobsoletes --whatprovides --whatrecommends --whatrequires --whatsuggests --whatsupplements --changelogs --conflicts --depends --enhances --list --location --obsoletes --provides --qf --recommends --requires --requires-pre --suggests --supplements --source" + local pkg_names=$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1) + opts="$repoquery_opts $pkg_names" ;; update|upgrade) - opts=$(tdnf list --upgrades | awk '{print $1}' | cut -d'.' -f1) + opts=$(tdnf list --upgrades 2>/dev/null | awk '{print $1}' | cut -d'.' -f1) + ;; + check|help|makecache) + # Commands that take no arguments + return 0 + ;; + check-update) + # Optional package names + opts="$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1)" + ;; + info) + # Package names or scope options + local scope_opts="installed available updates downgrades recent all" + local pkg_names="$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1)" + opts="$scope_opts $pkg_names" + ;; + list) + # Scope options or package names + local scope_opts="installed available updates downgrades recent all" + local pkg_names="$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1)" + opts="$scope_opts $pkg_names" + ;; + provides|whatprovides) + # Capability names (files, provides, etc.) - no easy way to list these + # Just return 0 to allow free-form input + return 0 + ;; + reposync) + # Optional repository names + opts=$(tdnf repolist all 2>/dev/null | awk '{if (NR > 1) print $1}') + ;; + search) + # Search terms - no easy way to list these, allow free-form input + return 0 + ;; + update-to|upgrade-to) + # Package names (with optional version) + opts="$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1)" + ;; + updateinfo) + # Mode options or package names + local mode_opts="all info summary" + local pkg_names="$(tdnf list 2>/dev/null | awk '{print $1}' | sort -u | cut -d'.' -f1)" + opts="$mode_opts $pkg_names" ;; esac COMPREPLY=( $(compgen -W "$opts" -- $cur) ) return 0 } -_tdnf() -{ +_tdnf() { local c=0 cur __opts __cmds COMPREPLY=() - __opts="--assumeno --assumeyes --cacheonly --debugsolver --disableexcludes --disableplugin --disablerepo --downloaddir --downloadonly --enablerepo --enableplugin --exclude --installroot --noautoremove --nogpgcheck --noplugins --quiet --reboot --refresh --releasever --repo --repofrompath --repoid --rpmverbosity --security --sec --setopt --skip --skipconflicts --skipdigest --skipsignature --skipobsoletes --testonly --version --available --duplicates --extras --file --installed --whatdepends --whatrequires --whatenhances --whatobsoletes --whatprovides --whatrecommends --whatrequires --whatsuggests --whatsupplements --depends --enhances --list --obsoletes --provides --recommends --requires --requires --suggests --source --supplements --arch --delete --download --download --gpgcheck --metadata --newest --norepopath --source --urls" - __cmds="autoerase autoremove check check-local check-update clean distro-sync downgrade erase help history info install list makecache mark provides whatprovides reinstall remove repolist repoquery reposync search update update-to updateinfo upgrade upgrade-to" + __opts="--4 -4 --6 -6 --alldeps --allowerasing --assumeno -y --assumeyes -b --best --builddeps -C --cacheonly -c --config -d --debuglevel --debugsolver --disableexcludes --disableplugin --disablerepo --downloaddir --downloadonly --enablerepo --enableplugin --exclude --forcearch --help -h -i --installroot --json --noautoremove --nodeps --nogpgcheck --nocligpgcheck --noplugins -q --quiet --reboot-required --refresh --releasever --repo --repofromdir --repofrompath --repoid --rpmdefine --rpmverbosity --sec-severity --security --setopt --skip-broken --skipconflicts --skipdigest --skipsignature --skipobsoletes --source --testonly -v --verbose --version --available --duplicates --extras --file --installed --userinstalled --upgrades --whatdepends --whatrequires --whatenhances --whatobsoletes --whatprovides --whatrecommends --whatsuggests --whatsupplements --whatconflicts --changelogs --conflicts --depends --enhances --list --location --obsoletes --provides --qf --recommends --requires --requires-pre --suggests --supplements --all --info --summary --recent --updates --downgrades --to --from --reverse --arch --delete --download-metadata --download-path --gpgcheck --metadata-path --newest-only --norepopath --urls" + __cmds="autoerase autoremove check check-local check-update clean count distro-sync downgrade erase help history info install list makecache mark provides whatprovides reinstall remove repolist repoquery reposync search update update-to updateinfo upgrade upgrade-to" cur="${COMP_WORDS[COMP_CWORD]}" _tdnf__process_if_prev_is_option && return 0 while [ $c -lt ${COMP_CWORD} ]; do diff --git a/tools/cli/lib/help.c b/tools/cli/lib/help.c index bc4cf83e..76b5e0f4 100644 --- a/tools/cli/lib/help.c +++ b/tools/cli/lib/help.c @@ -9,113 +9,407 @@ #include "includes.h" static const char *help_msg = - "Usage: tdnf [options] COMMAND\n\n" - "common options:\n" - " [--assumeno]\n" - " [-y, --assumeyes]\n" - " [-C, --cacheonly]\n" - " [-c [config file]]\n" - " [--debugsolver]\n" - " [--disableexcludes]\n" - " [--disableplugin=]\n" - " [--disablerepo=]\n" - " [--downloaddir=]\n" - " [--downloadonly]\n" - " [--enablerepo=]\n" - " [--enableplugin=]\n" - " [--exclude [file1,file2,...]]\n" - " [--installroot [path]]\n" - " [--noautoremove]\n" - " [--nogpgcheck]\n" - " [--noplugins]\n" - " [-q, --quiet]\n" - " [--reboot-required]\n" - " [--refresh]\n" - " [--releasever RELEASEVER]\n" - " [--repo=]\n" - " [--repofrompath=,]\n" - " [--repoid=]\n" - " [--rpmverbosity [debug level name]]\n" - " [--security]\n" - " [--sec-severity CVSS_v3.0_Severity]\n" - " [--setopt SETOPTS]\n" - " [--skip-broken]\n" - " [--skipconflicts]\n" - " [--skipdigest]\n" - " [--skipsignature]\n" - " [--skipobsoletes]\n" - " [--testonly]\n" - " [--version]\n\n" - "repoquery select options:\n" - " [--available]\n" - " [--duplicates]\n" - " [--extras]\n" - " [--file ]\n" - " [--installed]\n" - " [--whatdepends [,[..]]]\n" - " [--whatrequires [,[..]]]\n" - " [--whatenhances [,[..]]]\n" - " [--whatobsoletes [,[..]]]\n" - " [--whatprovides [,[..]]]\n" - " [--whatrecommends [,[..]]]\n" - " [--whatrequires [,[..]]]\n" - " [--whatsuggests [,[..]]]\n" - " [--whatsupplements [,[..]]]\n\n" - "repoquery query options:\n" - " [--depends]\n" - " [--enhances]\n" - " [--list]\n" - " [--obsoletes]\n" - " [--provides]\n" - " [--recommends]\n" - " [--requires]\n" - " [--requires-pre]\n" - " [--suggests]\n" - " [--source]\n" - " [--supplements]\n\n" - "reposync options:\n" - " [--arch= [--arch= [..]]\n" - " [--delete]\n" - " [--download-path=]\n" - " [--download-metadata]\n" - " [--gpgcheck]\n" - " [--metadata-path=]\n" - " [--newest-only]\n" - " [--norepopath]\n" - " [--source]\n" - " [--urls]\n\n" - "List of Main Commands\n\n" - "autoerase same as 'autoremove'\n" - "autoremove Remove a package and its automatic dependencies or all auto installed packages\n" - "check Checks repositories for problems\n" - "check-local Checks local rpm folder for problems\n" - "check-update Check for available package upgrades\n" - "clean Remove cached data\n" - "distro-sync Synchronize installed packages to the latest available versions\n" - "downgrade Downgrade a package\n" - "erase Remove a package or packages from your system\n" - "help Display a helpful usage message\n" - "history History Commands\n" - "info Display details about a package or group of packages\n" - "install Install a package or packages on your system\n" - "list List a package or groups of packages\n" - "makecache Generate the metadata cache\n" - "mark Mark package(s)\n" - "provides same as 'whatprovides'\n" - "whatprovides Find what package provides the given value\n" - "reinstall Reinstall a package\n" - "remove Remove a package or packages from your system\n" - "repolist Display the configured software repositories\n" - "repoquery Query repositories\n" - "reposync Download all packages from one or more repositories to a directory\n" - "search Search package details for the given string\n" - "update Upgrade a package or packages on your system (same as 'upgrade')\n" - "update-to same as 'upgrade-to'\n" - "updateinfo Display advisories about packages\n" - "upgrade Upgrade a package or packages on your system\n" - "upgrade-to Upgrade a package on your system to the specified version\n" - "\n" - "Please refer to https://github.com/vmware/tdnf/wiki for documentation."; + "Usage: tdnf [options] COMMAND\n" + "\nCommon Options\n" + "--4, -4 Resolve to IPv4 addresses only\n" + " Example: tdnf -4 install package\n" + + "--6, -6 Resolve to IPv6 addresses only\n" + " Example: tdnf -6 install package\n" + + "--alldeps Download all dependencies (requires --downloadonly)\n" + " Example: tdnf --downloadonly --alldeps install package\n" + + "--allowerasing Allow erasing of installed packages to resolve dependencies\n" + " Example: tdnf --allowerasing install pkg\n" + + "--assumeno Answer 'no' to all questions\n" + " Example: tdnf --assumeno remove package\n" + + "-y, --assumeyes Answer 'yes' to all questions\n" + " Example: tdnf -y install package\n" + + "-b, --best Try the best available package versions\n" + " Example: tdnf --best install package\n" + + "--builddeps Install build dependencies\n" + " Example: tdnf --builddeps install package\n" + + "-C, --cacheonly Run entirely from cache, don't update\n" + " Example: tdnf -C install package\n" + + "-c, --config Path to configuration file\n" + " Example: tdnf -c /etc/tdnf/tdnf.conf install package\n" + + "-d, --debuglevel Debug output level (emergency|alert|critical|error|warning|notice|info|debug)\n" + " Example: tdnf -d debug install package\n" + + "--debugsolver Enable debug output for dependency solver\n" + " Example: tdnf --debugsolver install pkg\n" + + "--disableexcludes Disable excludes from tdnf.conf\n" + " Example: tdnf --disableexcludes install\n" + + "--disableplugin Disable plugins by name\n" + " Example: tdnf --disableplugin=versionlock install package\n" + + "--disablerepo Disable repositories by id\n" + " Example: tdnf --disablerepo=updates install package\n" + + "--downloaddir Directory to store downloaded packages (requires --downloadonly)\n" + " Example: tdnf --downloadonly --downloaddir=/tmp/pkgs install\n" + + "--downloadonly Download packages only, do not install\n" + " Example: tdnf --downloadonly install pkg\n" + + "--enablerepo Enable repositories by id\n" + " Example: tdnf --enablerepo=updates install\n" + + "--enableplugin Enable plugins by name\n" + " Example: tdnf --enableplugin=versionlock install package\n" + + "--exclude Exclude packages by name\n" + " Example: tdnf --exclude=linux* install\n" + + "--forcearch Force architecture (x86_64|aarch64|noarch)\n" + " Example: tdnf --forcearch=x86_64 install\n" + + "-h, --help Show this help message\n" + " Example: tdnf --help\n" + + "-i, --installroot Set install root path (must be absolute)\n" + " Example: tdnf -i /mnt/chroot install pkg\n" + + "-j, --json Output in JSON format\n" + " Example: tdnf --json list installed\n" + + "--noautoremove Do not remove automatically installed dependencies\n" + " Example: tdnf --noautoremove remove pkg\n" + + "--nodeps Skip dependency checks(requires --downloadonly)\n" + " Example: tdnf --downloadonly --nodeps install package\n" + + "--nogpgcheck Skip GPG signature checks\n" + " Example: tdnf --nogpgcheck install pkg\n" + + "--nocligpgcheck Skip GPG signature checks for command line rpms\n" + " Example: tdnf --nocligpgcheck install http://foo.bar.com/package.rpm\n" + + "--noplugins Disable all plugins\n" + " Example: tdnf --noplugins install package\n" + + "-q, --quiet Quiet operation\n" + " Example: tdnf -q install package\n" + + "--reboot-required Check if reboot is required after transaction\n" + " Example: tdnf --reboot-required install package\n" + + "--refresh Refresh repository metadata before operation\n" + " Example: tdnf --refresh install package\n" + + "--releasever Set release version\n" + " Example: tdnf --releasever=5.0 install pkg\n" + + "--repo Enable only this repository\n" + " Example: tdnf --repo=base install pkg\n" + + "--repofromdir , Add repository from directory\n" + " Example: tdnf --repofromdir=local,/path/to/repo install package\n" + + "--repofrompath , Add repository from path\n" + " Example: tdnf --repofrompath=local,/mnt/repo install package\n" + + "--repoid Same as --repo\n" + " Example: tdnf --repoid=base install pkg\n" + + "--rpmdefine Define RPM macro\n" + " Example: tdnf --rpmdefine='_dbpath ' install package\n" + + "--rpmverbosity RPM verbosity level (emergency|alert|critical|error|warning|notice|info|debug)\n" + " Example: tdnf --rpmverbosity=debug install package\n" + + "--sec-severity Filter by security severity (Critical|Important|Moderate|Low)\n" + " Example: tdnf updateinfo --sec-severity=Critical\n" + + "--security Only show security updates\n" + " Example: tdnf --security update\n" + + "--setopt