shellcheck fixes, including real bug
[distro-functions] / src / package-manager-abstractions
1 #!/bin/bash
2 # Copyright (C) 2014 Ian Kelling
3
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # basic yum/apt package manager abstraction, plus a few minor conveniences
17 if command -v yum &> /dev/null; then
18 # package manager
19 p() {
20 local s; [[ $EUID != 0 ]] && s=sudo
21 $s yum "$@"
22 }
23 # package install
24 pi() {
25 local s; [[ $EUID != 0 ]] && s=sudo
26 $s yum -y install "$@"
27 }
28 # package find
29 pf() {
30 local s; [[ $EUID != 0 ]] && s=sudo
31 $s yum search "$@"
32 }
33 # package remove/uninstall
34 pu() {
35 local s; [[ $EUID != 0 ]] && s=sudo
36 $s yum autoremove "$@"
37 }
38 pup() { # upgrade
39 local s; [[ $EUID != 0 ]] && s=sudo
40 $s yum -y distro-sync full "$@"
41 }
42 # package list info
43 pl() {
44 yum info "$@"
45 }
46 pfile() {
47 yum whatprovides \*/$1
48 }
49
50 elif command -v apt-get &>/dev/null; then
51 pcheck() {
52 if dpkg -s -- "$@" | grep -Fx "Status: install ok installed" &>/dev/null; then
53 return 1
54 fi
55 return 0
56 }
57 pp() { # package policy
58 apt-cache policy $@
59 }
60 p() {
61 local s; [[ $EUID != 0 ]] && s=sudo
62 case $1 in
63 install)
64 $s apt-get --purge --auto-remove "$@"
65 ;;
66 *)
67 $s apt-get "$@"
68 ;;
69 esac
70 }
71 pupdate() {
72 local s f; [[ $EUID != 0 ]] && s=sudo
73 # update package list if its more than an 2 hours old
74 f=/var/cache/apt/pkgcache.bin
75 if [[ ! -r $f ]] \
76 || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*2 )); then
77 $s apt-get update
78 fi
79 }
80 pi() {
81 pcheck "$@" || return 0
82 while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
83 pupdate
84 local s; [[ $EUID != 0 ]] && s=sudo
85 $s $PI_PREFIX apt-get -y install --purge --auto-remove "$@"
86 }
87
88 pi-nostart() {
89 pcheck "$@" || return 0
90 while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
91 pupdate
92 local s; [[ $EUID != 0 ]] && s=sudo
93 local f=/usr/sbin/policy-rc.d
94 $s dd of=$f <<EOF
95 #!/bin/sh
96 exit 101
97 EOF
98 $s chmod +x $f
99 $s apt-get -y install --purge --auto-remove "$@"
100 $s rm $f
101 }
102 pf() {
103 # package name and descriptions
104 apt-cache search "$@"
105 }
106 pff() {
107 local s; [[ $EUID != 0 ]] && s=sudo
108 # nice aptitude search from emacs shell. package description width as
109 # wide as the screen, and package name field small aptitude
110 # manual can't figure out how wide emacs terminal is, of course
111 # it doesn't consult the $COLUMNS variable... and in a normal
112 # terminal, it makes the package name field ridiculously big
113 # also, remove that useless dash before the description
114 aptitude -F "%c%a%M %p %$((COLUMNS - 30))d" -w $COLUMNS search "$@"
115 }
116 pu() {
117 local s; [[ $EUID != 0 ]] && s=sudo
118 while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
119 $s apt-get -y remove --purge --auto-remove "$@"
120 # seems slightly redundant, but it removes more stuff sometimes.
121 $s apt-get -y autoremove
122 }
123 pup() { # upgrade
124 while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
125 pupdate
126 local s; [[ $EUID != 0 ]] && s=sudo
127 $s apt-get -y dist-upgrade --purge --auto-remove "$@"
128 $s apt-get -y autoremove
129 if [[ -e /usr/sbin/checkrestart ]]; then
130 $s /usr/sbin/checkrestart -p
131 fi
132 }
133 # package info
134 pl() {
135 if type -p aptitude &>/dev/null; then
136 aptitude show "$@"
137 else
138 apt-cache show "$@"
139 fi
140 }
141 pfile() {
142 local file=$1
143 # ucfq can tell us about config files which are not tracked
144 # with apt-file. but, for at least a few files I tested
145 # which are tracked with apt-file, ucfq doesn't show their
146 # package name. So, commenting this, waiting to find
147 # a config file only tracked by ucfq to see if it gives the
148 # package name and if I can identify this kind of file.
149 # if [[ $file == /* ]] && ! ucfq -w $file | grep ::: &>/dev/null; then
150 # ucfq $file
151
152 if [[ $file == */* ]]; then
153 apt-file find -x "$file"\$
154 else
155 apt-file find -x /"$file"\$
156 update-alternatives --list "$file" 2>/dev/null
157 fi
158 }
159 pkgfiles() {
160 if dpkg -s "$1" &>/dev/null; then
161 dpkg-query -L $1
162 else
163 apt-file -x list "^$1$"
164 fi
165 }
166
167 elif command -v pacman &>/dev/null; then
168 p() {
169 pacaur "$@"
170 }
171 pi() {
172 pacaur -S --noconfirm --needed --noedit "$@"
173 }
174 pf() {
175 pacaur -Ss "$@"
176 }
177 pu() {
178 pacaur -Rs --noconfirm "$@"
179 if p=$(pacaur -Qdtq); then
180 pacaur -Rs $p
181 fi
182 }
183 aurex() {
184 p="$1"
185 aur='https://aur.archlinux.org'
186 curl -s $aur/$(curl -s "$aur/rpc.php?type=info&arg=$p" \
187 | jq -r .results.URLPath) | tar xz
188 cd "$p"
189
190 }
191 pmirror() {
192 local s; [[ $EUID != 0 ]] && s=sudo
193 local x=$(mktemp)
194 curl -s "https://www.archlinux.org/mirrorlist/\
195 ?country=US&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on" \
196 | sed -r 's/^[ #]*(Server *=)/\1/' > $x
197 if (( $(stat -c %s $x ) > 10 )); then
198 $s cp $x /etc/pacman.d/mirrorlist
199 rm $x
200 fi
201 }
202 pup() { # upgrade
203 local s; [[ $EUID != 0 ]] && s=sudo
204 # file_time + 24 hours > current_time
205 if ! (( $(stat -c%Y /etc/pacman.d/mirrorlist) + 60*60*24 > $(date +%s) ))
206 then
207 pmirror
208 fi
209 pacaur -Syu --noconfirm "$@"
210 }
211 # package info
212 pl() {
213 pacaur -Si "$@"
214 }
215 pfile() {
216 pkgfile "$1"
217 }
218 pkgfiles() {
219 if pacaur -Qs "^$1$" &>/dev/null; then
220 pacman -Ql $1
221 else
222 pkgfile -l $1
223 fi
224 }
225 fi