Last active
October 19, 2025 15:01
-
-
Save pineapplehunter/42939b06bbf447d3ede6c658302990d2 to your computer and use it in GitHub Desktop.
nix bisect script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # bisects the package set on PKG | |
| # | |
| # Usage | |
| # 1. Copy this script to the root of nixpkgs as check.sh (do not commit!) | |
| # 2. Set the variable PKG to the package you want to bisect. use nixosTests.PKG for tests. | |
| # 3. Start git bisect with `git bisect start` and `git bisect good ...`, `git bisect bad ...` | |
| # 4. Run this bisect script with `git bisect run bash check.sh -A package [options]` | |
| # 5. Profit! | |
| set -euo pipefail | |
| usage () { | |
| echo "Usage: $0 [FILE] [-A ATTR] [-m|--mode quick|limit|build] [-n|--limit LIMIT]" | |
| echo "FILE : file used for evaluation. default.nix will be used by default." | |
| echo "-A,--attr ATTR : attribute used for bisect. for tests, use nixosTests.ATTR" | |
| echo "-m,--mode quick: skip every commit where dependency needs to be built" | |
| echo " limit: skip a commit if there are more than LIMIT amount of dependencies needed to build (default)" | |
| echo " build: build everything(often very slow)" | |
| echo "-n,--limit LIMIT: how many dependencies to allow building (only on limit mode)" | |
| echo "--fod : check a fixed output derivation. it will run a additional check build" | |
| echo "-v,--verbose : print verbose messages" | |
| } | |
| RED='\033[1;31m' | |
| GREEN='\033[1;32m' | |
| YELLOW='\033[1;33m' | |
| RESET='\033[0m' | |
| skip () { | |
| echo -e "${YELLOW}skip: $*${RESET}" >&2 | |
| exit 125 | |
| } | |
| fail () { | |
| echo -e "${RED}fail: $*${RESET}" >&2 | |
| exit 1 | |
| } | |
| if [[ $# == 0 ]]; then | |
| usage >&2 | |
| fail no arguments supplied | |
| fi | |
| cleanup () { | |
| rm -rf drvs.txt build-list.txt result-tmp* | |
| } | |
| trap cleanup EXIT | |
| ATTRS=() | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -A|--attr) | |
| ATTRS+=(-A "$2") | |
| shift 2 | |
| ;; | |
| -m|--mode) | |
| MODE=$2 | |
| shift 2 | |
| ;; | |
| -n|--limit) | |
| LIMIT=$2 | |
| shift 2 | |
| ;; | |
| --fod) | |
| FOD=1 | |
| shift | |
| ;; | |
| -v|--verbose) | |
| VERBOSE=1 | |
| shift | |
| ;; | |
| *) | |
| FILE=$1 | |
| shift | |
| ;; | |
| esac | |
| done | |
| VERBOSE=${VERBOSE:-0} | |
| if [[ $VERBOSE == 1 ]]; then | |
| set -x | |
| fi | |
| MODE=${MODE:-limit} | |
| LIMIT=${LIMIT:-20} | |
| FILE=${FILE:-default.nix} | |
| nix-instantiate "$FILE" "${ATTRS[@]}" --add-root result-tmp | \ | |
| xargs nix derivation show | \ | |
| jq ".[].inputDrvs | keys[]" -r |\ | |
| sed '/^\/nix\/store\//! s/^/\/nix\/store\//' > drvs.txt | |
| if [[ $VERBOSE == 1 ]]; then | |
| cat drvs.txt | |
| fi | |
| case "$MODE" in | |
| build) | |
| xargs nom-build --no-link < drvs.txt || skip dependency build failed | |
| ;; | |
| limit) | |
| xargs nix-build --no-link --dry-run < drvs.txt 2> build-list.txt || skip could not get build list | |
| if grep built build-list.txt > /dev/null; then | |
| BUILDS=$(grep built build-list.txt | grep -o '[0-9]\+' | head -n1 || echo 1) | |
| if [[ "$BUILDS" -lt "$LIMIT" ]]; then | |
| xargs nom-build --no-link < drvs.txt || skip dependency build failed | |
| else | |
| skip too many dependecies to build | |
| fi | |
| fi | |
| ;; | |
| quick) | |
| nix-build --no-link --dry-run < drvs.txt 2> build-list.txt || skip could not get build list | |
| grep built build-list.txt > /dev/null && skip dependency needs to be built | |
| ;; | |
| *) | |
| echo "ERROR: $MODE IS NOT IMPLEMENTED" >&2 | |
| ;; | |
| esac | |
| nom-build --no-link "$FILE" "${ATTRS[@]}" || fail build failed | |
| if [[ "${FOD:-0}" == 1 ]]; then | |
| nom-build --no-link --check "$FILE" "${ATTRS[@]}" || fail check build failed | |
| fi | |
| echo -e "${GREEN}Successfully built${RESET}" >&2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment