copy-firmware.sh: flesh out and fix dedup-firmware.sh

Flesh out the de-duplication logic in separate script. The copy-firmware.sh is
already complex enough and de-duplication doesn't really fit in there.

In the process we migrate away from the open-coded `ln --relative`. We also
avoid touching symlinks, which are not created by rdfind. Otherwise we end up
"fixing" the folder to folder symlinks (created earlier in the process) and
things explode.

As result we also get a few bonuses:
 - the COPYOPTS shell injection is gone - the variable was never used
 - people can dedup as separate step if/when they choose to do so

Aside: based on the noise in git log and around distros ... I'm wondering if
having the de-duplication as opt-in, would have been better. Is it too late to
change or the ship has sailed?

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Emil Velikov 2024-09-22 16:21:44 +01:00 committed by Mario Limonciello
parent cc4c1fccb0
commit ee8c336ab3
4 changed files with 58 additions and 27 deletions

View File

@ -26,21 +26,22 @@ deb:
rpm: rpm:
./build_packages.py --rpm ./build_packages.py --rpm
install: install: install-nodedup
install -d $(DESTDIR)$(FIRMWAREDIR) ./dedup-firmware.sh $(DESTDIR)$(FIRMWAREDIR)
./copy-firmware.sh $(COPYOPTS) $(DESTDIR)$(FIRMWAREDIR)
install-nodedup: install-nodedup:
install -d $(DESTDIR)$(FIRMWAREDIR) install -d $(DESTDIR)$(FIRMWAREDIR)
./copy-firmware.sh --ignore-duplicates $(DESTDIR)$(FIRMWAREDIR) ./copy-firmware.sh $(DESTDIR)$(FIRMWAREDIR)
install-xz: install-xz:
install -d $(DESTDIR)$(FIRMWAREDIR) install -d $(DESTDIR)$(FIRMWAREDIR)
./copy-firmware.sh --xz $(DESTDIR)$(FIRMWAREDIR) ./copy-firmware.sh --xz $(DESTDIR)$(FIRMWAREDIR)
./dedup-firmware.sh $(DESTDIR)$(FIRMWAREDIR)
install-zst: install-zst:
install -d $(DESTDIR)$(FIRMWAREDIR) install -d $(DESTDIR)$(FIRMWAREDIR)
./copy-firmware.sh --zstd $(DESTDIR)$(FIRMWAREDIR) ./copy-firmware.sh --zstd $(DESTDIR)$(FIRMWAREDIR)
./dedup-firmware.sh $(DESTDIR)$(FIRMWAREDIR)
clean: clean:
rm -rf release dist rm -rf release dist

View File

@ -91,6 +91,7 @@ def main():
"contrib/templates/debian.copyright", "contrib/templates/debian.copyright",
"contrib/templates/rpm.spec", "contrib/templates/rpm.spec",
"copy-firmware.sh", "copy-firmware.sh",
"dedup-firmware.sh",
] ]
) )
known_prefixes = set(name for name in whence_list if name.endswith("/")) known_prefixes = set(name for name in whence_list if name.endswith("/"))

View File

@ -9,7 +9,6 @@ prune=no
# shellcheck disable=SC2209 # shellcheck disable=SC2209
compress=cat compress=cat
compext= compext=
skip_dedup=0
while test $# -gt 0; do while test $# -gt 0; do
case $1 in case $1 in
@ -45,11 +44,6 @@ while test $# -gt 0; do
shift shift
;; ;;
--ignore-duplicates)
skip_dedup=1
shift
;;
-*) -*)
if test "$compress" = "cat"; then if test "$compress" = "cat"; then
echo "ERROR: unknown command-line option: $1" echo "ERROR: unknown command-line option: $1"
@ -75,13 +69,6 @@ if [ -z "$destdir" ]; then
exit 1 exit 1
fi fi
if ! command -v rdfind >/dev/null; then
if [ "$skip_dedup" != 1 ]; then
echo "ERROR: rdfind is not installed. Pass --ignore-duplicates to skip deduplication"
exit 1
fi
fi
# shellcheck disable=SC2162 # file/folder name can include escaped symbols # shellcheck disable=SC2162 # file/folder name can include escaped symbols
grep -E '^(RawFile|File):' WHENCE | sed -E -e 's/^(RawFile|File): */\1 /;s/"//g' | while read k f; do grep -E '^(RawFile|File):' WHENCE | sed -E -e 's/^(RawFile|File): */\1 /;s/"//g' | while read k f; do
test -f "$f" || continue test -f "$f" || continue
@ -95,16 +82,6 @@ grep -E '^(RawFile|File):' WHENCE | sed -E -e 's/^(RawFile|File): */\1 /;s/"//g'
fi fi
done done
if [ "$skip_dedup" != 1 ] ; then
$verbose "Finding duplicate files"
rdfind -makesymlinks true -makeresultsfile false "$destdir" >/dev/null
find "$destdir" -type l | while read -r l; do
target="$(realpath "$l")"
$verbose "Correcting path for $l"
ln -fs "$(realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target")" "$l"
done
fi
# shellcheck disable=SC2162 # file/folder name can include escaped symbols # shellcheck disable=SC2162 # file/folder name can include escaped symbols
grep -E '^Link:' WHENCE | sed -e 's/^Link: *//g;s/-> //g' | while read f d; do grep -E '^Link:' WHENCE | sed -e 's/^Link: *//g;s/-> //g' | while read f d; do
if test -L "$f$compext"; then if test -L "$f$compext"; then

52
dedup-firmware.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Deduplicate files in a given destdir
#
err() {
echo "ERROR: $*"
exit 1
}
verbose=:
destdir=
while test $# -gt 0; do
case $1 in
-v | --verbose)
# shellcheck disable=SC2209
verbose=echo
;;
*)
if test -n "$destdir"; then
err "unknown command-line options: $*"
fi
destdir="$1"
shift
;;
esac
done
if test -z "$destdir"; then
err "destination directory was not specified."
fi
if ! test -d "$destdir"; then
err "provided directory does not exit."
fi
if ! command -v rdfind >/dev/null; then
err "rdfind is not installed."
fi
$verbose "Finding duplicate files"
rdfind -makesymlinks true -makeresultsfile true "$destdir" >/dev/null
grep DUPTYPE_WITHIN_SAME_TREE results.txt | grep -o "$destdir.*" | while read -r l; do
target="$(realpath "$l")"
$verbose "Correcting path for $l"
ln --force --symbolic --relative "$target" "$l"
done
rm results.txt