feat(update): detect Homebrew installs and upgrade via brew#44
Conversation
The update command previously fell back to `npm i -g` for any install it couldn't identify as pnpm. On a Homebrew-installed CLI that either creates a conflicting npm-global binary or fails with EACCES against the brew-owned node prefix. Detect a brew install (the running script resolves into a brew Cellar) and delegate to `brew upgrade <brewFormula>` instead, inheriting brew's own progress output. Adds an optional `brewFormula` option for brew-distributed CLIs to set. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doistbot
left a comment
There was a problem hiding this comment.
This PR thoughtfully improves the update command by detecting Homebrew environments and delegating to brew upgrade, which gracefully prevents permission errors and binary conflicts for macOS and Linuxbrew users. The approach significantly enhances the update experience while seamlessly preserving the existing npm workflow. A few areas need slight refinement before merging, specifically ensuring accurate success reporting when the brew formula lags the npm registry, failing faster on missing formulas to avoid unnecessary network calls, ensuring cross-platform test reliability, and consolidating some duplicated process-spawning logic.
- Report a neutral brew result instead of claiming the npm dist-tag version was installed (brew owns versioning and can be a no-op when the formula lags). - Fail fast on a brew install with no configured formula, before the registry round-trip. - Consolidate the spinner call and extract a shared spawn+capture helper. - Pin process.platform in brew tests for cross-OS determinism; add a quiet/JSON brew case asserting the piped stdio fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@doistbot /review |
doistbot
left a comment
There was a problem hiding this comment.
This PR introduces Homebrew detection to the update command, gracefully delegating to brew upgrade instead of defaulting to npm when a brew-managed installation is detected. This is a thoughtful addition that will significantly improve the update experience for macOS and Linuxbrew users by preventing permission errors and conflicting binaries. A few adjustments are needed to accurately reflect install status when a brew formula lags behind npm, stabilize the JSON output schema across package managers, consolidate duplicated code, and expand test coverage for spinner behavior and non-Homebrew fallback scenarios.
Round 2 of doistbot review: - Read the on-disk version after `brew upgrade` (brew list --versions) and derive `installed` from it, so a no-op upgrade (formula lagging npm) no longer reports installed: true. Expose the applied version as `installedVersion`. - Stable success envelope across installers: always carry `latestVersion` plus a `via` discriminator (npm | pnpm | brew) instead of dropping keys on brew. - Evaluate `detectPackageManager()` unconditionally to drop the nullable union and `pm as string` cast; consolidate the summary/lines branches. - Tests reuse `createProgram(overrides)`; add coverage for the no-op vs changed brew result, formula-set-but-npm-managed fallback, and brew spinner threading. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## [0.21.0](v0.20.1...v0.21.0) (2026-05-22) ### Features * **update:** detect Homebrew installs and upgrade via brew ([#44](#44)) ([a532a41](a532a41))
|
🎉 This PR is included in version 0.21.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
updatecommand previously defaulted any unrecognised install tonpm i -g. On a Homebrew-installed CLI that creates a conflicting npm-global binary or fails withEACCESagainst the brew-owned node prefix.process.argv[1]) resolves via symlink into a HomebrewCellar(works on Apple Silicon/opt/homebrew, Intel/usr/local, Linuxbrew) — and delegate tobrew upgrade <brewFormula>instead, inheriting brew's own progress output. Under--json/--ndjsonbrew's stdout is piped (not inherited) so it can't corrupt the machine-readable stream.brewFormulaconsumer option (e.g.'doist/tap/todoist-cli'). npm-only CLIs leave it unset; a brew install detected without it errors with a manual-brew upgradehint rather than running npm.The npm-registry dist-tag check still gates "is an update available". A brew formula can lag the npm publish, so
brew upgrademay be a no-op until the formula is bumped — documented in the README and docstring.Test plan
npm test— full suite (439 passing), incl. new brew cases: correctbrew upgrade <formula>spawn with inherited stdio, non-zero exit →UPDATE_INSTALL_FAILED, and the no-formula guard refusing to fall back to npmnpm run type-checknpm run check(oxlint + oxfmt)<cli> update --checkand<cli> update🤖 Generated with Claude Code