Skip to content

Commit ab8b9e4

Browse files
committed
fix: atomic install/update, safe uninstall, spinner errors, theme timeout
1 parent 5498b8e commit ab8b9e4

3 files changed

Lines changed: 47 additions & 14 deletions

File tree

common.sh

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,28 @@ _detect_theme() {
3939

4040
# 2. Query terminal background via OSC 11 (iTerm2, Ghostty, Kitty, WezTerm)
4141
if [[ -t 2 ]] && [[ -r /dev/tty ]]; then
42-
local old_stty response=""
42+
local old_stty response="" _dd_pid _timer_pid
43+
local _dd_tmp
44+
_dd_tmp=$(mktemp)
4345
old_stty=$(stty -g </dev/tty 2>/dev/null) || true
4446
stty raw -echo min 0 time 2 </dev/tty 2>/dev/null
4547
printf '\033]11;?\a' > /dev/tty 2>/dev/null
46-
response=$(dd bs=1 count=30 </dev/tty 2>/dev/null) || true
48+
# Read with kill-timer to prevent hang in non-standard terminals
49+
dd bs=1 count=30 </dev/tty >"$_dd_tmp" 2>/dev/null &
50+
_dd_pid=$!
51+
(sleep 1 && kill "$_dd_pid" 2>/dev/null) &
52+
_timer_pid=$!
53+
wait "$_dd_pid" 2>/dev/null
54+
kill "$_timer_pid" 2>/dev/null; wait "$_timer_pid" 2>/dev/null
55+
response=$(cat "$_dd_tmp")
56+
rm -f "$_dd_tmp"
4757
# Drain any leftover bytes from terminal response
48-
dd bs=1 count=64 </dev/tty >/dev/null 2>&1 || true
58+
dd bs=1 count=64 </dev/tty >/dev/null 2>&1 &
59+
_dd_pid=$!
60+
(sleep 1 && kill "$_dd_pid" 2>/dev/null) &
61+
_timer_pid=$!
62+
wait "$_dd_pid" 2>/dev/null
63+
kill "$_timer_pid" 2>/dev/null; wait "$_timer_pid" 2>/dev/null
4964
stty "$old_stty" </dev/tty 2>/dev/null
5065
if [[ "$response" =~ rgb:([0-9a-fA-F]+)/([0-9a-fA-F]+)/([0-9a-fA-F]+) ]]; then
5166
local r=$((16#${BASH_REMATCH[1]:0:2}))
@@ -130,10 +145,17 @@ spinner() {
130145
run_with_spinner() {
131146
local msg="$1"
132147
shift
133-
"$@" &>/dev/null &
148+
local _rws_log
149+
_rws_log=$(mktemp)
150+
"$@" &>"$_rws_log" &
134151
spinner $! "$msg"
135152
wait $! 2>/dev/null
136-
return $?
153+
local rc=$?
154+
if [[ $rc -ne 0 ]]; then
155+
cat "$_rws_log" >&2
156+
fi
157+
rm -f "$_rws_log"
158+
return $rc
137159
}
138160

139161
# Progress bar — inline redraw
@@ -1056,15 +1078,16 @@ macrift_update() {
10561078
local tmp
10571079
tmp="$(mktemp -d)"
10581080
if curl -fsSL "$MACRIFT_REPO_TAR" | tar -xz -C "$tmp" && [[ -d "$tmp/macrift-main" ]]; then
1059-
rm -rf "$MACRIFT_DIR"
1081+
# Atomic swap: backup old → move new → remove backup
1082+
mv "$MACRIFT_DIR" "$MACRIFT_DIR.bak"
10601083
if mv "$tmp/macrift-main" "$MACRIFT_DIR"; then
10611084
chmod +x "$MACRIFT_DIR/macrift.sh"
10621085
find "$MACRIFT_DIR" -name "*.sh" -exec chmod +x {} +
1086+
rm -rf "$MACRIFT_DIR.bak"
10631087
log_ok "Updated to $(cat "$MACRIFT_DIR/VERSION" 2>/dev/null || echo 'latest')"
10641088
else
10651089
log_err "Failed to replace install directory"
1066-
# Restore from tmp if possible
1067-
[[ -d "$tmp/macrift-main" ]] && mv "$tmp/macrift-main" "$MACRIFT_DIR"
1090+
mv "$MACRIFT_DIR.bak" "$MACRIFT_DIR"
10681091
rm -rf "$tmp"
10691092
return 1
10701093
fi

install.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,16 @@ printf '\n %bmacrift installer%b\n\n' "$BOLD" "$RESET"
3838
info "Downloading macrift..."
3939
tmp="$(mktemp -d)"
4040
if curl -fsSL "$REPO_TAR" | tar -xz -C "$tmp"; then
41-
[[ -d "$INSTALL_DIR" ]] && rm -rf "$INSTALL_DIR"
42-
mv "$tmp/macrift-main" "$INSTALL_DIR"
41+
# Atomic swap: backup old → move new → remove backup
42+
[[ -d "$INSTALL_DIR" ]] && mv "$INSTALL_DIR" "$INSTALL_DIR.bak"
43+
if mv "$tmp/macrift-main" "$INSTALL_DIR"; then
44+
rm -rf "$INSTALL_DIR.bak"
45+
else
46+
err "Failed to move files into place"
47+
[[ -d "$INSTALL_DIR.bak" ]] && mv "$INSTALL_DIR.bak" "$INSTALL_DIR"
48+
rm -rf "$tmp"
49+
exit 1
50+
fi
4351
rm -rf "$tmp"
4452
ok "Downloaded → $INSTALL_DIR"
4553
else
@@ -69,8 +77,8 @@ else
6977

7078
if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then
7179
local_zshrc="$HOME/.zshrc"
72-
path_line='export PATH="$HOME/.local/bin:$PATH"'
73-
if ! grep -qF '.local/bin' "$local_zshrc" 2>/dev/null; then
80+
path_line='export PATH="$HOME/.local/bin:$PATH" # added by macrift'
81+
if ! grep -qF '# added by macrift' "$local_zshrc" 2>/dev/null; then
7482
printf '\n%s\n' "$path_line" >> "$local_zshrc"
7583
ok "Added ~/.local/bin to PATH in .zshrc"
7684
fi

macrift.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ for arg in "$@"; do
2626
rm -f "$HOME/.local/bin/macrift"
2727
[[ -L "/usr/local/bin/macrift" ]] && sudo rm -f "/usr/local/bin/macrift"
2828
if [[ -f "$HOME/.zshrc" ]]; then
29-
sed -i '' '/\.local\/bin/d' "$HOME/.zshrc" 2>/dev/null || true
29+
sed -i '' '/# added by macrift/d' "$HOME/.zshrc" 2>/dev/null || true
3030
fi
3131
printf ' Done. macrift removed.\n\n'
3232
fi
@@ -45,7 +45,9 @@ done
4545

4646
# Resolve symlink — global 'macrift' command is a symlink to this file
4747
MACRIFT_ENTRY="${BASH_SOURCE[0]}"
48-
[[ -L "$MACRIFT_ENTRY" ]] && MACRIFT_ENTRY="$(readlink "$MACRIFT_ENTRY")"
48+
while [[ -L "$MACRIFT_ENTRY" ]]; do
49+
MACRIFT_ENTRY="$(readlink "$MACRIFT_ENTRY")"
50+
done
4951
source "$(cd "$(dirname "$MACRIFT_ENTRY")" && pwd)/common.sh"
5052

5153
# Init log file

0 commit comments

Comments
 (0)