Merge pull request #7 from duckwork/master
[vpm.git] / vpm
blob8b770e528e508205aeea4c975ad278deb8cfb1da
1 #!/bin/bash
2 # vim: ft=sh ts=2 sw=2 sts=2 et
4 # vpm - void package management utility for
5 # XBPS, the X Binary Package System
6 # Copyright (c) 2016 Armin Jenewein <a@m2m.pm>, GitHub: @netzverweigerer
7 # For more information about XBPS, see:
8 # https://github.com/voidlinux/xbps
10 # Released under the terms of the GNU general public license, version 3+
11 # see LICENSE file for license information.
13 # set version number
14 version="1.3"
16 # disable verbosity, by default
17 verbose=false
19 # VPM color definitions
20 numcolorok=2
21 numcolorfail=1
22 numcolorlogo=5
23 numcolorheader=3
24 numcolortext=4
25 numcolorgray=2
26 numcolorpkgcount=8
27 numcolordarkgray=11
28 numcolorbrackets=6
30 progname=${0##*/}
32 # enable or disable colors based on the argument given, i.e.:
33 # setcolors on # colors on
34 # setcolors off # colors off
35 # setcolors auto # colors on or off depending on environment
36 declare -A COLORS
37 setcolors () {
38 local opt=$1
40 # determine if colors should be enabled or not
41 if [[ $opt == auto ]]; then
42 # if stdout is a TTY and the TERM looks like it supports color enable colors
43 if [[ -t 1 && $TERM == *color* ]]; then
44 opt='on'
45 else
46 opt='off'
50 case "$opt" in
51 on)
52 local i
53 for i in {1..11}; do
54 if [[ -n ${COLORS[$i]} ]]; then
55 continue
57 COLORS[$i]=$(tput setaf "$i")
58 done
59 colorbrackets=${COLORS[$numcolorbrackets]}
60 colordarkgray=${COLORS[$numcolordarkgray]}
61 colorfail=${COLORS[$numcolorfail]}
62 colorgray=${COLORS[$numcolorgray]}
63 colorheader=${COLORS[$numcolorheader]}
64 colorlogo=${COLORS[$numcolorlogo]}
65 colorok=${COLORS[$numcolorok]}
66 colorpkgcount=${COLORS[$numcolorpkgcount]}
67 colortext=${COLORS[$numcolortext]}
68 colorreset=$(tput sgr0)
70 off)
71 colorbrackets=
72 colordarkgray=
73 colorfail=
74 colorgray=
75 colorheader=
76 colorlogo=
77 colorok=
78 colorpkgcount=
79 colortext=
80 colorreset=
81 unset COLORS
82 declare -A COLORS
85 rmsg 255 "unknown color option: '$opt'"
86 exit 255
88 esac
91 # print the logo with brackets colorized
92 getlogo () {
93 printf '%s[%s%s%s]%s' \
94 "$colorbrackets" \
95 "$colorlogo" "$progname" \
96 "$colorbrackets" \
97 "$colorreset"
100 # prints a message (with vpm-prefix)
101 msg () {
102 local logo=$(getlogo)
104 echo "$logo" "$colortext" "$@" "$colorreset"
107 # rmsg - same (but colorized based on return status passed via $1)
108 rmsg () {
109 local code=$1
110 shift
112 local logo=$(getlogo)
113 local statuscolor
115 if ((code == 0)); then
116 statuscolor=$colorok
117 else
118 statuscolor=$colorfail
121 echo "$logo" "$statuscolor" "$@" "$colorreset"
124 banner () {
125 echo -n "$colorlogo"
126 echo ' __ ___ __ _ __ '
128 printf " \\ V / '_ \\ ' \ "
129 echo -n "$colorgray"
130 echo " $progname - void package management utility for XBPS"
131 echo -n "$colorlogo"
132 echo -n ' \_/| .__/_|_|_|'
133 echo -n "$colorgray"
134 echo ' GitHub: https://github.com/netzverweigerer/vpm'
135 echo -n "$colorlogo"
136 echo ' |/ '
137 echo ' ยด '
138 echo -n "$colorreset"
141 version () {
142 banner
143 msg "$progname - Version: $version"
144 msg "Copyright (c) 2016 Armin Jenewein <a@m2m.pm> (GPLv3+)"
145 msg "XBPS version: $(xbps-query -v --version | sed 's/GIT: UNSET//')"
148 # check if we have UID 0, exit otherwise
149 rootcheck () {
150 if [[ $EUID -gt 0 ]]; then
151 msg "$progname: This operation needs super-user privileges."
152 SUDO=sudo
153 else
154 SUDO=''
158 t () {
159 if [[ -n $show_translations ]]; then
160 tput setaf 242
161 echo ' ' "$@"
162 echo
163 tput setaf 109
167 usage () {
168 echo
169 version
170 echo
171 echo -n "$colorheader"
172 echo "USAGE: "
173 echo -n "$colorgray"
174 echo "$progname [OPTIONS] [SUBCOMMANDS] [<ARGS>]"
175 echo
176 echo -n "$colorheader"
177 echo "OPTIONS: "
178 echo -n "$colorgray"
179 echo "--color=<yes|no|auto> - Enable/Disable colorized output (default: auto)"
180 echo "--help - (same as: help)"
181 echo "--help-pager - (same as: helppager)"
182 echo "--show-translations - Show XBPS command translations for $progname sub-commands"
183 echo "--verbose - Verbose mode (shows XBPS command translations during execution)"
184 echo
185 echo -n "$colorheader"
186 echo "SUBCOMMANDS: "
187 echo -n "$colorgray"
188 echo "sync (sy) - Synchronize remote repository data"
189 t "xbps-install -S"
190 echo "update (up) - Update the system"
191 t "xbps-install -Sduv"
192 echo "listrepos (lr) - List configured repositories"
193 echo "repolist (rl) - Alias for listrepos"
194 t "xbps-query -v -L"
195 echo "addrepo (ar) <ARGS> - Add an additional repository"
196 t "xbps-install <ARGS>"
197 echo "info (in) <pkg> - Show information about <package>"
198 t "xbps-query-v -R"
199 echo "filelist (fl) <pkg> - Show file-list of <package>"
200 t "xbps-query -v -R -f"
201 echo "deps <pkg> - Show dependencies for <package>"
202 t "xbps-query -v -R -x"
203 echo "reverse (rv) <pkg> - Show reverse dependendies of <package> (see man xbps-query)"
204 t "xbps-query -v -R -X"
205 echo "search (s) <name> - Search for package by <name>"
206 t "xbps-query -v -Rs"
207 echo "searchfile (sf) <file> - Search for package containing <file> (local)"
208 t "xbps-query -v -o \"*/$1\""
209 echo "list (ls) - List installed packages"
210 t "xbps-query -v -l"
211 echo "install (i) <pkg(s)> - Install <package(s)>"
212 t "xbps-install -S"
213 echo "devinstall (di) <pkg(s)> - Install <package> (and corresponding <package>-devel package(s))"
214 t "xbps-install -S <package> <package>-devel"
215 echo "listalternatives (la) - List alternative candidates"
216 t "xbps-alternatives -l"
217 echo "setalternative (sa) <pkg(s) - Set alternative for <package>"
218 t "xbps-alternatives -s"
219 echo "reconfigure (rc) <pkg> - Re-configure installed <package>"
220 t "xbps-reconfigure -v"
221 echo "forceinstall (fi) <pkg(s)> - Force installation of <package(s)>"
222 t "xbps-install -f"
223 echo "remove (rm) <package(s)) - Remove <package(s)> from the system"
224 t "xbps-remove -v "
225 echo "removerecursive (rr) <pkg(s)> - Recursively remove package(s) (and its dependencies)"
226 t "xbps-remove -v -R"
227 echo "cleanup (cl) - Clean up cache directory"
228 t "xbps-remove -v -O"
229 echo "autoremove (ar) - Remove orphaned packages"
230 t "xbps-remove -v -O"
231 echo "whatprovides (wp) <file> - Search for package containing <file>"
232 t "xlocate <pkg>"
233 echo "help - Show usage information"
234 echo "helppager (hp) - Show usage information (will pipe output to less/more)"
235 echo
236 echo -n "$colorheader"
237 echo "XBPS COMPATIBILITY COOLNESS:"
238 echo -n "$colorgray"
239 f=(/usr/sbin/xbps-*)
240 echo "$progname also understands all unknown XBPS sub-commands, too:"
241 echo -n "Example: "
242 selected=${f[$RANDOM % ${#f[@]}]}
243 echo "$progname ${selected##*-} <ARGS> - see also: /usr/sbin/xbps-*"
244 echo
245 echo -n "$colorreset"
248 setcolors auto
249 case "$1" in
250 --color=true|--color=yes|--color=on)
251 setcolors on
252 shift
254 --color=auto)
255 setcolors auto
256 shift
258 --color=false|--color=off|--color=no)
259 setcolors off
260 shift
262 --verbose=true)
263 shift
264 verbose=true
266 --show-translations)
267 shift
268 show_translations=1
270 --help)
271 shift
272 usage
273 exit 255
275 --help-pager)
276 shift
277 "$0" --color=off --help | less
279 --*)
280 msg "Unknown option: $1 (try: $progname --help)"
281 exit 1
283 esac
285 if [[ "$1" == "" ]]; then
286 usage
287 exit 0
290 arg=$1
292 if [[ "$arg" =~ --.* ]]; then
293 b=${arg:2}
294 arg=$b
297 case "$arg" in
298 info|in)
299 shift
300 msg "(xbps-query -v -R $@):"
301 xbps-query -v -R "$@"
302 ret=$?
303 rmsg "$ret" "Execution finished (xbps-query -v -R $@), return code was: $ret"
304 exit "$ret"
307 filelist|fl|listfiles)
308 shift
309 xbps-query -v -R -f "$@"
310 ret=$?;
311 if [[ $verbose == "true" ]]; then
312 rmsg "$ret" "Execution finished (xbps-query -v -R -f \"*/$1\"), return code was: $ret"
314 exit "$ret"
317 deps|dep|dependencies)
318 shift
319 xbps-query -v -R -x "$@"
320 ret=$?
321 rmsg "$ret" "Execution finished (xbps-query -v -R -x \"*/$1\"), return code was: $ret"
322 exit "$ret"
325 reverse|rv)
326 shift
327 msg "Reverse dependencies for $@ (xbps-query -v -R $@):"
328 xbps-query -v -R -X "$@"
329 ret=$?
330 msg "$ret" "Execution finished (xbps-query -v -R $@), return code was: $ret"
331 exit "$ret"
334 searchfile|sf)
335 shift
336 msg "searchfile (xbps-query -v -o \"*/$1\"):"
337 xbps-query -v -o "*/$1"
338 ret=$?
339 msg "$ret" "Execution finished (xbps-query -v -o \"*/$1\"), return code was: $ret"
340 exit $ret
343 remotesearchfile|rsf)
344 shift
345 msg "remotesearchfile (xbps-query -R -v -o \"*/$1\"):"
346 xbps-query -R -v -o "*/$1"
347 ret=$?
348 msg "$ret" "Execution finished (xbps-query -R -v -o \"*/$1\"), return code was: $ret"
349 exit "$ret"
352 list|ls)
353 shift
354 msg "Installed packages: "
356 count=0
357 while read -r _ pkg _; do
358 ((count++))
359 pkgname=${pkg%-*}
360 version=${pkg##*-}
362 printf '%s%d %s%s %s (%s%s%s) [%s%s%s]%s\n' \
363 "$colorpkgcount" "$count" \
364 "$colortext" "$pkgname" \
365 "$colorbrackets" \
366 "$colorgray" "$version" \
367 "$colorbrackets" \
368 "$colordarkgray" "$pkg" \
369 "$colorbrackets" \
370 "$colorreset"
371 done < <(xbps-query -v -l)
374 listalternative|listalternatives|la)
375 xbps-alternatives -l "$@"
376 ret=$?
377 rmsg "$ret" "xbps-alternatives return code: $ret (xbps-alternatives -l $@)"
380 setalternative|setalternatives|sa)
381 shift
382 rootcheck
383 $SUDO xbps-alternatives -s "$@"
384 ret=$?
385 rmsg "$ret" "xbps-alternatives return code: $ret (xbps-alternatives -s $@)"
388 repolist|listrepos|rl|lr)
389 msg "Configured repositories (xbps-query -v -L): "
390 xbps-query -v -L
391 ret=$?
392 rmsg "$ret" "[xbps-query -v -L] return code: $ret"
393 shift
394 echo
395 msg "Available sub-repositories (xbps-query -v -Rs void-repo): "
396 xbps-query -v -Rs void-repo
397 ret=$?
398 rmsg "$ret" "[xbps-query -v -Rs void-repo] return code: $ret"
399 shift
400 echo
401 msg "Use \"$progname addrepo <repository>\" to add a sub-repository."
402 echo
405 addrepo|ar)
406 shift
407 rootcheck
408 for repo in "$@"; do
409 msg "Adding repository: $repo"
410 $SUDO xbps-install "$1"
411 ret=$?
412 rmsg "$ret" "[xbps-install $arg] return code: $ret"
413 msg "Synchronizing remote repository data (xbps-install -S): "
414 $SUDO xbps-install -S
415 ret=$?
416 rmsg "$ret" "[xbps-install -S] return code: $ret"
417 shift
418 done
421 sync|sy)
422 shift
423 rootcheck
424 msg "Synchronizing remote repository data: (xbps-install -S):"
425 $SUDO xbps-install -S
426 ret=$?
427 rmsg "$ret" "[xbps-install -S] return code: $ret"
430 install|i)
431 shift
432 rootcheck
433 if [[ "$#" -lt 1 ]]; then
434 msg "ERROR: install: argument missing, try --help."
435 exit 1
437 msg "Installing packages: $@ (xbps-install -S $@) ..."
438 $SUDO xbps-install -S "$@"
439 ret=$?
440 rmsg "$ret" "[xbps-install -S $@] return code: $ret"
443 yesinstall)
444 shift
445 rootcheck
446 if [[ "$#" -lt 1 ]]; then
447 msg "ERROR: install: argument missing, try --help."
448 exit 1
450 msg "Installing packages: $@ (xbps-install -S $@) ..."
451 $SUDO xbps-install -y -S "$@"
452 ret=$?
453 rmsg "$ret" "[xbps-install -S $@] return code: $ret"
456 devinstall)
457 shift
458 rootcheck
459 if [[ "$#" -lt 1 ]]; then
460 msg "ERROR: devinstall: argument missing, try --help."
461 exit 1
463 args=("$@")
464 msg "devinstall: Packages will be installed one-by-one"
465 msg "Use \"forceinstall\" to override this if you know what you're doing."
466 msg "(Note: forceinstall won't install -devel packages)"
467 for arg in "${args[@]}"; do
468 let count=count+1
469 msg "Installing package: $arg (xbps-install -S $arg) ..."
470 $SUDO xbps-install -S "$arg"
471 ret=$?
472 rmsg "$ret" "[xbps-install -S $arg] return code: $ret"
473 msg "installing devel package (${arg}-devel):"
474 $SUDO xbps-install -S "${arg}-devel"
475 ret=$?
476 rmsg "$ret" "[xbps-install -S ${arg}-devel] return code: $ret"
477 done
480 forceinstall|fi)
481 shift
482 rootcheck
483 msg "Force-Installing Package(s): $@ (xbps-install -Sf $@)"
484 $SUDO xbps-install -Sf "$@"
485 ret=$?
486 rmsg "$ret" "[xbps-install -Sf ${@}] return code: $ret"
489 remove|rm)
490 shift
491 rootcheck
492 msg "Removing package(s): $@ (xbps-remove -v $@)"
493 $SUDO xbps-remove -v "$@"
494 ret=$?
495 rmsg "$ret" "[xbps-remove -v ${@}] return code: $ret"
498 removerecursive|rr)
499 shift
500 rootcheck
501 msg "Removing package(s) recursively: $@ (xbps-remove -v -R $@)"
502 $SUDO xbps-remove -v -R "$@"
503 ret=$?
504 rmsg "$ret" "[xbps-remove -v -R ${@}] return code: $ret"
507 reconfigure|rc)
508 shift
509 rootcheck
510 msg "reconfigure: Re-configuring package(s) (xbps-reconfigure -v $@):"
511 $SUDO xbps-reconfigure -v "$@"
512 ret=$?
513 rmsg "$ret" "[xbps-reconfigure -v ${@}] return code: $ret"
516 autoremove|ar)
517 shift
518 rootcheck
519 msg "autoremove: Removing orphaned packages (xbps-remove -v -o)"
520 $SUDO xbps-remove -v -o
521 ret=$?
522 rmsg "$ret" "[xbps-remove -v -o] return code: $ret"
525 update|upgrade|up)
526 shift
527 rootcheck
528 msg "Running system update (xbps-install -Suv)"
529 $SUDO xbps-install -Suv
530 ret=$?
531 if [[ $ret == 16 ]]; then
532 msg "Updating xbps (xbps-install -u xbps)"
533 xbps-install -u xbps
534 ret2=$?
535 rmsg "$ret2" "[xbps-install -u xbps] return code: $ret2"
536 exit 0
538 rmsg "$ret" "[xbps-install -Suv] return code: $ret"
541 search|s)
542 shift
543 msg "Searching for: $@ (xbps-query -v -Rs $@)"
544 xbps-query -v -Rs "$@"
545 ret=$?
546 rmsg "$ret" "[xbps-query -v -Rs $@] return code: $ret"
549 cleanup|clean|cl)
550 msg "Cleaning up packages (will remove orphaned packages) (xbps-remove -v -O $@)"
551 shift
552 rootcheck
553 $SUDO xbps-remove -v -O "$@"
554 ret=$?
555 rmsg "$ret" "[xbps-remove -v -O $@] return code: $ret"
558 h|help|-h|--help)
559 usage
562 helppager|help-pager|hp)
563 if hash less >/dev/null 2>&1; then
564 "$0" --color=off help | less
565 else
566 "$0" --color=off help | more
570 whatprovides|wp)
571 shift
572 if hash xlocate >/dev/null 2>&1; then
573 # set -x
574 # xlocate -S "$@"
575 msg "relaying to: \"xlocate $@\" - use xlocate -S to (re-)build cached DB."
576 xlocate "$@"
577 else
578 rmsg 255 "xlocate not found. Try installing the xtools package."
582 ''|*)
583 a="$1"
584 if hash "xbps-${a}" >/dev/null 2>&1; then
585 shift
586 # xbps-<subcommand> found
587 msg "relaying to XBPS: xbps-$a $@"
588 "xbps-$a" "$@"
589 ret=$?
590 rmsg "$ret" "xbps-$a $@ return code: $ret"
591 else
592 rmsg 255 "Unrecognized $progname subcommand: $1 (and xbps-$1 does not exist) - Try: $progname help"
593 echo
594 exit 1
598 esac
600 exit 0