@@ -8,48 +8,64 @@ set -euo pipefail
88
99usage () {
1010 cat << EOF
11- Usage: $( basename " $0 " ) [-d|--diff] [-f|--fetch] [-n|--days <n>] [-m|--meta <path>] [-p|--pattern <glob>] [-r|--repo <path>] [--clone <path>]
11+ Usage: $( basename " $0 " ) [-d|--diff] [-f|--fetch] [-g|--grep <pattern>] [- n|--days <n>] [-m|--meta <path>] [-o|--output-dir <path>] [-p|--pattern <glob>] [-r|--repo <path>] [--clone <path>]
1212
1313Find AUR packages modified within a time window whose branches contain changes
1414to files matching a given glob pattern.
1515
1616Options:
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
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+ -g, --grep <pattern> Only include packages whose diff matches <pattern> (grep -E)
20+ -n, --days <n> Look-back window in days (default: 7)
21+ -m, --meta <path> Path to packages-meta-v1.json (default: packages-meta-v1.json in the aur repo root)
22+ -o, --output-dir <path> Write each package's diff to <path>/<package>.patch
23+ -p, --pattern <glob> File pattern to inspect (default: *)
24+ -r, --repo <path> Path to the AUR git checkout (default: git repo of current directory)
25+ --clone <path> Clone the AUR mono repository to <path> and use it as the repo
26+ -h, --help Show this help text
2527
2628Examples:
2729 $( basename " $0 " ) --repo ~/Documents/shared_projects/aur --fetch --diff --days 1
30+ $( basename " $0 " ) --repo ~/Documents/shared_projects/aur --output-dir ~/patches --days 1
31+ $( basename " $0 " ) --repo ~/Documents/shared_projects/aur --grep "npm install" --days 7
2832EOF
2933}
3034
3135SHOW_DIFF=0
3236FETCH=0
37+ GREP_PATTERN=" "
3338DAYS=7
3439META_JSON=" "
40+ OUTPUT_DIR=" "
3541PATTERN=" *"
3642REPO_ROOT=" "
3743CLONE_PATH=" "
3844while [[ " ${1:- } " == -* ]]; do
3945 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 ;;
46+ -d|--diff) SHOW_DIFF=1 ;;
47+ -f|--fetch) FETCH=1 ;;
48+ -g|--grep) shift ; GREP_PATTERN=" $1 " ;;
49+ -n|--days) shift ; DAYS=" $1 " ;;
50+ -m|--meta) shift ; META_JSON=" $1 " ;;
51+ -o|--output-dir) shift ; OUTPUT_DIR=" $1 " ;;
52+ -p|--pattern) shift ; PATTERN=" $1 " ;;
53+ -r|--repo) shift ; REPO_ROOT=" $1 " ;;
54+ --clone) shift ; CLONE_PATH=" $1 " ;;
55+ -h|--help) usage; exit 0 ;;
4856 * ) echo " Unknown flag: $1 " >&2 ; echo >&2 ; usage >&2 ; exit 1 ;;
4957 esac
5058 shift
5159done
5260
61+ if [[ -n " $OUTPUT_DIR " ]]; then
62+ if [[ -e " $OUTPUT_DIR " && ! -d " $OUTPUT_DIR " ]]; then
63+ echo " error: output-dir '$OUTPUT_DIR ' exists but is not a directory" >&2
64+ exit 1
65+ fi
66+ mkdir -p " $OUTPUT_DIR "
67+ fi
68+
5369if [[ -n " $CLONE_PATH " ]]; then
5470 echo " Cloning AUR mono repository to $CLONE_PATH ..." >&2
5571 git clone " $AUR_REPO_URL " " $CLONE_PATH "
@@ -98,28 +114,44 @@ for pkg in "${PKGS[@]}"; do
98114 fi
99115
100116 # 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 "
117+ if ! git -C " $REPO_ROOT " log " origin/$pkg " --since=" $SINCE_DATE " --name-only --format=" " -- " $PATTERN " | grep -q . ; then
118+ continue
119+ fi
120+
121+ diff_output= " "
122+ if (( SHOW_DIFF )) || [[ -n " $OUTPUT_DIR " ]] || [[ -n " $GREP_PATTERN " ]] ; then
123+ # Find the boundary commits for the range touching $ PATTERN
124+ mapfile -t commits < <(
125+ git -C " $REPO_ROOT " log " origin/ $pkg " --since =" $SINCE_DATE " --format= " %H " -- " $PATTERN "
126+ )
127+ newest= " ${commits[0]} "
128+ oldest= " ${commits[-1]} "
129+ # Diff from the parent of the oldest in-range commit (empty tree if root)
130+ if git -C " $REPO_ROOT " rev-parse " ${oldest} ^ " & > /dev/null ; then
131+ base= " ${oldest} ^ "
132+ else
133+ # So far this always outputs the magic value
134+ # '4b825dc642cb6eb9a060e54bf8d69288fbee4904', but instead of hardcoding
135+ # it we regenerate it each time to not rely on it
136+ #
137+ # https://stackoverflow.com/a/9766506
138+ base= " $( git -C " $REPO_ROOT " mktree < /dev/null ) "
123139 fi
140+ diff_output=$( git -C " $REPO_ROOT " diff " $base " " $newest " -- " $PATTERN " )
141+ fi
142+
143+ # Match against grep pattern if specified
144+ if [[ -n " $GREP_PATTERN " ]] && ! grep -qE " $GREP_PATTERN " <<< " $diff_output" ; then
145+ continue
146+ fi
147+
148+ echo " $pkg "
149+
150+ if (( SHOW_DIFF )) && [[ -n " $OUTPUT_DIR " ]]; then
151+ printf ' %s' " $diff_output " | tee " $OUTPUT_DIR /$pkg .patch"
152+ elif (( SHOW_DIFF )) ; then
153+ printf ' %s' " $diff_output "
154+ elif [[ -n " $OUTPUT_DIR " ]]; then
155+ printf ' %s' " $diff_output " > " $OUTPUT_DIR /$pkg .patch"
124156 fi
125157done
0 commit comments