feat(nix): add scripts for zk, edit, commit and rebuild

This commit is contained in:
Mohammad Rafiq 2025-07-09 04:20:46 +08:00
parent 782bbcbaa3
commit 08090fa25c
No known key found for this signature in database
5 changed files with 244 additions and 9 deletions

View file

@ -0,0 +1,71 @@
{ pkgs, ... }:
pkgs.writeShellScriptBin "commit" # bash
''
if git diff-index --quiet HEAD --; then exit 0; fi
PROMPT="Please generate a commit message for this diff."
GUIDELINES="1. Use conventional commit syntax, following the context. 2. Cap the commit message at 80 characters, preferably less. You must not go beyond this limit. 3. Do not include backticks. Only generate the raw text. 4. Be as succint as possible. Each commit should be atomic. You may throw a warning if it is not."
NUM_ANCESTORS=0
PUSH=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--num-ancestors | -n)
NUM_ANCESTORS="$2"
shift 2
;;
--push | -u)
PUSH=true
shift
;;
*)
echo "Unrecognised argument: $1. Exiting..."
exit 1
;;
esac
done
# Get context and diff
CONTEXT=$(git --no-pager log -n 10)
DIFF=$(git --no-pager diff HEAD~$NUM_ANCESTORS)
# Generate initial response
RESPONSE=$(aichat "$PROMPT\nGuidelines: $GUIDELINES\nContext from git log:\n$CONTEXT\nDiff from git diff HEAD:\n$DIFF")
while true; do
echo "$RESPONSE"
echo
echo "Choose an action:"
read -p "Options: [y]es, [r]eroll, [e]dit, [q]uit? " -n 1 -r choice
echo
case "$choice" in
y | yes)
git commit -am "$RESPONSE"
echo "Committed successfully."
if $PUSH; then
git push
echo "Pushed successfully."
fi
exit 0
;;
r | reroll)
RESPONSE=$(aichat "$PROMPT\nGuidelines: $GUIDELINES\nContext from git log:\n$CONTEXT\nDiff from git diff HEAD:\n$DIFF")
;;
e | edit)
echo "$RESPONSE" > /tmp/commit_msg.txt
"$EDITOR" /tmp/commit_msg.txt
RESPONSE=$(cat /tmp/commit_msg.txt)
rm /tmp/commit_msg.txt
;;
q | quit | "")
echo "Aborted."
exit 1
;;
*)
echo "Invalid choice. Please choose again."
;;
esac
done
''

View file

@ -0,0 +1,12 @@
{ pkgs, ... }:
let
finder = "${pkgs.fzf}/bin/fzf --preview 'cat {}'";
in
pkgs.writeShellScriptBin "edit" # sh
''
if [ $# -gt 0 ]; then
$EDITOR $(${finder} -q $*)
else
$EDITOR $(${finder})
fi
''

View file

@ -0,0 +1,9 @@
{ pkgs, ... }:
pkgs.writeShellScriptBin "note" # bash
''
zk edit -i
pushd ~/notebook > /dev/null
git add .
commit -u
popd > /dev/null
''

View file

@ -0,0 +1,148 @@
{ pkgs }:
let
inherit (pkgs.lib) getExe;
in
pkgs.writeShellScriptBin "rebuild" # sh
''
QUICK=false
NO_GENERATION_CHECK=false
TEST_SHELL=false
REMOTE_HOSTS=()
REBUILDING_ALL=false
# ANSI color codes
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m'
info() {
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "''${GREEN}''${timestamp} INFO: $1''${NC}"
}
warn() {
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "''${ORANGE}''${timestamp} WARN: $1''${NC}"
}
err() {
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "''${RED}''${timestamp} ERROR: $1''${NC}"
}
prompt() {
local PROMPT="$1"
shift
read -p "$PROMPT? (y/n) [n]: " -n 1 -r REPLY
echo
if [[ "$REPLY" =~ ^[Yy]$ ]]; then
"$*"
else
info "$PROMPT aborted."
fi
}
spawn_test_shell() {
info "Spawning test shell on $1..."
(export PS1="Test shell> "
exec ${pkgs.bash}/bin/bash ssh "$1") || {
${pkgs.cowsay}/bin/cowsay "You aborted."
exit 1
}
}
rebuild_remote() {
local args=(".#nixosConfigurations.$1" "--target-host" "$1")
local CURRENT_GENERATION=$(ssh "$1" readlink /nix/var/nix/profiles/system | cut -d- -f2)
if "$TEST_SHELL"; then
info "Testing $1..."
${getExe pkgs.nh} os test "''${args[@]}" || exit 1
git diff HEAD --color=always --stat --patch
spawn_test_shell "$1"
info "Rebuilding $1..."
${getExe pkgs.nh} os boot "''${args[@]}" || exit 1
else
info "Rebuilding $1 on $HOSTNAME..."
${getExe pkgs.nh} os switch "''${args[@]}" || exit 1
fi
if ! "$NO_GENERATION_CHECK"; then
local NEW_GENERATION=$(ssh "$1" readlink /nix/var/nix/profiles/system | cut -d- -f2)
info "$1 - New generation is $NEW_GENERATION. Current is $CURRENT_GENERATION."
if [ ! $NEW_GENERATION -gt $CURRENT_GENERATION ]; then
warn "New config was not added to bootloader."
fi
fi
}
info "Starting rebuild script."
if [ ! -f "flake.nix" ]; then
err "flake.nix not found in the current directory. Exiting."
exit 1 # Indicate an error
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--quick | -q)
QUICK=true
shift
;;
--no-generation-check | -n)
NO_GENERATION_CHECK=true
shift
;;
--test-shell | -t)
TEST_SHELL=true
shift
;;
--all | -a)
reachable_hosts=()
hostnames=$(nix flake show --all-systems --json | , jq -r '.nixosConfigurations | keys | .[]')
for host in ''${hostnames[@]}; do
info "Checking if $host is reachable..."
if ping -c 1 -W 1 "$host" > /dev/null 2>&1 ; then
info "$host is reachable."
reachable_hosts+=("$host")
else
warn "$host is unreachable."
fi
done
REMOTE_HOSTS=(''${reachable_hosts[@]})
REBUILDING_ALL=true
shift
;;
*)
if [ !REBUILDING_ALL ]; then
if ping -c 1 -W 1 "$1" > /dev/null 2>&1 ; then
REMOTE_HOSTS+=("$1")
else
err "$1 is unreachable. Exiting."
exit 1
fi
fi
shift
;;
esac
done
if [ ''${#REMOTE_HOSTS[@]} == 0 ]; then
info "No hostnames provided."
REMOTE_HOSTS=("$HOSTNAME")
fi
git add .
for host in "''${REMOTE_HOSTS[@]}"; do
rebuild_remote $host
done
if ! "$QUICK"; then
prompt "Commit changes" commit
prompt "Reboot system" sudo systemctl reboot
fi
info "Rebuild script completed successfully."
exit 0
''

View file

@ -38,15 +38,10 @@ in
fastfetch fastfetch
ripgrep ripgrep
aichat aichat
(pkgs.writeShellScriptBin "note" # bash (import ./_scripts/edit.nix { inherit pkgs; })
'' (import ./_scripts/commit.nix { inherit pkgs; })
zk edit -i (import ./_scripts/note.nix { inherit pkgs; })
pushd ~/notebook > /dev/null (import ./_scripts/rebuild.nix { inherit pkgs; })
git add .
commit -u
popd > /dev/null
''
)
]; ];
}; };
programs = { programs = {