Skip to content

Commit dc6f5b5

Browse files
add show-aur-changes script
The script identifies all AUR packages which have been modified within a given time. The script also supports the needed plumbing and convenience functionality such as fetching fresh metadata and git mirror updates, showing effective per-package diffs and cloning the mono repository from scratch. Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Christian Heusel <christian@heusel.eu>
1 parent 4c74fc5 commit dc6f5b5

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

aur/show-aur-changes

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/bash
2+
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
AUR_REPO_URL="https://github.com/archlinux/aur"
6+
7+
set -euo pipefail
8+
9+
usage() {
10+
cat <<EOF
11+
Usage: $(basename "$0") [-d|--diff] [-f|--fetch] [-n|--days <n>] [-m|--meta <path>] [-p|--pattern <glob>] [-r|--repo <path>] [--clone <path>]
12+
13+
Find AUR packages modified within a time window whose branches contain changes
14+
to files matching a given glob pattern.
15+
16+
Options:
17+
-d, --diff Print the effective diff for each matched package
18+
-f, --fetch Sync the local mirror and metadata to the latest state before running
19+
-n, --days <n> Look-back window in days (default: 7)
20+
-m, --meta <path> Path to packages-meta-v1.json (default: packages-meta-v1.json in the aur repo root)
21+
-p, --pattern <glob> File pattern to inspect (default: *)
22+
-r, --repo <path> Path to the AUR git checkout (default: git repo of current directory)
23+
--clone <path> Clone the AUR mono repository to <path> and use it as the repo
24+
-h, --help Show this help text
25+
26+
Examples:
27+
$(basename "$0") --repo ~/Documents/shared_projects/aur --fetch --diff --days 1
28+
EOF
29+
}
30+
31+
SHOW_DIFF=0
32+
FETCH=0
33+
DAYS=7
34+
META_JSON=""
35+
PATTERN="*"
36+
REPO_ROOT=""
37+
CLONE_PATH=""
38+
while [[ "${1:-}" == -* ]]; do
39+
case "$1" in
40+
-d|--diff) SHOW_DIFF=1 ;;
41+
-f|--fetch) FETCH=1 ;;
42+
-n|--days) shift; DAYS="$1" ;;
43+
-m|--meta) shift; META_JSON="$1" ;;
44+
-p|--pattern) shift; PATTERN="$1" ;;
45+
-r|--repo) shift; REPO_ROOT="$1" ;;
46+
--clone) shift; CLONE_PATH="$1" ;;
47+
-h|--help) usage; exit 0 ;;
48+
*) echo "Unknown flag: $1" >&2; echo >&2; usage >&2; exit 1 ;;
49+
esac
50+
shift
51+
done
52+
53+
if [[ -n "$CLONE_PATH" ]]; then
54+
echo "Cloning AUR mono repository to $CLONE_PATH ..." >&2
55+
git clone "$AUR_REPO_URL" "$CLONE_PATH"
56+
REPO_ROOT="$CLONE_PATH"
57+
fi
58+
59+
REPO_ROOT="${REPO_ROOT:-"$(git rev-parse --show-toplevel)"}"
60+
META_JSON="${META_JSON:-"$REPO_ROOT/packages-meta-v1.json"}"
61+
62+
if [[ ! -f "$META_JSON" ]] && ! (( FETCH )); then
63+
echo "error: metadata file not found: $META_JSON" >&2
64+
echo "hint: run with --fetch to download it" >&2
65+
exit 1
66+
fi
67+
68+
if (( FETCH )); then
69+
echo "Updating git mirror ..." >&2
70+
git -C "$REPO_ROOT" fetch --all --prune
71+
echo "Fetching latest metadata from aur.archlinux.org ..." >&2
72+
curl -fsSL "https://aur.archlinux.org/packages-meta-v1.json.gz" \
73+
| gzip -d > "$META_JSON"
74+
echo "Saved to $META_JSON" >&2
75+
fi
76+
77+
# Compute the cutoff as unix timestamp
78+
CUTOFF=$(date -d "-${DAYS} days" +%s)
79+
80+
# Collect the unique PackageBases modified since CUTOFF
81+
mapfile -t PKGS < <(
82+
jq -r --argjson cutoff "$CUTOFF" \
83+
'[.[] | select(.LastModified >= $cutoff)] | map(.PackageBase) | unique | .[]' \
84+
"$META_JSON"
85+
)
86+
87+
echo "Packages modified in the last ${DAYS} day(s): ${#PKGS[@]}" >&2
88+
echo "File pattern: $PATTERN" >&2
89+
90+
# For each package, check if its branch has matching file changes since $CUTOFF
91+
SINCE_DATE=$(date -d "-${DAYS} days" --iso-8601=seconds)
92+
93+
for pkg in "${PKGS[@]}"; do
94+
# Check if the remote branch exists
95+
if ! git -C "$REPO_ROOT" rev-parse --verify "origin/$pkg" &>/dev/null; then
96+
echo "error: no remote branch for package '$pkg'" >&2
97+
exit 1
98+
fi
99+
100+
# Check if there are any commits matching $PATTERN for this package since $CUTOFF
101+
if git -C "$REPO_ROOT" log "origin/$pkg" --since="$SINCE_DATE" --name-only --format="" -- "$PATTERN" | grep -q .; then
102+
echo "$pkg"
103+
104+
if (( SHOW_DIFF )); then
105+
# Find the boundary commits for the range touching $PATTERN
106+
mapfile -t commits < <(
107+
git -C "$REPO_ROOT" log "origin/$pkg" --since="$SINCE_DATE" --format="%H" -- "$PATTERN"
108+
)
109+
newest="${commits[0]}"
110+
oldest="${commits[-1]}"
111+
# Diff from the parent of the oldest in-range commit (empty tree if root)
112+
if git -C "$REPO_ROOT" rev-parse "${oldest}^" &>/dev/null; then
113+
base="${oldest}^"
114+
else
115+
# So far this always outputs the magic value
116+
# '4b825dc642cb6eb9a060e54bf8d69288fbee4904', but instead of hardcoding
117+
# it we regenerate it each time to not rely on it
118+
#
119+
# https://stackoverflow.com/a/9766506
120+
base="$(git mktree < /dev/null)"
121+
fi
122+
git -C "$REPO_ROOT" diff "$base" "$newest" -- "$PATTERN"
123+
fi
124+
fi
125+
done

0 commit comments

Comments
 (0)