#!/bin/bash set -euo pipefail shopt -s nullglob input="99-unsorted.sh" output="98-patches.sh" filestoremove="remove-these" truncate=1 mkdir -p patches while [[ $# -gt 0 ]]; do case "$1" in --no-trunc) truncate=0 ;; --in) input=$2 shift 1 ;; --out) output=$2 shift 1 ;; *) break ;; esac shift 1 done tmpfile=$(mktemp) [[ $truncate -eq 1 ]] && (echo -n >"$output") # empty output file to be rewritten echo "temp file is $tmpfile" while IFS= read -r line; do # Only process lines starting with "CopyFile " [[ "$line" =~ ^CopyFile[[:space:]]+/ ]] || { echo "$line" >>"$tmpfile" continue } path="${line#CopyFile }" path="${path%% *}" # remove any trailing args # Check ownership if ! info=$(pacman -Qo "$path" 2>/dev/null); then echo "WARN: Skipping $path: not owned by any package" >&2 echo "$line" >>"$tmpfile" continue fi # Example output: "/etc/pacman.conf is owned by pacman 5.1.3-1" pkg_name=$(awk '{print $(NF-1)}' <<<"$info") pkg_ver=$(awk '{print $NF}' <<<"$info") # Find package archive in cache archives=(/var/cache/pacman/pkg/${pkg_name}-${pkg_ver}-*.pkg.tar.zst) if ((${#archives[@]} == 0)); then echo "WARN: Cached package not found for $pkg_name-$pkg_ver" >&2 echo "$line" >>"$tmpfile" continue fi archive="${archives[0]}" # Create diff file name base=$(basename "$path") diff_file="patches/${pkg_name}_${base}.diff" # Relative path inside package archive relpath="${path#/}" # Generate diff if ! tar -xOf "$archive" "$relpath" 2>/dev/null | diff -u - "$path" > "$diff_file"; then echo "patch \"\$(GetPackageOriginalFile $pkg_name $path)\" ./$diff_file" >>"$output" echo "$path" >> $filestoremove echo "INFO: Added patch for $path" >&2 else rm -f "$diff_file" echo "INFO: No differences for $path" fi done <"$input" if ! diff -u --color=always "$input" "$tmpfile" 2>/dev/null; then : fi mv "$input" "$input.backup" mv "$tmpfile" "$input" echo echo "OK: All done. Patch commands written to $output"