tazpkg view modules/remove @ rev 926

Unblock package before removing
author Aleksej Bobylev <al.bobylev@gmail.com>
date Mon Sep 26 11:12:32 2016 +0300 (2016-09-26)
parents 62fda2a9d702
children fd96c4f9a889
line source
1 #!/bin/sh
2 # TazPkg - Tiny autonomous zone packages manager, hg.slitaz.org/tazpkg
3 # remove - TazPkg module
4 # Remove packages
7 # Connect function libraries
8 . /lib/libtaz.sh
10 # Get TazPkg working environment
11 . @@MODULES@@/getenv
16 # Log activity
18 log_pkg() {
19 [ -w "$LOG" ] &&
20 echo "$(date +'%F %T') - $1 - $PACKAGE ($VERSION$EXTRAVERSION)" >> "$LOG"
21 }
24 # Interactive mode
26 im() { tty -s; }
29 # Block of receipt function callers
30 # Why? "Bad" receipt sourcing can redefine some vital TazPkg variables.
31 # Few receipts function should be patched now.
33 # Input: $1 = path to the receipt to be processed
35 call_pre_remove() {
36 local tmp
37 if grep -q '^pre_remove()' "$1"; then
38 action 'Execute pre-remove commands...'
39 tmp="$(mktemp)"
40 cp "$1" "$tmp"
41 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
42 ( . "$tmp"; pre_remove "$root" )
43 status
44 rm "$tmp"
45 fi
46 }
48 call_post_remove() {
49 local tmp
50 if grep -q '^post_remove()' "$1"; then
51 action 'Execute post-remove commands...'
52 tmp="$(mktemp)"
53 cp "$1" "$tmp"
54 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
55 ( . "$tmp"; post_remove "$root" )
56 status
57 rm "$tmp"
58 fi
59 }
62 # return possible name for a virtual package name
64 virtual_pkg() {
65 # input: $1 virtual package name
66 # $2 repository db directory
67 # output: display possible package name
69 debug "\nvirtual_pkg('$1', '$2')"
70 local i
71 unset IFS
72 for i in $(grep -hs "^$1=" "$2/packages.equiv" | sed "s/^$1=//"); do
73 if echo $i | fgrep -q : ; then
74 # format 'alternative:newname'
75 # if alternative is installed then substitute newname
76 if [ -f $INSTALLED/${i%:*}/receipt ]; then
77 # substitute package dependency
78 echo ${i#*:}
79 return
80 fi
81 elif ! grep -q "^$1 " "$2/packages.info" || [ -f "$INSTALLED/$i/receipt" ]; then
82 # unconditional substitution
83 echo $i
84 return
85 fi
86 done
87 # the real package name
88 echo $1
89 }
94 for rep in $PRIORITY; do
95 [ ! -f "$rep/packages.info" ] && continue
96 PACKAGE="$(virtual_pkg "$1" "$rep")"
97 [ "$PACKAGE" != "$1" ] && break
98 done
100 if [ ! -f "$INSTALLED/$PACKAGE/receipt" ]; then
101 newline; _ 'Package "%s" is not installed.' "$PACKAGE"
102 exit 1
103 fi
105 . "$INSTALLED/$PACKAGE/receipt"
107 # Info #1: dependent packages (to be processed later)
108 ALTERED="$(awk -F$'\t' -vp=" $PACKAGE " 'index(" " $8 " ", p) { printf " %s\n", $1 }' "$PKGS_DB/installed.info")"
110 if [ -n "$ALTERED" ]; then
111 _ 'The following packages depend on package "%s":' "$PACKAGE"
112 echo "$ALTERED"
113 fi
115 # Info #2: changed packages (to be processed later)
116 REFRESH=$(cd "$INSTALLED"; grep -sl "^$PACKAGE$" */modifiers)
118 if [ -n "$REFRESH" ]; then
119 _ 'The following packages have been modified by package "%s":' "$PACKAGE"
120 for i in $REFRESH; do
121 echo " ${i%/modifiers}"
122 done
123 fi
125 # Confirmation
126 if [ -n "$noconfirm" ] || im && [ -z "$auto" ]; then
127 confirm "$(_ 'Remove package "%s" (%s)? (y/N)' "$PACKAGE" "$VERSION$EXTRAVERSION")"
128 if [ "$?" -ne 0 ]; then
129 newline; _ 'Uninstallation of package "%s" cancelled.' "$PACKAGE"
130 exit 0
131 fi
132 fi
133 # We are here: non-interactive mode, or --auto, or --yes, or answer 'y'
135 # Removing package
136 title 'Removing package "%s"' "$PACKAGE"
138 # Unblock package quietly; otherwise:
139 # 1. We can no longer install the package one more time - because it is blocked
140 # 2. We can no longer unblock the package - because it is not installed
141 tazpkg -u "$PACKAGE" --nowarning | grep -v '^$'
143 # [1/5] Pre-remove commands
144 call_pre_remove "$INSTALLED/$PACKAGE/receipt"
147 # [2/5] Removing files
148 action 'Removing all files installed...'
150 # NOTE: package 'faenza-icon-theme' install time: 12s; removing time ~ 11min on my system o_O
151 # After optimization: 3s! (Long) for-loops are (big) evil ;)
153 # NOTE: many packages contains filenames with spaces:
154 # lzcat /var/lib/tazpkg/files.list.lzma | awk -F" " '{if(NF>2)print $1}' | sed 's|:$||' | uniq
155 # Redefine IFS to only-new-line field separator:
156 IFS=$'\n'
158 files2remove="$(mktemp)"
160 debug '\nDetermine which files to remove...'
161 if [ -f "$INSTALLED/$PACKAGE/modifiers" ]; then
162 debug ' (modifiers detected)'
164 mods="$(mktemp)"
165 for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do
166 cat "$INSTALLED/$mod/files.list" >> "$mods" 2>/dev/null
167 done
169 awk -vroot="$root" -vfl="$INSTALLED/$PACKAGE/files.list" '
170 {
171 if (FILENAME == fl)
172 f[$0] = 1;
173 else
174 f[$0] = "";
175 }
176 END {
177 for (i in f) {
178 if (f[i] == 1) printf "%s%s\n", root, i;
179 }
180 }' "$INSTALLED/$PACKAGE/files.list" "$mods" > "$files2remove"
181 rm "$mods"
182 else
183 debug ' (modifiers not detected)'
185 awk -vroot="$root" '{ printf "%s%s\n", root, $0; }' \
186 "$INSTALLED/$PACKAGE/files.list" > "$files2remove"
187 fi
189 debug 'Removing files...'
190 xargs rm -f < "$files2remove"
192 debug 'Removing folders...'
193 awk '
194 BEGIN {
195 FS = "/"; OFS = "/";
196 }
197 {
198 # removing filename beyond the last "/"
199 $NF = "";
200 if (! a[$0]) {
201 a[$0] = 1; print;
202 }
203 }' "$files2remove" | xargs rmdir -p 2>/dev/null
205 rm "$files2remove"
206 unset IFS
208 status
210 # [3/5] Post-remove commands
211 call_post_remove "$INSTALLED/$PACKAGE/receipt"
213 # [4/5] Update system databases
214 fl="$INSTALLED/$PACKAGE/files.list"; upd=0
216 fgrep /usr/share/applications/ "$fl" | fgrep -q .desktop && udesk='yes'
217 fgrep -q /usr/share/mime "$fl" && umime='yes'
218 fgrep -q /usr/share/icon/hicolor "$fl" && uicon='yes'
219 fgrep -q /usr/share/glib-2.0/schemas "$fl" && uschm='yes'
220 fgrep /usr/lib/gdk-pixbuf "$fl" | fgrep -q .so && upixb='yes'
221 fgrep -q /lib/modules "$fl" && ukrnl='yes'
223 if [ -n "$udesk$umime$uicon$uschm$upixb$ukrnl" ]; then
224 action 'Update system databases...'
225 upd=1
226 fi
228 # package 'desktop-file-utils'
229 [ -n "$udesk" ] && chroot "$root/" /usr/bin/update-desktop-database /usr/share/applications 2>/dev/null
230 # package 'shared-mime-info'
231 [ -n "$umime" ] && chroot "$root/" /usr/bin/update-mime-database /usr/share/mime
232 # packages 'gtk+', 'gtk+3'
233 [ -n "$uicon" ] && chroot "$root/" /usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor
234 # package 'glib'
235 # hide messages like next because they are unresolved (we may to patch glib to hide them, almost the same)
236 # warning: Schema '*' has path '*'. Paths starting with '/apps/', '/desktop/' or '/system/' are deprecated.
237 [ -n "$uschm" ] && chroot "$root/" /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas 2>&1 | fgrep -v '/apps/'
238 # package 'gdk-pixbuf'
239 [ -n "$upixb" ] && chroot "$root/" /usr/bin/gdk-pixbuf-query-loaders --update-cache
240 # packages 'busybox', 'kmod', 'depmod'
241 [ -n "$ukrnl" ] && grep '/lib/modules' "$fl" | cut -d'/' -f4 | uniq | xargs chroot "$root/" /sbin/depmod -a
243 [ "$upd" -eq 1 ] && status
246 # [5/5] Remove package receipt and remove it from databases
247 action 'Removing package receipt...'
248 rm -rf "$INSTALLED/$PACKAGE"
249 sed -i "/ $PACKAGE-$VERSION$EXTRAVERSION.tazpkg$/d" "$PKGS_DB/installed.$SUM"
250 sed -i "/^$PACKAGE /d" "$PKGS_DB/installed.info"
251 status
253 footer "$(_ 'Package "%s" (%s) removed.' "$PACKAGE" "$VERSION$EXTRAVERSION")"
255 # Log this activity
256 log_pkg Removed
258 # Stop if non-interactive mode and no --auto option
259 if ! im && [ -z "$auto" ]; then exit 0; fi
261 # Process dependent packages
262 if [ -n "$ALTERED" ]; then
263 if [ -n "$auto" ]; then
264 answer=0
265 else
266 confirm "$(_ 'Remove packages depending on package "%s"? (y/N)' "$PACKAGE")"
267 answer=$?
268 fi
269 if [ "$answer" -eq 0 ]; then
270 for i in $ALTERED; do
271 if [ -d "$INSTALLED/$i" ]; then
272 tazpkg remove $i
273 fi
274 done
275 fi
276 fi
278 # Process changed packages
279 if [ -n "$REFRESH" ]; then
280 if [ -n "$auto" ]; then
281 answer=0
282 else
283 confirm "$(_ 'Reinstall packages modified by package "%s"? (y/N)' "$PACKAGE")"
284 answer=$?
285 fi
286 if [ "$answer" -eq 0 ]; then
287 for i in $REFRESH; do
288 if [ "$(wc -l < "$INSTALLED/$i")" -gt 1 ]; then
289 _ 'Package "%s" was modified by "%s" and other packages. It will not be reinstalled.' \
290 "${i%/modifiers}" "$PACKAGE"
291 _ 'Check "%s" for reinstallation.' "$INSTALLED/$i"
293 continue
294 fi
295 rm -r "$INSTALLED/$i"
296 tazpkg get-install ${i%/modifiers} --forced
297 done
298 fi
299 fi