feat: add Windows support via file-copy apply mode#3
Merged
Conversation
Windows handles symlinks poorly (they need Developer Mode or admin), so on Windows stellar now copies the theme file over starship.toml instead of symlinking. The mode is selected by runtime.GOOS and overridable via STELLAR_APPLY_MODE=copy|symlink for testing. - symlink: rename CreateSymlink -> ApplyTheme, add IsCopyMode() and a shared copyFile helper; back up the user's original config safely in copy mode (never overwrite an existing backup, so a lost config.json can't clobber it) - current: make verification mode-aware (only readlink in symlink mode) - update: unblock Windows, append .exe, download next to the binary, and do a Windows-safe self-replace; clean up the leftover .old on the next run - goreleaser: build windows/amd64 + windows/arm64 - installer: add install.ps1 and point install.sh's Windows guard at it - tests: copy-mode unit and e2e coverage, incl. the backup-clobber safety net Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lf-update Address code-review findings on the Windows support work: - record applied_hash in config.json so stellar recognizes its own applied file mode-independently; the documented edit-and-reapply workflow, clean --all, and apply-mode switches no longer create junk versioned backups (legacy configs without the hash keep the old content-match fallback) - stellar current: branch on the observed on-disk state (Lstat) instead of STELLAR_APPLY_MODE, restore the lost "theme file missing" diagnostic for copied configs, and surface path-resolution errors - stellar rollback: print the backup notice instead of silently discarding the backup path; share the notice helper with apply and derive the restore hint from the written path - install.ps1: verify the download against checksums.txt before replacing stellar.exe (temp-then-move), preserve REG_EXPAND_SZ when updating the user PATH, detect WoW64 hosts via PROCESSOR_ARCHITEW6432 - self-update: gate leftover cleanup to Windows, remove only stellar's own .old/.stellar-update-* artifacts, drop the unreachable removal of the running old binary - tests: pin STELLAR_APPLY_MODE=symlink in SetupTestEnv and skip symlink tests where unsupported so the suite runs on Windows; make CaptureOutput restore stdout on test failure; add regression tests for the backup, rollback, current, and cleanup behavior Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ructured backup info
Move the AppliedHash bookkeeping out of the apply/rollback call sites into
ApplyTheme itself, so no future caller can forget it and cause spurious
backups. In copy mode the hash is computed while the file streams through
copyFile instead of re-reading it afterward.
Replace BackupIdentifier's path re-parsing with a BackupInfo{Path, Identifier}
built at creation time from the same author/version values used to construct
the path, formatted via theme.Theme.String() so the identifier wire format
stays defined in one place.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Preserve the checksum-verified download when the Windows binary swap double-fails (rename to .old succeeded, install and restore both failed): replaceExecutable now owns the temp file's fate and returns recovery instructions instead of letting the caller delete the only good binary. - Run update-leftover cleanup on every OS, not just Windows: temp files are created next to the binary everywhere, so an interrupted update on Linux/macOS no longer litters the bin dir forever. - Match leftovers with os.ReadDir + prefix instead of filepath.Glob, which misinterpreted glob metacharacters in the install path (e.g. tools[1]) and silently cleaned nothing. - Turn the GitHub release endpoints into package vars as an e2e test seam. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-healthy The regular-file branch reported a healthy applied theme as long as the cached theme file existed, so a hand-modified or replaced starship.toml was misreported as the current theme (a regression from the symlink-only check on main). Compare the file's hash against cfg.AppliedHash (falling back to the cached theme file for legacy configs) and report 'modified or replaced' with a re-apply hint on mismatch. Also flag an empty CurrentPath and a directory at the config path as broken instead of skipping validation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Backups of the user's original starship.toml live at <author>/backup inside
the cache tree, so 'stellar clean' (and --all) swept them away and made the
printed restore hint permanently unrecoverable ('backup' is not a real hub
author, so there is nothing to re-download). Skip backup themes during
cleaning; they remain removable explicitly via 'stellar remove'.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- OR TLS 1.2 into SecurityProtocol so Windows PowerShell 5.1 on pre-.NET-4.7 defaults (TLS 1.0 only) can reach GitHub instead of failing the download. - Expand registry PATH entries before comparing against the install dir, so an existing unexpanded entry (e.g. %LOCALAPPDATA%\stellar\bin) is recognized and no duplicate is appended; the raw REG_EXPAND_SZ value is still written back untouched. - Merge the duplicated if ($RawPath) blocks computing NewPath and Kind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…afety - TestE2E_Update: successful update, already-up-to-date, and checksum- mismatch paths against an httptest server via the release-URL seams, with the test binary snapshotted and restored around the swap. - stellar current: healthy untouched copy-mode apply, hand-edited config reported as modified, empty current path and directory-at-config-path reported as broken. - stellar clean / clean --all: original-config backups survive and the printed restore hint still applies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pers - export symlink.IsManaged as the single "is starship.toml stellar's own" predicate; backupOriginalConfig and `stellar current` now use the same three-signal check, so current's modified diagnostic can no longer disagree with whether the next apply actually backs the file up - add theme.BackupThemeName so the backup writer (internal/symlink) and the clean-time guard (internal/cache) share one constant - add theme.IsValidIdentifierRune as the single [a-zA-Z0-9_-] definition, used by sanitizeBackupAuthor, with a test pinning it to the parser regex - collapse current.go's four duplicated diagnostic blocks into printReapplyHint / printThemeFileMissing (output unchanged) - extract platformBinaryName shared by updateCmd and the update E2E test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hanging The backup version-slot search only exited on ENOENT, so any persistent non-ENOENT stat error (ENOTDIR because <author>/backup exists as a plain file, EACCES on an unreadable dir) spun the loop forever and hung `stellar apply`/`stellar rollback`. Probe errors now abort the apply with a clear error, leaving the user's unmanaged starship.toml untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cleanupUpdateLeftovers runs on every command start and removed any .stellar-update-* file next to the binary, including the temp file of a "stellar update" still running in another process, aborting that update at the final rename. Leftover temp files are now only removed once they are older than an hour; an in-flight download's mtime is always fresh. The .old removal stays unconditional since it is never in-flight. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ery files from leftover cleanup On Windows, os.Rename intermittently fails with sharing violations while Defender or the Search Indexer briefly holds a freshly written file. The new symlink.RenameWithRetry rides that out with a bounded backoff (no-op single rename on other OSes) and is used for the theme-apply rename and the self-update binary swap. The self-update double-failure path now also renames the preserved, checksum-verified download to a .stellar-recovery-* name that removeUpdateLeftovers never matches, so a later stellar run can no longer delete the exact file the recovery instructions point at. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Windows handles symlinks poorly (they need Developer Mode or admin), so on Windows stellar now copies the theme file over starship.toml instead of symlinking. The mode is selected by runtime.GOOS and overridable via STELLAR_APPLY_MODE=copy|symlink for testing.