fix(npm): prevent binary unavailability during auto-upgrade - #704
fix(npm): prevent binary unavailability during auto-upgrade#704lizhengfeng101 wants to merge 2 commits into
Conversation
Add a binary cache fallback mechanism to ensure ocr remains available while the background auto-upgrade is running npm i -g. Before the upgrade, the current binary is copied to ~/.opencodereview/bin/ as a safety net. resolveNativeBinary() now checks this cache path as a last resort before returning null. This fixes: - Unix: the gap window where binary is deleted before new one installs - Windows: broken installs when npm i -g fails due to file locks
|
🔍 OpenCodeReview found 2 issue(s) in this PR.
|
| const cachePath = path.join( | ||
| os.homedir(), ".opencodereview", "bin", BINARY_FILENAME | ||
| ); |
There was a problem hiding this comment.
[maintainability · medium]
The cache directory path ".opencodereview" is hardcoded here and also independently defined in scripts/update.js as path.join(os.homedir(), ".opencodereview"). If either location is changed without updating the other, the cache lookup will silently fail. Consider extracting this into a shared constant exported from platform.js (e.g., CACHE_DIR) and importing it in update.js to ensure consistency.
| const lockFile = path.join(stateDir, "update.lock"); | ||
| const hintFile = path.join(stateDir, "update-available"); | ||
|
|
||
| const CACHE_BIN_DIR = path.join(stateDir, "bin"); |
There was a problem hiding this comment.
[maintainability · medium]
The cache directory path ~/.opencodereview/bin is constructed independently here and in platform.js (lines 58-59). If one location is updated but the other isn't, they will silently diverge, causing the cache to never be found or written correctly. Consider exporting CACHE_BIN_DIR (or a function like getCacheBinPath()) from platform.js and importing it here, so there's a single source of truth for the cache path.
Replace the simple binary cache with a proper staged binary mechanism: - Add version.json metadata tracking (version, timestamp, platform) - Add platform validation to prevent cross-platform misuse - Add file integrity checks (exists, non-empty) in resolveStagedBinary() - Notify users via dim stderr message when running from staged binary - Refresh staged binary after successful upgrade for next-time protection - Reuse STATE_DIR from platform.js to eliminate path duplication - Always write version.json to avoid orphan binaries on disk Resolution priority: platform package > staged binary > legacy path.
Summary
~/.opencodereview/bin/soocrremains available while the background auto-upgrade runsnpm i -gresolveNativeBinary()uses it as a last resort when the platform package binary is missingProblem
When the background auto-upgrade runs
npm i -g, npm removes the old platform package before installing the new one. During this gap window,ocrfails with "binary not found". On Windows, the running.execannot be deleted, so the upgrade fails entirely and can leave a permanently broken install.Solution
A simple binary cache mechanism:
scripts/update.jscopies the current binary to~/.opencodereview/bin/before runningnpm i -gscripts/platform.jsadds this cache path as the third fallback inresolveNativeBinary()(after platform package → legacy path → cache → null)This ensures
ocralways has a working binary to fall back on, even during the upgrade gap window or after a failed Windows upgrade.Closes #703
Test plan
make checkpassesmake testpassesocr versionduring upgrade → should always succeed via cache fallback