void-packages/common/xbps-src/shutils/purge_distfiles.sh
q66 7febf540a9 shutils/purge_distfiles.sh: fix purging of multiple distfiles
Previously, xbps-src would try to find checksums in template files
and not purge those found but it actually ignored everything that
had the checksums specified on multiple lines.

The reason for this is that the bash 'read' builtin reads until it
finds a newline, and if you specify multiple checksums on multiple
lines rather than on one line it would ignore all but the first.

Fix this by replacing newlines with spaces, so that it can properly
read all checksums into an array.
2019-12-23 00:53:29 +01:00

86 lines
2.2 KiB
Bash

# Scan srcpkgs/*/template for hashes and distfiles to determine
# obsolete sources/by_sha256 files and their corresponding
# sources/<pkgname>-<version> files that can be purged
purge_distfiles() {
readonly HASHLEN=64
if [ -z "$XBPS_SRCDISTDIR" ]; then
msg_error "The variable \$XBPS_SRCDISTDIR is not set."
exit 1
fi
#
# Scan all templates for their current distfiles and checksums (hashes)
#
declare -A my_hashes
templates=(srcpkgs/*/template)
max=${#templates[@]}
cur=0
if [ -z "$max" ]; then
msg_error "No srcpkgs/*/template files found. Wrong working directory?"
exit 1
fi
percent=-1
for template in ${templates[@]}; do
pkg=${template#*/}
pkg=${pkg%/*}
if [ ! -L "srcpkgs/$pkg" ]; then
checksum="$(grep -Ehrow [0-9a-f]{$HASHLEN} ${template}|sort|uniq|tr '\n' ' ')"
read -a _my_hashes <<< ${checksum}
i=0
while [ -n "${_my_hashes[$i]}" ]; do
hash="${_my_hashes[$i]}"
[ -z "${my_hashes[$hash]}" ] && my_hashes[$hash]=$template
i=$((i + 1))
done
fi
cur=$((cur + 1))
pnew=$((100 * cur / max))
if [ $pnew -ne $percent ]; then
percent=$pnew
printf "\rScanning templates : %3d%% (%d/%d)" $percent $cur $max
fi
done
echo
echo "Number of hashes : ${#my_hashes[@]}"
#
# Collect inodes of all distfiles in $XBPS_SRCDISTDIR
#
declare -A inodes
distfiles=($XBPS_SRCDISTDIR/*/*)
max=${#distfiles[@]}
if [ -z "$max" ]; then
msg_error "No distfiles files found in '$XBPS_SRCDISTDIR'"
exit 1
fi
cur=0
percent=-1
for distfile in ${distfiles[@]}; do
inode=$(stat "$distfile" --printf "%i")
if [ -z "${inodes[$inode]}" ]; then
inodes[$inode]="$distfile"
else
inodes[$inode]+="|$distfile"
fi
cur=$((cur + 1))
pnew=$((100 * cur / max))
if [ $pnew -ne $percent ]; then
percent=$pnew
printf "\rCollecting inodes : %3d%% (%d/%d)" $percent $cur $max
fi
done
echo
hashes=($XBPS_SRCDISTDIR/by_sha256/*)
for file in ${hashes[@]}; do
hash_distfile=${file##*/}
hash=${hash_distfile:0:$HASHLEN}
[ -n "${my_hashes[$hash]}" ] && continue
inode=$(stat "$file" --printf "%i")
echo "Obsolete $hash (inode: $inode)"
( IFS="|"; for f in ${inodes[$inode]}; do rm -vf "$f"; rmdir "${f%/*}" 2>/dev/null; done )
done
echo "Done."
}