#!/usr/bin/env nix-shell #!nix-shell -i bash -p nix-update usage() { echo "update: update rev/hash for one or more packages" echo "usage: update [options] [attr-path]" echo "" echo "options:" echo "- --dry-run" echo "- --verbose" echo "" echo "examples:" echo "- update nixpkgs: update only the nixpkgs input" echo "- update sane: update every package under the 'sane' attribute" echo "- update: update everything i know how to update" exit 1 } warn() { echo "$@" } info() { echo "$@" } debug() { if [ -n "$verbose" ]; then echo "$@" fi } hasEffect() { if [ -n "$dryRun" ]; then echo "dry-run: skip $@" else eval "$@" fi } # usage: getPkgs outVar prefix getPkgs() { local -n attrsArr="$1" local attrPrefix="$2" if [ -z "$attrPrefix" ]; then attrPrefix=sane fi local attrs="$(nix-env -f . --query --available --attr-path --no-name -A $attrPrefix)" attrsArr+=($attrs) } updateOnePkg() { local attrPath="$1" if [[ "$attrPath" =~ ^"$ignore" ]]; then warn "ignoring $attrPath" return fi local updateScript="$(nix eval --raw -f . $attrPath.passthru.updateScript --apply 'builtins.concatStringsSep "'" "'"')" if [ -z "$updateScript" ]; then warn "don't know how to update '$attrPath'" return fi # make sure everything needed to invoke the script actually exists on disk nix-build -A "$attrPath.passthru.updateScript" || true local UPDATE_NIX_NAME="$(nix eval --raw -f . $attrPath.name)" local UPDATE_NIX_PNAME="$(nix eval --raw -f . $attrPath.pname)" local UPDATE_NIX_OLD_VERSION="$(nix eval --raw -f . $attrPath.version)" info "updating: '$attrPath'" debug "$updateScript" # we lose spaces inside the exec args... could `nix eval` without `--raw` to fix that. UPDATE_NIX_NAME="$UPDATE_NIX_NAME" UPDATE_NIX_PNAME="$UPDATE_NIX_PNAME" UPDATE_NIX_OLD_VERSION="$UPDATE_NIX_OLD_VERSION" UPDATE_NIX_ATTR_PATH="$attrPath" eval $updateScript } dryRun= ignore= toplevelsToUpdate=() verbose= parseArgs() { while [ "$#" -ne 0 ]; do local arg=$1 shift case "$arg" in (--help) usage ;; (--dry-run) dryRun=1 ;; (--verbose) verbose=1 ;; (*) toplevelsToUpdate+=("$arg") ;; esac done if [ "${#toplevelsToUpdate[@]}" -eq 0 ]; then ignore=sane.feeds toplevelsToUpdate=(sane) fi } parseArgs "$@" pkgsToUpdate=() for t in "${toplevelsToUpdate[@]}"; do getPkgs pkgsToUpdate "$t" done for p in "${pkgsToUpdate[@]}"; do hasEffect updateOnePkg "$p" done