#!/bin/bash # vim: ft=sh ts=2 sw=2 sts=2 et # vpm - void package management utility for # XBPS, the X Binary Package System # Copyright (c) 2016 Armin Jenewein , GitHub: @netzverweigerer # Copyright (c) 2019 Dave Eddy , GitHub: @bahamas10 # Copyright (c) 2021 oSoWoSo , codeberg.org: @oSoWoSo # For more information about XBPS, see: # https://github.com/voidlinux/xbps # Released under the terms of the GNU general public license, version 3+ # see LICENSE file for license information. # set version number version="1.3.1" # disable verbosity, by default # verbose=false # VPM color definitions numcolorok=2 numcolorfail=1 numcolorlogo=5 numcolorheader=3 numcolortext=4 numcolorgray=2 numcolorpkgcount=8 numcolordarkgray=11 numcolorbrackets=6 progname=${0##*/} # enable or disable colors based on the argument given, i.e.: # setcolors on # colors on # setcolors off # colors off # setcolors auto # colors on or off depending on environment declare -A COLORS setcolors () { local opt=$1 # determine if colors should be enabled or not if [[ $opt == auto ]]; then # if stdout is a TTY and the TERM looks like it supports color enable colors if [[ -t 1 && $TERM == *color* ]]; then opt='on' else opt='off' fi fi case "$opt" in on) local i for i in {1..11}; do if [[ -n ${COLORS[$i]} ]]; then continue fi COLORS[$i]=$(tput setaf "$i") done colorbrackets=${COLORS[$numcolorbrackets]} colordarkgray=${COLORS[$numcolordarkgray]} colorfail=${COLORS[$numcolorfail]} colorgray=${COLORS[$numcolorgray]} colorheader=${COLORS[$numcolorheader]} colorlogo=${COLORS[$numcolorlogo]} colorok=${COLORS[$numcolorok]} colorpkgcount=${COLORS[$numcolorpkgcount]} colortext=${COLORS[$numcolortext]} colorreset=$(tput sgr0) ;; off) colorbrackets= colordarkgray= colorfail= colorgray= colorheader= colorlogo= colorok= colorpkgcount= colortext= colorreset= unset COLORS declare -A COLORS ;; *) rmsg 255 "unknown color option: '$opt'" exit 255 ;; esac } # print the logo with brackets colorized getlogo () { printf '%s[%s%s%s]%s' \ "$colorbrackets" \ "$colorlogo" "$progname" \ "$colorbrackets" \ "$colorreset" } # prints a message (with vpm-prefix) msg () { local logo=$(getlogo) local newline=true if [[ $1 == '-n' ]]; then newline=false shift fi printf '%s %s%s%s' "$logo" "$colortext" "$*" "$colorreset" $newline && echo } # rmsg - same (but colorized based on return status passed via $1) rmsg () { local code=$1 shift local logo=$(getlogo) local statuscolor if ((code == 0)); then statuscolor=$colorok else statuscolor=$colorfail fi printf '%s %s%s%s\n' "$logo" "$statuscolor" "$*" "$colorreset" } banner () { echo -n "$colorlogo" echo ' __ ___ __ _ __ ' printf " \\ V / '_ \\ ' \ " echo -n "$colorgray" echo " $progname - void package management utility for XBPS" echo -n "$colorlogo" echo -n ' \_/| .__/_|_|_|' echo -n "$colorgray" echo ' Source: https://codeberg.org/oSoWoSo/vpm' echo -n "$colorlogo" echo ' |/ ' echo ' ยด ' echo -n "$colorreset" } version () { banner msg "$progname - Version: $version" msg "Copyright (c) 2016 Armin Jenewein (GPLv3+)" msg "oSoWoSo " msg "XBPS version: $(xbps-query -v --version | sed 's/GIT: UNSET//')" } # check if we have UID 0, exit otherwise rootcheck () { if [[ $EUID -gt 0 ]]; then msg "$(tput setaf 1)This operation needs super-user privileges.$(tput sgr 0)" SUDO=sudo else SUDO='' fi } t () { if [[ -n $show_translations ]]; then tput setaf 242 echo ' ' "$@" echo tput setaf 109 fi } wrapcommand() { local cmd ret cmd=("$@") echo "$colortext(${cmd[*]}):$colorreset" "${cmd[@]}" ret=$? rmsg "$ret" "[${cmd[*]}], return code was: $ret" exit "$ret" } usage () { echo version echo echo -n "$colorheader" echo "USAGE: " echo -n "$colorgray" echo "$progname [OPTIONS] [SUBCOMMANDS] []" echo echo -n "$colorheader" echo "OPTIONS: " echo -n "$colorgray" echo "--color= - Enable/Disable colorized output (default: auto)" echo "--help - (same as: help)" echo "--help-pager - (same as: helppager)" echo "--show-translations - Show XBPS command translations for $progname sub-commands" echo "--verbose - Verbose mode (shows XBPS command translations during execution)" echo echo -n "$colorheader" echo "SUBCOMMANDS: " echo -n "$colorgray" echo "sync (sy) - Synchronize remote repository data" t "xbps-install -S" echo "update (up) - Update the system" t "xbps-install -Suv" echo "listrepos (lr) - List configured repositories" echo "repolist (rl) - Alias for listrepos" t "xbps-query -v -L" echo "addrepo (ad) - Add an additional repository" t "xbps-install " echo "about (a) - Show information about " t "xbps-query -v -R" echo "filelist (fl) - Show file-list of " t "xbps-query -v -R -f" echo "deps - Show dependencies for " t "xbps-query -v -R -x" echo "reverse (rv) - Show reverse dependendies of (see man xbps-query)" t "xbps-query -v -R -X" echo "search (s) - Search for package by " t "xbps-query -v -Rs" echo "searchfile (sf) - Search for package containing (local)" t "xbps-query -v -o \"*/$1\"" echo "list (ls) - List installed packages" t "xbps-query -v -l" echo "install (i) - Install " t "xbps-install" echo "devinstall (di) - Install (and corresponding -devel package(s))" t "xbps-install -devel" echo "listalternatives (la) - List alternative candidates" t "xbps-alternatives -l" echo "setalternative (sa) " t "xbps-alternatives -s" echo "reconfigure (rc) - Re-configure installed " t "xbps-reconfigure -v" echo "forceinstall (fi) - Force installation of " t "xbps-install -f" echo "remove (rm) from the system" t "xbps-remove -v " echo "removerecursive (rr) - Recursively remove package(s) (and its dependencies)" t "xbps-remove -v -R" echo "cleanup (cl) - Remove obsolete packages in cachedir" t "xbps-remove -v -O" echo "autoremove (ar) - Remove orphaned packages" t "xbps-remove -v -o" echo "whatprovides (wp) - Search for package containing " t "xlocate " echo "help - Show usage information" echo "helppager (hp) - Show usage information (will pipe output to less/more)" echo echo -n "$colorheader" echo "XBPS COMPATIBILITY COOLNESS:" echo -n "$colorgray" f=(/usr/sbin/xbps-*) echo "$progname also understands all unknown XBPS sub-commands, too:" echo -n "Example: " selected=${f[$RANDOM % ${#f[@]}]} echo "$progname ${selected##*-} - see also: /usr/sbin/xbps-*" echo echo -n "$colorreset" } setcolors auto case "$1" in --color=true|--color=yes|--color=on) setcolors on shift ;; --color=auto) setcolors auto shift ;; --color=false|--color=off|--color=no) setcolors off shift ;; --verbose=true) shift verbose=true ;; --show-translations) shift show_translations=1 ;; --help) shift usage exit 255 ;; --help-pager) shift "$0" --color=off --help | less ;; --*) msg "Unknown option: $1 (try: $progname --help)" exit 1 ;; esac if [[ -z $1 ]]; then usage exit 0 fi cmd=$1 if [[ $arg =~ --.* ]]; then cmd=${arg:2} fi shift case "$cmd" in about|a) wrapcommand xbps-query -v -R "$@" ;; filelist|fl|listfiles) wrapcommand xbps-query -v -R -f "$@" ;; deps|dep|dependencies) wrapcommand xbps-query -v -R -x "$@" ;; reverse|rv) msg -n "Reverse dependencies for $* " wrapcommand xbps-query -v -R -X "$@" ;; searchfile|sf) msg -n 'searchfile ' wrapcommand xbps-query -v -o "*/$1" ;; remotesearchfile|rsf) msg -n 'remotesearchfile ' wrapcommand xbps-query -R -v -o "*/$1" ;; list|ls) msg -n 'Installed packages: ' count=0 while read -r _ pkg _; do ((count++)) pkgname=${pkg%-*} version=${pkg##*-} printf '%s%d %s%s %s (%s%s%s) [%s%s%s]%s\n' \ "$colorpkgcount" "$count" \ "$colortext" "$pkgname" \ "$colorbrackets" \ "$colorgray" "$version" \ "$colorbrackets" \ "$colordarkgray" "$pkg" \ "$colorbrackets" \ "$colorreset" done < <(xbps-query -v -l) ;; listalternative|listalternatives|la) wrapcommand xbps-alternatives -l "$@" ;; setalternative|setalternatives|sa) rootcheck wrapcommand xbps-alternatives -s "$@" echo ;; repolist|listrepos|rl|lr) code=0 msg -n "Configured repositories (xbps-query -v -L): " xbps-query -v -L ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-query -v -L] return code: $ret" echo msg -n "Available sub-repositories (xbps-query -v -Rs void-repo): " xbps-query -v -Rs void-repo ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-query -v -Rs void-repo] return code: $ret" echo msg -n "Use \"$progname addrepo \" to add a sub-repository." echo exit "$code" ;; addrepo|ad) rootcheck echo if (($# < 1)); then rmsg 255 "ERROR: install: argument missing, try --help." exit 1 fi code=0 for repo in "$@"; do msg "Adding repository: $repo" $SUDO xbps-install "$repo" ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-install $arg] return code: $ret" msg "Synchronizing remote repository data (xbps-install -S): " $SUDO xbps-install -S ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-install -S] return code: $ret" done exit "$code" ;; sync|sy) rootcheck msg -n 'Synchronizing remote repository data ' echo wrapcommand $SUDO xbps-install -S ;; install|i) rootcheck if (($# < 1)); then rmsg 255 "ERROR: install: argument missing, try --help." exit 1 fi msg -n "Installing packages: $* " echo wrapcommand $SUDO xbps-install "$@" ;; yesinstall) rootcheck if (($# < 1)); then rmsg 255 "ERROR: install: argument missing, try --help." exit 1 fi msg -n "Installing packages (assumed yes): $* " echo wrapcommand $SUDO xbps-install -y "$@" ;; devinstall) rootcheck if (($# < 1)); then rmsg 255 "ERROR: devinstall: argument missing, try --help." exit 1 fi args=("$@") code=0 msg "devinstall: Packages will be installed one-by-one" msg "Use \"forceinstall\" to override this if you know what you're doing." msg "(Note: forceinstall won't install -devel packages)" for arg in "${args[@]}"; do msg "Installing package: $arg (xbps-install $arg) ..." $SUDO xbps-install "$arg" ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-install $arg] return code: $ret" msg "installing devel package (${arg}-devel):" $SUDO xbps-install "${arg}-devel" ret=$? ((ret == 0)) || code=1 rmsg "$ret" "[xbps-install ${arg}-devel] return code: $ret" done exit "$code" ;; forceinstall|fi) rootcheck msg -n "Force-Installing Package(s): $* " echo wrapcommand $SUDO xbps-install -f "$@" ;; remove|rm) rootcheck msg -n "Removing package(s): $* " echo wrapcommand $SUDO xbps-remove -v "$@" ;; removerecursive|rr) rootcheck msg -n "Removing package(s) recursively: $* " echo wrapcommand $SUDO xbps-remove -v -R "$@" ;; reconfigure|rc) rootcheck msg -n 'reconfigure: Re-configuring package(s) ' echo wrapcommand $SUDO xbps-reconfigure -v "$@" ;; autoremove|ar) rootcheck msg -n 'autoremove: Removing orphaned packages ' echo wrapcommand $SUDO xbps-remove -v -o ;; update|upgrade|up) rootcheck msg -n 'Running system update ' echo $SUDO xbps-install -Suv if [[ $? == 16 ]]; then msg -n "$(tput setaf 1)Updating xbps $(tput sgr 0)" $SUDO xbps-install -u xbps wrapcommand $SUDO xbps-install -Suv else if [[ $? == 1 ]]; then msg -n 'Your system is up to date.' else msg -n $? 'Something goes wrong!' fi fi msg -n 'Checking if something need restart...' xcheckrestart ;; search|s) msg -n "Searching for: $* " wrapcommand xbps-query -v -Rs "$@" ;; cleanup|clean|cl) msg -n 'Remove obsolete packages in cachedir ' rootcheck echo wrapcommand $SUDO xbps-remove -v -O "$@" ;; h|help|-h|--help) usage ;; helppager|help-pager|hp) pager=$PAGER if [[ -z $pager ]]; then if command -v less &>/dev/null; then pager=less else pager=more fi fi "$0" --color=off help | $pager exit 0 ;; whatprovides|wp) if ! command -v xlocate &>/dev/null; then rmsg 255 "xlocate not found. Try installing the xtools package." exit 1 fi # msg -n "relaying to xlocate - use xlocate -S to (re-)build cached DB. " wrapcommand xlocate -S && xlocate "$@" ;; ''|*) xbpscmd="xbps-$cmd" if ! command -v "$xbpscmd" &>/dev/null; then rmsg 255 "Unrecognized $progname subcommand: $cmd (and $xbpscmd does not exist) - Try: $progname help" echo exit 1 fi # xbps- found msg -n 'relaying to XBPS: ' wrapcommand "$xbpscmd" "$@" ;; esac # enjoy and make better if you can...