Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

stackrpms-diff: a complex example

I maintain packages for a number of projects. Some of them are redressings of existing packages by other netizens. My best example is waterfox-g (upstream by hawkeye116477).

I like to maintain a patch that shows the differences between the upstream and my work. This is for transparency, as well as to show the differences so I can recreate those differences for the next version of the package. I don't version-control my debian/ directory in the proper way. I've been chided for this before, but I understand this janky way and you are welcome to re-do my work the correct way!

For a package like waterfox-g where I drop the -kpe ending because I don't use KDE and company (just not my style; they seem nicer than gnomes in general though), some of the filenames change too, which messes up a diff. So here is my complex (original in my scm). files/2024/listings/ (Source)

# Startdate: 2024-01-25-5 15:11
# Reference: scite/
# Usage: stackrpms/waterfox-g/ | vi -
# Purpose: handle the renamed files because of dropping the -kpe suffix
cd ~/dev
# do diff color=always if this is going to a terminal
\test -c /proc/$$/fd/1 && _diff_color="always"
{ test -n "${DIFF_COLOR}" || test -n "${DIFF_COLORS}" ; } && { _diff_color="always" ; }
diff -x '.*.swp' \
   --exclude-from="${right}/../diff-excludes" \
   --color="${_diff_color}" \
   -aur "${left}" "${right}"
for word in dirs dsc install links lintian-overrides manpages postinst postrm preinst prerm links ;
   _result="$( diff --color="${_diff_color}" -aur "${left}/waterfox-g-kpe.${word}" "${right}/waterfox-g.${word}" )"
   test -n "${_result}" && {
      echo diff -aur "${left}/waterfox-g-kpe.${word}" "${right}/waterfox-g.${word}"
      echo "${_result}"

Random notes on this cool script:

I have a separate file, diff-excludes that lists all the old and new filenames to exclude from the first diff, one per line. I didn't want to just have a dozen -x FILENAME entries because that clutters the otherwise useful output of the long command, with the full command line before each diff entry.

I probably need to come up with a programmatic way to generate this from line 17, but I haven't done that yet.

Line 11 escapes the test so it uses the executable test and not any possible built-in. I know it forks a new process and all that, but I'd rather not depend on a bash or other shell built-in.

I do my own stdout evaluation to determine color. Half the time, I'm running the command in a terminal, and the other half the time I'm sending it to a file to then view with $EDITOR (guess which one). So I wrote all this extra logic to handle adding or excluding the color.

If anybody has a better method for diffing two directories that experiences file renames (with possible content changes too; that's why I'm running the diff!), please let me know.