at 22.05-pre 4.0 kB view raw
1#!/usr/bin/env bash 2set -e 3 4# --print: avoid dependency on environment 5optPrint= 6if [ "$1" == "--print" ]; then 7 optPrint=true 8 shift 9fi 10 11if [ "$#" != 1 ] && [ "$#" != 2 ]; then 12 cat <<EOF 13 Usage: $0 [--print] from-commit-spec [to-commit-spec] 14 You need to be in a git-controlled nixpkgs tree. 15 The current state of the tree will be used if the second commit is missing. 16 17 Examples: 18 effect of latest commit: 19 $ $0 HEAD^ 20 $ $0 --print HEAD^ 21 effect of the whole patch series for 'staging' branch: 22 $ $0 origin/staging staging 23EOF 24 exit 1 25fi 26 27# A slightly hacky way to get the config. 28parallel="$(echo 'config.rebuild-amount.parallel or false' | nix-repl . 2>/dev/null \ 29 | grep -v '^\(nix-repl.*\)\?$' | tail -n 1 || true)" 30 31echo "Estimating rebuild amount by counting changed Hydra jobs (parallel=${parallel:-unset})." 32 33toRemove=() 34 35cleanup() { 36 rm -rf "${toRemove[@]}" 37} 38trap cleanup EXIT SIGINT SIGQUIT ERR 39 40MKTEMP='mktemp --tmpdir nix-rebuild-amount-XXXXXXXX' 41 42nixexpr() { 43 cat <<EONIX 44 let 45 lib = import $1/lib; 46 hydraJobs = import $1/pkgs/top-level/release.nix 47 # Compromise: accuracy vs. resources needed for evaluation. 48 { supportedSystems = cfg.systems or [ "x86_64-linux" "x86_64-darwin" ]; }; 49 cfg = (import $1 {}).config.rebuild-amount or {}; 50 51 recurseIntoAttrs = attrs: attrs // { recurseForDerivations = true; }; 52 53 # hydraJobs leaves recurseForDerivations as empty attrmaps; 54 # that would break nix-env and we also need to recurse everywhere. 55 tweak = lib.mapAttrs 56 (name: val: 57 if name == "recurseForDerivations" then true 58 else if lib.isAttrs val && val.type or null != "derivation" 59 then recurseIntoAttrs (tweak val) 60 else val 61 ); 62 63 # Some of these contain explicit references to platform(s) we want to avoid; 64 # some even (transitively) depend on ~/.nixpkgs/config.nix (!) 65 blacklist = [ 66 "tarball" "metrics" "manual" 67 "darwin-tested" "unstable" "stdenvBootstrapTools" 68 "moduleSystem" "lib-tests" # these just confuse the output 69 ]; 70 71 in 72 tweak (builtins.removeAttrs hydraJobs blacklist) 73EONIX 74} 75 76# Output packages in tree $2 that weren't in $1. 77# Changing the output hash or name is taken as a change. 78# Extra nix-env parameters can be in $3 79newPkgs() { 80 # We use files instead of pipes, as running multiple nix-env processes 81 # could eat too much memory for a standard 4GiB machine. 82 local -a list 83 for i in 1 2; do 84 local l="$($MKTEMP)" 85 list[$i]="$l" 86 toRemove+=("$l") 87 88 local expr="$($MKTEMP)" 89 toRemove+=("$expr") 90 nixexpr "${!i}" > "$expr" 91 92 nix-env -f "$expr" -qaP --no-name --out-path --show-trace $3 \ 93 | sort > "${list[$i]}" & 94 95 if [ "$parallel" != "true" ]; then 96 wait 97 fi 98 done 99 100 wait 101 comm -13 "${list[@]}" 102} 103 104# Prepare nixpkgs trees. 105declare -a tree 106for i in 1 2; do 107 if [ -n "${!i}" ]; then # use the given commit 108 dir="$($MKTEMP -d)" 109 tree[$i]="$dir" 110 toRemove+=("$dir") 111 112 git clone --shared --no-checkout --quiet . "${tree[$i]}" 113 (cd "${tree[$i]}" && git checkout --quiet "${!i}") 114 else #use the current tree 115 tree[$i]="$(pwd)" 116 fi 117done 118 119newlist="$($MKTEMP)" 120toRemove+=("$newlist") 121# Notes: 122# - the evaluation is done on x86_64-linux, like on Hydra. 123# - using $newlist file so that newPkgs() isn't in a sub-shell (because of toRemove) 124newPkgs "${tree[1]}" "${tree[2]}" '--argstr system "x86_64-linux"' > "$newlist" 125 126# Hacky: keep only the last word of each attribute path and sort. 127sed -n 's/\([^. ]*\.\)*\([^. ]*\) .*$/\2/p' < "$newlist" \ 128 | sort | uniq -c 129 130if [ -n "$optPrint" ]; then 131 echo 132 cat "$newlist" 133fi