You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.3 KiB
127 lines
3.3 KiB
#!/usr/bin/env bash |
|
set -e |
|
|
|
# --print: avoid dependency on environment |
|
optPrint= |
|
if [ "$1" == "--print" ]; then |
|
optPrint=true |
|
shift |
|
fi |
|
|
|
if [ "$#" != 1 ] && [ "$#" != 2 ]; then |
|
cat <<-EOF |
|
Usage: $0 [--print] commit-spec [commit-spec] |
|
You need to be in a git-controlled nixpkgs tree. |
|
The current state of the tree will be used if the second commit is missing. |
|
EOF |
|
exit 1 |
|
fi |
|
|
|
# A slightly hacky way to get the config. |
|
parallel="$(echo 'config.rebuild-amount.parallel or false' | nix-repl . 2>/dev/null \ |
|
| grep -v '^\(nix-repl.*\)\?$' | tail -n 1 || true)" |
|
|
|
echo "Estimating rebuild amount by counting changed Hydra jobs." |
|
|
|
toRemove=() |
|
|
|
cleanup() { |
|
rm -rf "${toRemove[@]}" |
|
} |
|
trap cleanup EXIT SIGINT SIGQUIT ERR |
|
|
|
MKTEMP='mktemp --tmpdir nix-rebuild-amount-XXXXXXXX' |
|
|
|
nixexpr() { |
|
cat <<-EONIX |
|
let |
|
lib = import $1/lib; |
|
hydraJobs = import $1/pkgs/top-level/release.nix |
|
# Compromise: accuracy vs. resources needed for evaluation. |
|
{ supportedSystems = cfg.systems or [ "x86_64-linux" "x86_64-darwin" ]; }; |
|
cfg = (import $1 {}).config.rebuild-amount or {}; |
|
|
|
recurseIntoAttrs = attrs: attrs // { recurseForDerivations = true; }; |
|
|
|
# hydraJobs leaves recurseForDerivations as empty attrmaps; |
|
# that would break nix-env and we also need to recurse everywhere. |
|
tweak = lib.mapAttrs |
|
(name: val: |
|
if name == "recurseForDerivations" then true |
|
else if lib.isAttrs val && val.type or null != "derivation" |
|
then recurseIntoAttrs (tweak val) |
|
else val |
|
); |
|
|
|
# Some of these contain explicit references to platform(s) we want to avoid; |
|
# some even (transitively) depend on ~/.nixpkgs/config.nix (!) |
|
blacklist = [ |
|
"tarball" "metrics" "manual" |
|
"darwin-tested" "unstable" "stdenvBootstrapTools" |
|
"moduleSystem" "lib-tests" # these just confuse the output |
|
]; |
|
|
|
in |
|
tweak (builtins.removeAttrs hydraJobs blacklist) |
|
EONIX |
|
} |
|
|
|
# Output packages in tree $2 that weren't in $1. |
|
# Changing the output hash or name is taken as a change. |
|
# Extra nix-env parameters can be in $3 |
|
newPkgs() { |
|
# We use files instead of pipes, as running multiple nix-env processes |
|
# could eat too much memory for a standard 4GiB machine. |
|
local -a list |
|
for i in 1 2; do |
|
local l="$($MKTEMP)" |
|
list[$i]="$l" |
|
toRemove+=("$l") |
|
|
|
local expr="$($MKTEMP)" |
|
toRemove+=("$expr") |
|
nixexpr "${!i}" > "$expr" |
|
|
|
nix-env -f "$expr" -qaP --no-name --out-path --show-trace $3 \ |
|
| sort > "${list[$i]}" & |
|
|
|
if [ "$parallel" != "true" ]; then |
|
wait |
|
fi |
|
done |
|
|
|
wait |
|
comm -13 "${list[@]}" |
|
} |
|
|
|
# Prepare nixpkgs trees. |
|
declare -a tree |
|
for i in 1 2; do |
|
if [ -n "${!i}" ]; then # use the given commit |
|
dir="$($MKTEMP -d)" |
|
tree[$i]="$dir" |
|
toRemove+=("$dir") |
|
|
|
git clone --shared --no-checkout --quiet . "${tree[$i]}" |
|
(cd "${tree[$i]}" && git checkout --quiet "${!i}") |
|
else #use the current tree |
|
tree[$i]="$(pwd)" |
|
fi |
|
done |
|
|
|
newlist="$($MKTEMP)" |
|
toRemove+=("$newlist") |
|
# Notes: |
|
# - the evaluation is done on x86_64-linux, like on Hydra. |
|
# - using $newlist file so that newPkgs() isn't in a sub-shell (because of toRemove) |
|
newPkgs "${tree[1]}" "${tree[2]}" '--argstr system "x86_64-linux"' > "$newlist" |
|
|
|
# Hacky: keep only the last word of each attribute path and sort. |
|
sed -n 's/\([^. ]*\.\)*\([^. ]*\) .*$/\2/p' < "$newlist" \ |
|
| sort | uniq -c |
|
|
|
if [ -n "$optPrint" ]; then |
|
echo |
|
cat "$newlist" |
|
fi |
|
|
|
|