192 lines
5.3 KiB
Bash
Executable File
192 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# gnf – Friendly wrapper around 'sudo dnf'
|
||
# Version 1.2
|
||
# Author: You
|
||
#
|
||
# Features:
|
||
# • Implicit '-y' on install/remove/reinstall/downgrade (toggle with -n/--no-confirm)
|
||
# • 'gnf update' pipeline:
|
||
# - dnf update [-y] [--refresh]
|
||
# - flatpak update (user + system)
|
||
# - optional fwupd refresh+update
|
||
# with its own flags: -r/--refresh, -f/--firmware, -n/--no-confirm, -y/--yes
|
||
# • Passes any other 'dnf' subcommand straight to sudo dnf
|
||
# • 'copr' sub-commands get auto '-y' for addrepo/removerepo/enable/disable/list
|
||
|
||
set -euo pipefail
|
||
|
||
PROGRAM=$(basename "$0")
|
||
VERSION="1.2"
|
||
|
||
usage() {
|
||
cat <<EOF
|
||
$PROGRAM – wrapper for sudo dnf with smart defaults
|
||
|
||
Usage:
|
||
$PROGRAM [GLOBAL OPTIONS] COMMAND [COMMAND OPTIONS] [ARGS...]
|
||
|
||
GLOBAL OPTIONS (must precede COMMAND):
|
||
-h, --help Show this help and exit
|
||
--version Show version and exit
|
||
-n, --no-confirm Disable the automatic '-y' on supported commands
|
||
-y, --yes (Re-)enable the automatic '-y' (default)
|
||
|
||
COMMANDS:
|
||
install, remove, reinstall, downgrade
|
||
→ Implicit '-y' unless disabled by global '-n'
|
||
|
||
update (alias: upgrade)
|
||
→ dnf update + flatpak update + optional fwupd
|
||
→ COMMAND OPTIONS:
|
||
-r, --refresh Pass --refresh to dnf update
|
||
-f, --firmware After dnf+flatpak, run fwupdmgr refresh && update
|
||
-n, --no-confirm Do NOT add '-y' to dnf update
|
||
-y, --yes Force '-y' on dnf update (default)
|
||
→ You may group short flags: e.g. -rf or -fr
|
||
|
||
copr (subcommands: addrepo, removerepo, enable, disable, list, …)
|
||
→ For addrepo/removerepo/enable/disable/list, we auto '-y'
|
||
→ Other copr actions are passed straight through
|
||
|
||
any other dnf COMMAND is forwarded to 'sudo dnf'
|
||
|
||
EXAMPLES:
|
||
gnf install vim git
|
||
gnf -n install firefox # interactive remove/install
|
||
gnf update # dnf update -y ; flatpak
|
||
gnf update -r # + --refresh
|
||
gnf update -rf # + firmware
|
||
gnf -n update --refresh # no -y, + refresh
|
||
gnf copr addrepo user/project
|
||
|
||
EOF
|
||
}
|
||
|
||
# If no args, show help
|
||
if [[ $# -eq 0 ]]; then
|
||
usage
|
||
exit 0
|
||
fi
|
||
|
||
#
|
||
# 1) Parse GLOBAL OPTIONS
|
||
#
|
||
auto_yes=true
|
||
while [[ $# -gt 0 && "$1" == -* ]]; do
|
||
case "$1" in
|
||
-h|--help) usage; exit 0 ;;
|
||
--version) echo "$PROGRAM $VERSION"; exit 0 ;;
|
||
-n|--no-confirm) auto_yes=false; shift ;;
|
||
-y|--yes) auto_yes=true; shift ;;
|
||
--) shift; break ;; # end of globals
|
||
*) break ;; # first non-global dash-opt
|
||
esac
|
||
done
|
||
|
||
# Must have at least one positional argument now: the COMMAND
|
||
if [[ $# -lt 1 ]]; then
|
||
echo "Error: no COMMAND specified." >&2
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
cmd=$1; shift
|
||
# Treat 'upgrade' as alias for 'update'
|
||
[[ "$cmd" == "upgrade" ]] && cmd=update
|
||
|
||
#
|
||
# 2) Dispatch on COMMAND
|
||
#
|
||
case "$cmd" in
|
||
|
||
# ---------------------------------------------------------------
|
||
# install/remove/reinstall/downgrade (auto '-y' unless -n)
|
||
# ---------------------------------------------------------------
|
||
install|remove|reinstall|downgrade)
|
||
dnf_args=()
|
||
$auto_yes && dnf_args+=(-y)
|
||
sudo dnf "$cmd" "${dnf_args[@]}" "$@"
|
||
exit $?
|
||
;;
|
||
|
||
# ---------------------------------------------------------------
|
||
# update pipeline
|
||
# ---------------------------------------------------------------
|
||
update)
|
||
# 2.1) Map any long opts to short ones for getopts
|
||
mapped=()
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
--refresh) mapped+=(-r) ;;
|
||
--firmware) mapped+=(-f) ;;
|
||
--no-confirm) mapped+=(-n) ;;
|
||
--yes) mapped+=(-y) ;;
|
||
--) mapped+=(--);;
|
||
*) mapped+=("$arg");;
|
||
esac
|
||
done
|
||
|
||
# 2.2) Parse update-specific flags with getopts (supports grouping: -rf)
|
||
refresh=false
|
||
firmware=false
|
||
confirm=$auto_yes
|
||
OPTIND=1
|
||
# note: the leading colon suppresses getopts’ own error msg
|
||
while getopts ":rfny" opt "${mapped[@]}"; do
|
||
case "$opt" in
|
||
r) refresh=true ;;
|
||
f) firmware=true ;;
|
||
n) confirm=false ;;
|
||
y) confirm=true ;;
|
||
\?) echo "Unknown option '-$OPTARG' for update" >&2; exit 1 ;;
|
||
esac
|
||
done
|
||
shift $((OPTIND - 1))
|
||
|
||
# 2.3) Run the dnf update
|
||
dnf_args=()
|
||
$confirm && dnf_args+=(-y)
|
||
$refresh && dnf_args+=(--refresh)
|
||
sudo dnf update "${dnf_args[@]}" "$@"
|
||
|
||
# 2.4) Run flatpak updates (user then system)
|
||
flatpak update -y
|
||
sudo flatpak update
|
||
|
||
# 2.5) Optional firmware via fwupd
|
||
if $firmware; then
|
||
sudo fwupdmgr refresh
|
||
sudo fwupdmgr update
|
||
fi
|
||
|
||
exit $?
|
||
;;
|
||
|
||
# ---------------------------------------------------------------
|
||
# copr sub-commands
|
||
# ---------------------------------------------------------------
|
||
copr)
|
||
if [[ $# -lt 1 ]]; then
|
||
echo "Error: 'gnf copr' requires a subcommand." >&2
|
||
exit 1
|
||
fi
|
||
sub=$1; shift
|
||
case "$sub" in
|
||
addrepo|removerepo|enable|disable|list)
|
||
sudo dnf copr "$sub" -y "$@" ;;
|
||
*)
|
||
sudo dnf copr "$sub" "$@" ;;
|
||
esac
|
||
exit $?
|
||
;;
|
||
|
||
# ---------------------------------------------------------------
|
||
# anything else → pass straight to sudo dnf
|
||
# ---------------------------------------------------------------
|
||
*)
|
||
sudo dnf "$cmd" "$@"
|
||
exit $?
|
||
;;
|
||
esac
|