mt-update (4003B)
1 #!/bin/sh 2 CLIENT="" 3 if [ -f "/etc/mt-client" ]; then 4 CLIENT=$(cat /etc/mt-client) 5 elif [ -n "$1" ]; then 6 CLIENT="$1" 7 else 8 CLIENT="$USER" 9 fi 10 11 if [ -z "$CLIENT" ]; then 12 echo "No client?" 13 exit 14 fi 15 16 DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/mt-update" 17 REPO_DIR="$DATA_DIR/$CLIENT" 18 CHANNEL_DIR="$DATA_DIR/channel" 19 20 # Note that this script assumes the presence of 21 # 1) coreutils (duh) 22 # 2) notify-send 23 # 3) git 24 # 4) guix (also duh) 25 26 mkdir -p "$DATA_DIR" 27 28 NID=$(notify-send -t 0 -p "Checking for updates...") 29 NOTIF="notify-send -t 0 -r $NID" 30 31 # 32 # Update channel 33 # 34 35 CCOMMIT_A=$(git -C "$CHANNEL_DIR" rev-parse HEAD) 36 echo channel commit a $CCOMMIT_A 37 38 if [ -d "$CHANNEL_DIR/.git" ]; then 39 git -C "$CHANNEL_DIR" pull 40 else 41 git clone "git@monastech.xyz:channel" "$CHANNEL_DIR" 42 fi 43 44 CCOMMIT_B=$(git -C "$CHANNEL_DIR" rev-parse HEAD) 45 echo channel commit b $CCOMMIT_B 46 47 # 48 # Update guix 49 # 50 51 # This might seem arbitrary, but the channels in channels.scm are pinned to 52 # specific commits that are only updated once a specific version is deemed 53 # stable enough to be used by veryone. This should happen roughly once a month. 54 55 PULLED="" 56 UPDATED_CHANNEL="" 57 58 if [ "$CCOMMIT_A" != "$CCOMMIT_B" ]; then 59 UPDATED_CHANNEL="yes" 60 61 # This doesn't seem to work properly. It's updated every time the channel is. 62 if [ -z "$CCOMMIT_A" ] \ 63 || { ! git -C "$CHANNEL_DIR" diff --quiet --exit-code "$CCOMMIT_A" "$CCOMMIT_B" mt/channels.scm; } 64 then 65 66 $NOTIF "Updating channels..." \ 67 "This might take a few minutes." 68 69 if guix pull -C "${CHANNEL_DIR}/mt/channels.scm"; then 70 notify-send -t 0 \ 71 "Channels updated!" \ 72 "Both home and system environments will be updated." 73 PULLED="yes" 74 else 75 notify-send -u critical -t 0 \ 76 "Failed to update channels!" 77 fi 78 fi 79 fi 80 81 $NOTIF "Checking for updates..." 82 83 COMMIT_A=$(git -C "$REPO_DIR" rev-parse HEAD) 84 echo commit a $COMMIT_A 85 86 # 87 # Update configuration 88 # 89 90 if [ -d "$REPO_DIR/.git" ]; then 91 git -C "$REPO_DIR" pull 92 else 93 git clone "git@monastech.xyz:$CLIENT" "$REPO_DIR" 94 fi 95 96 COMMIT_B=$(git -C "$REPO_DIR" rev-parse HEAD) 97 echo commit b $COMMIT_B 98 99 if [ "$COMMIT_A" != "$COMMIT_B" ] \ 100 || [ -n "$UPDATED_CHANNEL" ] 101 then 102 UPDATE_FAILED= 103 104 if [ -z "$COMMIT_A" ] \ 105 || { ! git -C "$REPO_DIR" diff --quiet --exit-code "$COMMIT_A" "$COMMIT_B" home/; } \ 106 || [ -n "$PULLED" ] \ 107 || [ -n "$UPDATED_CHANNEL" ] 108 then 109 $NOTIF "Updating home environment..." 110 111 if guix home -L "$CHANNEL_DIR" -L "$REPO_DIR" reconfigure "${REPO_DIR}/home/${USER}.scm"; then 112 notify-send -t 0 \ 113 "Updated home environment!" \ 114 "After all updates are complete, log out and log back in." 115 else 116 notify-send -u critical -t 0 \ 117 "Failed to build home environment!" 118 UPDATE_FAILED="yes" 119 fi 120 fi 121 122 if [ -z "$COMMIT_A" ] \ 123 || { ! git -C "$REPO_DIR" diff --quiet --exit-code "$COMMIT_A" "$COMMIT_B" system/; } \ 124 || [ -n "$PULLED" ] \ 125 || [ -n "$UPDATED_CHANNEL" ] 126 then 127 $NOTIF "Updating system environment..." 128 129 if pkexec guix system -L "$CHANNEL_DIR" -L "$REPO_DIR" reconfigure "${REPO_DIR}/system/$(cat /etc/hostname)".scm; then 130 notify-send -t 0 \ 131 "Updated system environment!" \ 132 "After all updates are complete, please restart the machine." 133 else 134 notify-send -u critical -t 0 \ 135 "Failed to update system environment!" 136 UPDATE_FAILED="yes" 137 fi 138 fi 139 140 if [ -n "$UPDATE_FAILED" ]; then 141 echo "Resetting commits" 142 # Go back to the commit from before updates were attempted 143 git reset -C "$REPO_DIR" reset "$CCOMMIT_A" --hard 144 git reset -C "$REPO_DIR" reset "$COMMIT_A" --hard 145 fi 146 147 $NOTIF "All updates are complete!" 148 else 149 $NOTIF "No updates are available." 150 fi 151