aboutsummaryrefslogtreecommitdiff
path: root/scripts/dot-local/bin/aconfmgr-patcher
blob: cbc9c93775ed60d5387a3389c710e5c5056af419 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/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"