tazpkg diff modules/remove @ rev 857
remove: speed up to a hundred times
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Thu Nov 12 20:13:00 2015 +0200 (2015-11-12) |
parents | b6daeaa95431 |
children | b278bf56267b |
line diff
1.1 --- a/modules/remove Tue Oct 20 10:24:52 2015 +0300 1.2 +++ b/modules/remove Thu Nov 12 20:13:00 2015 +0200 1.3 @@ -13,25 +13,6 @@ 1.4 1.5 1.6 1.7 -remove_with_path() { 1.8 - # Avoid dirname errors by checking for argument. 1.9 - [ -n "$1" ] || return 1.10 - 1.11 - local dir 1.12 - rm -f $1 2>/dev/null 1.13 - dir="$1" 1.14 - while [ "$dir" != "/" ]; do 1.15 - dir="$(dirname "$dir")" 1.16 - rmdir "$dir" 2>/dev/null || break 1.17 - done 1.18 -} 1.19 - 1.20 - 1.21 -grepesc() { 1.22 - sed 's/\[/\\[/g' 1.23 -} 1.24 - 1.25 - 1.26 # Log activity 1.27 1.28 log_pkg() { 1.29 @@ -126,22 +107,74 @@ 1.30 1.31 # [2/4] Removing files 1.32 action 'Removing all files installed...' 1.33 + 1.34 +# NOTE: package 'faenza-icon-theme' install time: 12s; removing time ~ 11min on my system o_O 1.35 +# After optimization: 6s! (Long) for-loops are (big) evil ;) 1.36 + 1.37 +# NOTE: many packages contains filenames with spaces: 1.38 +# lzcat /var/lib/tazpkg/files.list.lzma | awk -F" " '{if(NF>2)print $1}' | sed 's|:$||' | uniq 1.39 +# Redefine IFS to only-new-line field separator: 1.40 +IFS=$'\n' 1.41 + 1.42 +files2remove="$(mktemp)" 1.43 +dirs2remove="$(mktemp)" 1.44 + 1.45 +debug '\nDetermine which files to remove...' 1.46 if [ -f "$INSTALLED/$PACKAGE/modifiers" ]; then 1.47 - for file in $(cat "$INSTALLED/$PACKAGE/files.list"); do 1.48 - for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do 1.49 - [ -f "$INSTALLED/$mod/files.list" ] && \ 1.50 - [ $(grep "^$(echo $file | grepesc)$" "$INSTALLED/$mod/files.list" | wc -l) -gt 1 ] && \ 1.51 - continue 2 1.52 - done 1.53 - debug "remove_with_path ($root$file)" 1.54 - remove_with_path "$root$file" 1.55 + debug ' (modifiers detected)' 1.56 + 1.57 + mods="$(mktemp)" 1.58 + for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do 1.59 + cat "$INSTALLED/$mod/files.list" >> "$mods" 2>/dev/null 1.60 done 1.61 + 1.62 + awk -vroot="$root" -vfl="$INSTALLED/$PACKAGE/files.list" ' 1.63 + { 1.64 + if (FILENAME == fl) 1.65 + f[$0] = 1; 1.66 + else 1.67 + f[$0] = ""; 1.68 + } 1.69 + END { 1.70 + for (i in f) { 1.71 + if (f[i] == 1) printf "%s%s\n", root, i; 1.72 + } 1.73 + }' "$INSTALLED/$PACKAGE/files.list" "$mods" > "$files2remove" 1.74 + rm "$mods" 1.75 else 1.76 - for file in $(cat "$INSTALLED/$PACKAGE/files.list"); do 1.77 - debug "remove_with_path ($root$file)" 1.78 - remove_with_path "$root$file" 1.79 + debug ' (modifiers not detected)' 1.80 + 1.81 + awk -vroot="$root" '{ printf "%s%s\n", root, $0; }' \ 1.82 + "$INSTALLED/$PACKAGE/files.list" > "$files2remove" 1.83 +fi 1.84 + 1.85 +debug 'Removing files...' 1.86 +xargs rm -f < "$files2remove" 1.87 + 1.88 +debug 'Determine which folders to remove...' 1.89 +awk ' 1.90 +BEGIN { 1.91 + FS = "/"; OFS = "/"; 1.92 +} 1.93 +{ 1.94 + # removing filename beyond the last "/" 1.95 + $NF = ""; 1.96 + if (! a[$0]) { 1.97 + a[$0] = 1; print; 1.98 + } 1.99 +}' "$files2remove" | sed 's|/$||' > "$dirs2remove" 1.100 + 1.101 +debug 'Removing folders...' 1.102 +for dir2r in $(cat "$dirs2remove"); do 1.103 + dir="$dir2r" 1.104 + while [ -n "$dir" ]; do 1.105 + rmdir "$dir" 2>/dev/null || break 1.106 + dir="${dir%/*}" 1.107 done 1.108 -fi 1.109 +done 1.110 +rm "$files2remove" "$dirs2remove" 1.111 +unset IFS 1.112 + 1.113 status 1.114 1.115 # [3/4] Post-remove commands