fix(daemon): preserve curl-installer daemon as .bak instead of deleting#282
Conversation
When `commandDaemonInstall` resolves to a system-managed binary (e.g. Homebrew, or a stale `/usr/local/bin/shelltime-daemon` on Linux), the cleanup branch previously deleted `~/.shelltime/bin/shelltime-daemon` outright. Combined with `install.bash` running `shelltime daemon reinstall` on upgrades, this caused the freshly-extracted daemon binary to be removed — and any subsequent `daemon install` would re-download it from GitHub releases. Rename the curl-installer copy to `shelltime-daemon.bak` instead. The existing `.bak` recovery branch at the top of `commandDaemonInstall` restores it on the next run, so once the user clears the stale system binary the daemon binary returns with no network fetch needed.
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request modifies the daemon installation logic to preserve existing curl-installer binaries by renaming them to a backup file instead of deleting them. Feedback was provided regarding a redundant file removal operation before renaming, noting that atomic replacement is already handled by the operating system on Unix-like platforms.
| _ = os.Remove(preservedPath) | ||
| if rnErr := os.Rename(curlDaemonPath, preservedPath); rnErr == nil { |
There was a problem hiding this comment.
On Unix-like systems (Linux and macOS), os.Rename atomically replaces the destination file if it already exists. The explicit os.Remove(preservedPath) is redundant and introduces a small non-atomic window where the backup file is missing. While harmless in this context, relying on os.Rename's native behavior is more idiomatic and robust.
if rnErr := os.Rename(curlDaemonPath, preservedPath); rnErr == nil {
Summary
commandDaemonInstallresolves to a system-managed binary (Homebrew on macOS, or a stale/usr/local/bin/shelltime-daemonon Linux), the cleanup branch previously deleted~/.shelltime/bin/shelltime-daemon. Combined withinstall.bashrunningshelltime daemon reinstallon upgrades, this removed the binaryinstall.bashhad just extracted — and the nextdaemon installre-downloaded it from GitHub releases.shelltime-daemon.bakinstead of removing it. The existing.bakrecovery branch at the top ofcommandDaemonInstall(lines 32-40) restores it on the next run, so once the user clears the stale system binary the daemon binary returns with no network fetch.install.bash. No changes tomodel/path.goresolution preference.Repro / before vs after
Setup (Linux, simulating the stale-system-binary case):
~/.shelltime/bin/shelltime-daemonis gone. Nextshelltime daemon installhits GitHub releases to re-download.~/.shelltime/bin/shelltime-daemon.bakexists. After the user clears/usr/local/bin/shelltime-daemonand re-runsshelltime daemon install, the existing.bakrecovery branch promotes it back toshelltime-daemon— no network fetch.Test plan
go build ./...succeedsgo test ./model/...green (path_test.goresolution cases unchanged)/usr/local/bin/shelltime-daemon+ fresh~/.shelltime/bin/shelltime-daemon→ afterdaemon install,.bakexists; after clearing the stale system binary and re-running,.bakis consumed andshelltime-daemonis restored~/.shelltime/bin,daemon installrenames it to.bak(logged) and service starts against the Homebrew binary.bakfiles (pre-renameos.Remove(preservedPath)clears any stale.bak)Out of scope
/usr/local/binentry indaemonHomebrewSearchPaths(resolution preference unchanged)./usr/local/binbinary for one reinstall cycle — user still needs to manually clear that. This fix only ensures their good binary survives.Generated by Claude Code