helm/bin/hey

197 lines
7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env zsh
# I don't believe the interface for Nix's utility scripts are very good. Guix's,
# on the other hand, is excellent. Management of your OS is done by a single
# program with simpler, more intuitive commands. This script is a rudimentary
# attempt at giving me that.
#
2020-10-16 02:49:47 -07:00
# hey cd|check -> nix flake check $DOTFILES
# hey sh|show -> nix flake show $DOTFILES
# hey u|update -> nix flake update --recreate-lock-file $DOTFILES
# hey re|rebuild -> nixos-rebuild --flake $DOTFILES#$HOST ${1:-build}
# hey t|test -> nixos-rebuild --flake $DOTFILES#$HOST --fast test
2020-10-25 12:19:38 -07:00
# hey theme $THEME -> THEME=$THEME hey test (quick theme swapping)
2020-10-16 02:49:47 -07:00
# hey rollback -> hey rebuild --rollback switch
# hey s|search -> nix search nixpkgs $@
2020-10-25 12:19:38 -07:00
# hey swap $PATH -> swaps all specified nix-store symlinks (or recursively
# in a specified directory) with copies so they can be
# modified in place (while tweaking). Run again to
# restore the old link (careful, you'll lose work if you
# don't save your changes elsewhere!)
2020-10-16 02:49:47 -07:00
# hey vm -> hey rebuild vm
# hey up|upgrade -> hey update && hey rebuild switch
# hey gc -> GC user profile, optimise nix store
# sudo hey gc -> GC, optimise nix store, & delete old boot entries
# hey push REMOTE -> push flake to remote (over SSH) and rebuild remotely
# hey gen|generations -> explore, manage, diff across generations (WIP)
#
2020-10-16 02:49:47 -07:00
# hey (with no sub-command) can also be used as an alternative to nix-env:
#
2020-10-16 02:49:47 -07:00
# hey -q
# hey -iA nixos.htop
# hey -e htop
set -e
REMOTE=${REMOTE:-"~/.config/dotfiles"}
DOTFILES="${0:a:h}/.."
#
function main {
function _do { [[ $DRYRUN ]] && echo "$@" || "$@" }
### Helpers
function _usage {
2020-10-16 02:49:47 -07:00
echo "Usage: hey COMMAND [FLAGS...] [ARGS...]"
echo
echo "Available commands:"
2020-10-17 14:01:35 -07:00
echo " check (ch) Same as 'nix flake check \$DOTFILES'"
echo " gc Garbage collect and optimize store"
echo " generations (gen) TODO"
2020-10-17 14:01:35 -07:00
echo " push Push thie config to a remote NixOS system and rebuild it"
echo " rebuild (re) Rebuild current system flake"
echo " rollback Roll back to last generation"
echo " search (s) Searches nixpkgs for a package"
echo " show (sh) Same as 'nix flake show \$DOTFILES'"
echo " swap Swap nix-store link (or directory thereof) for tweaking"
2020-10-17 15:42:02 -07:00
echo " test (t) Quickly rebuild, for quick iteration"
2020-10-25 12:19:38 -07:00
echo " theme Quickly swap to another theme"
2020-10-17 14:01:35 -07:00
echo " upgrade (up) Update flake lockfile and rebuild"
echo " vm Build flake into a VM image"
}
function _rebuild {
# Move to $DOTFILES to prevent polluting the system with result links
pushd $DOTFILES >/dev/null
_do sudo nixos-rebuild --flake ".#${HOSTNAME:-$HOST}" ${@:-build}
popd >/dev/null
}
function _update {
echo "Updating NixOS flake"
if [[ "$@" ]]; then
for flake in $@; do
_do nix flake update --update-input "$flake" "$DOTFILES"
done
else
_do nix flake update --recreate-lock-file "$DOTFILES"
fi
}
function _gc {
if [[ $EUID == 0 ]]; then
echo "Cleaning up your system..."
_do sudo nix-collect-garbage ${@:--d}
_do nix-store --optimise
# nix-collect-garbage is a Nix tool, not a NixOS tool. It won't delete old
# boot entries until you do a nixos-rebuild (which means we'll always have
# 2 boot entries at any time). Instead, we properly delete them by
# reloading the current environment.
_do sudo nix-env --delete-generations old --profile /nix/var/nix/profiles/system
_do sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
else
echo "Cleaning up your user profile..."
_do nix-collect-garbage ${@:--d}
fi
}
function _swap {
for target in $@; do
if [ -d "$target" ]; then
files=( "$target"/**/*.nix-store-backup )
links=( $(find "$target" -type l) )
if [[ "$files" ]]; then
echo "There are swapped files here. Unswapping!"
for file in $files[@]; do
_swap "$link"
done
else
echo "Swapping files in $target"
for link in $links[@]; do
if [[ "$(readlink $link)" == /nix/store/* ]]; then
_swap "$link"
fi
done
fi
elif [ -f "$target.nix-store-backup" ]; then
echo "Unswapping $target"
_do mv -i "$target.nix-store-backup" "$target"
elif [ -f "$target" ]; then
echo "Swapping $target"
_do mv "$target" "$target.nix-store-backup"
_do cp "$target.nix-store-backup" "$target"
else
>&2 echo "Not a valid target: $target"
exit 1
fi
done
}
###
cmd="$1"
[[ $# > 0 ]] && shift
case "$cmd" in
2020-12-20 17:08:31 -08:00
sh|shell) _do nix develop "$DOTFILES" "$@" ;;
repl) _do nix repl "$DOTFILES/flake.nix" "<nixpkgs>" "$@" ;;
2020-10-23 15:11:03 -07:00
ch|check) _do nix flake check "$@" "$DOTFILES";;
sh|show) _do nix flake show "$@" "$DOTFILES" ;;
theme) THEME="$1" _rebuild --fast test ;;
2020-10-17 15:42:02 -07:00
t|test) _rebuild --fast test "$@" ;;
re|rebuild) _rebuild "${@:-switch}" ;;
rollback) _rebuild --rollback switch ;;
vm) _rebuild "$@" vm ;;
u|update) _update "$@" ;;
up|upgrade) _update && _rebuild switch ;;
s|search) nix search nixpkgs "$@" ;;
2020-10-25 12:19:38 -07:00
swap) _swap $@ ;;
gc) _gc "$@" ;;
push)
target=$1
cmd=${2:-test}
# build then ssh in to switch/boot/test so we don't require root ssh
# access on the remote.
echo "Enabling root ssh access on $target"
ssh -t "$target" "sudo mkdir -p /root/.ssh && sudo cp -f ~/.ssh/authorized_keys /root/.ssh/"
echo "Building $target ($cmd)"
HOSTNAME="${HOSTNAME:-$target}" _rebuild \
--build-host localhost \
--target-host "root@$target" \
$cmd
echo "Undoing root ssh access on $target"
ssh -t "root@$target" "rm -f /root/.ssh/authorized_keys"
;;
gen|generations)
profile=/nix/var/nix/profiles/system
case "$1" in
switch) >&2 echo "Targeted rollback not supported yet" ;; # TODO Is this true?
diff)
to=/nix/var/nix/profiles/system-${2}-link
diff \
<(nix-store -q --references $profile) \
<(nix-store -q --references $to)
;;
remove)
shift
_do sudo nix-env --delete-generations --profile $profile $@
;;
"")
_do sudo nix-env --list-generations --profile $profile
;;
esac
;;
h|help|-h|--help) _usage ;;
-*) _do nix-env "$cmd" "$@" ;;
"") _usage ;;
*) echo "Couldn't find command: $cmd" 1>&2
exit 1
;;
esac
}
main "$@"