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