1#!/usr/bin/env nix-shell
2#!nix-shell -i bash -p git jq
3
4# Outputs a list of maintainers that would be pinged across two nixpkgs revisions.
5# Authors:
6# Morgan Jones (@numinit)
7# Tristan Ross (@RossComputerGuy)
8
9set -euo pipefail
10
11if [ $# -lt 2 ]; then
12 echo "Usage: $0 <rev-from> <rev-to>" >&2
13 exit 1
14fi
15
16repo="$(git rev-parse --show-toplevel)"
17system="$(nix-instantiate --eval --expr builtins.currentSystem)"
18rev1="$(git -C "$repo" rev-parse "$1")"
19rev2="$(git -C "$repo" rev-parse "$2")"
20
21echo "Touched files:" >&2
22git -C "$repo" diff --name-only "$rev1" "$rev2" \
23 | jq --raw-input --slurp 'split("\n")[:-1]' | tee "$TMPDIR/touched-files.json" >&2
24
25# Runs an eval in the given worktree, outputting the path to $TMPDIR/$1.path.
26# $1: The revision SHA.
27eval_in_worktree() (
28 mkdir -p .worktree
29 local rev="$1"
30 local tree=".worktree/$rev"
31 if [ ! -d "$tree" ]; then
32 git -C "$repo" worktree add -f -d "$tree" "$rev" >&2
33 fi
34 cd "$tree"
35
36 local workdir="$TMPDIR/$rev"
37 rm -rf "$workdir"
38 mkdir -p "$workdir"
39
40 nix-build ci -A eval.attrpathsSuperset -o "$workdir/paths" >&2
41 mkdir -p "$workdir/intermediates"
42 nix-build ci -A eval.singleSystem \
43 --arg evalSystem "$system" \
44 --arg attrpathFile "$workdir/paths/paths.json" \
45 --arg chunkSize ${CHUNK_SIZE:-10000} \
46 -o "$workdir/intermediates/.intermediate-1" >&2
47
48 # eval.combine nix-build needs a directory, not a symlink
49 cp -RL "$workdir/intermediates/.intermediate-1" "$workdir/intermediates/intermediate-1"
50 chmod -R +w "$workdir/intermediates/intermediate-1"
51 rm -rf "$workdir/intermediates/.intermediate-1"
52
53 nix-build ci -A eval.combine \
54 --arg resultsDir "$workdir/intermediates" \
55 -o "$workdir/result" >&2
56)
57
58eval_in_worktree "$rev1" &
59pid1=$!
60eval_in_worktree "$rev2" &
61pid2=$!
62
63wait $pid1
64wait $pid2
65
66path1="$TMPDIR/$rev1"
67path2="$TMPDIR/$rev2"
68
69# Use the repo this script was executed in to get accurate maintainer info
70nix-build "$repo/ci" -A eval.compare \
71 --arg beforeResultDir "$path1/result" \
72 --arg afterResultDir "$path2/result" \
73 --arg touchedFilesJson "$TMPDIR/touched-files.json" \
74 --arg byName true \
75 -o comparison
76
77echo "Pinged maintainers (check $repo/comparison for more details)" >&2
78jq < comparison/maintainers.json