fix(engine): robust Windows install + ship rocky-lsp alongside rocky#931
Merged
Conversation
On Windows a running executable is locked, so install.ps1's in-place Copy-Item over rocky.exe failed with 'being used by another process' whenever something was running the binary — most commonly the VS Code Rocky extension, which spawns 'rocky lsp' (the installer never ships the standalone rocky-lsp, so the extension falls back to running rocky.exe itself). Renaming an in-use binary is allowed on Windows (the running process keeps its handle to the renamed file), so mirror what install.sh already does with mv: try a normal copy, and on a locked overwrite move the old binary aside (rocky.exe.old-<rand>) and drop the new one into place, then tell the user to restart VS Code. Stale .old files from prior in-use updates are swept on the next run. The install now succeeds while VS Code is open.
The VS Code extension prefers a sibling rocky-lsp binary for the language server; when it is present the extension never runs rocky.exe as the LSP, so rocky.exe is never locked in the first place (the root cause of the Windows in-place-overwrite failure). Both installers now best-effort install rocky-lsp next to rocky: download the rocky-lsp-<target> archive, verify it against the same checksums.txt, and place it with the same mechanism as rocky (mv on Unix; rename-then-replace on Windows, now factored into an Install-RockyBinary helper so both binaries get identical robust install). Best-effort and non-fatal: if the rocky-lsp archive is missing (older release) or fails verification, it is skipped and the extension falls back to 'rocky lsp' (which the rename-then-replace install already handles). The core rocky install is unchanged.
hugocorreia90
added a commit
that referenced
this pull request
Jun 19, 2026
…fix (#936) - ide-setup.md: the VS Code extension prefers a standalone rocky-lsp binary (now installed next to rocky by the install scripts) and falls back to 'rocky lsp'. - engine CHANGELOG [Unreleased]: record the installer fix (#931) — rocky-lsp shipped alongside rocky + Windows rename-then-replace — so it rides the next engine release notes. The fix is already live (scripts served from main).
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.
The bug
Running the Windows install one-liner while VS Code is open fails:
Why
Two things combine:
install.ps1overwroterocky.exein place withCopy-Item -Force. On Windows a running executable is locked, so the overwrite fails.rocky-lsp. The VS Code extension prefersrocky-lspfor the language server but, not finding it, falls back to spawningrocky lsp— so it runsrocky.exe, locking the exact file the installer is replacing.install.sh(macOS/Linux) didn't hit this because it usesmv(atomic rename, fine over a running binary on Unix). This was Windows-only.The fix (two complementary changes)
1. Rename-then-replace on Windows. Renaming an in-use binary is allowed on Windows (the running process keeps its handle), so
install.ps1now mirrorsinstall.sh'smv: try a normal copy, and on a locked overwrite move the old binary aside (rocky.exe.old-<rand>) and drop the new one in. Stale.oldfiles are swept on the next run. The install now succeeds while VS Code is open.2. Ship
rocky-lspalongsiderocky(both installers). This removes the root cause: whenrocky-lspis present the extension uses it for the LSP and never runsrocky.exe, sorocky.exeis never locked. Both installers best-effort downloadrocky-lsp-<target>, verify it against the samechecksums.txt, and place it with the same mechanism asrocky. The Windows rename-replace is factored into anInstall-RockyBinaryhelper so both binaries get identical robust install (androcky-lsp's own future updates are covered too).Best-effort and non-fatal: if the
rocky-lsparchive is missing (older release) or fails verification, it's skipped and the extension falls back torocky lsp. The corerockyinstall is unchanged.No release needed — the one-liners fetch the scripts from
main, so this takes effect on merge.Verification
bash -n+shellcheck -S errorclean oninstall.sh.install.ps1hand-verified (nopwshon the build host):-ErrorAction Stopmakes the lock error terminating so thecatchfires; non-lock failures rethrow; the unique.old-<rand>name avoids colliding with a still-locked prior.old;Install-RockyBinaryis defined before its call sites; therocky-lspblock reuses the already-fetchedchecksums.txtand is wrapped so any failure is non-fatal.🤖 Generated with Claude Code