fix(cli): sentry cli uninstall does not detect Homebrew from the Cellar path
维护者通常 1 天内回复
已经有一个关联 PR 被合并了。
- #1592 来自 @sentry-junior —— 已合并
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 74/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- node.js, typescript
- 领域
- cli
调研方向
从 packages/cli/src/commands/cli/uninstall.ts 和 packages/cli/src/lib/upgrade.ts 中的 Cellar 检测开始;然后查看 packages/cli/test/commands/cli/uninstall.test.ts 和现有的 brew 测试。为安装信息为空且 process.execPath 位于 Cellar 的情况添加测试。完成标准是 uninstall 建议执行 brew uninstall getsentry/tools/sentry,并且不计划删除 Cellar 二进制文件。
由索引模型根据 Issue 内容生成。
描述
Problem
sentry cli uninstall only recognises a Homebrew install if the install method was saved in the CLI database. It checks stored install info (install.method) and detectRuntimePackageManager(), which only looks at node_modules for npm/pnpm/bun/yarn. It never does the Cellar check that sentry cli upgrade uses.
When a Homebrew install has no recorded method, uninstall treats it as self-managed. It doesn't print Run: brew uninstall getsentry/tools/sentry, and it plans to delete the Cellar binary and remove completions, skills and config itself.
This can happen after any brew install that never recorded a method. The old post_install wrote the record into a temporary HOME that Homebrew then deleted (#1545, #1555), and the new caveat command sentry cli setup --no-modify-path --no-completions doesn't pass --method brew. detectInstallationMethod() returns "brew" from the Cellar check before it reaches the code that saves the detected method, so the record stays empty.
Cause
In packages/cli/src/commands/cli/uninstall.ts:
const installInfo = getInstallInfo();
const pmMethod =
installInfo?.method && installInfo.method in PM_UNINSTALL_HINTS
? installInfo.method
: detectRuntimePackageManager();
detectRuntimePackageManager() (same file) only checks process.argv[1] for node_modules paths. It doesn't look for /Cellar/ and doesn't call detectInstallationMethod().
The self-delete guard has the same problem:
const isSelfManaged =
!(installInfo?.method || detectRuntimePackageManager()) ||
installInfo?.method === "curl" ||
installInfo?.method === "unknown";
With no install info and no node_modules path, isSelfManaged is true for a Homebrew install, so the binary is added to the removal plan.
The Cellar check already exists in packages/cli/src/lib/upgrade.ts, but it's private:
function isHomebrewInstall(): boolean {
let execPath = process.execPath;
try { execPath = realpathSync(execPath); } catch { /* use original */ }
return execPath.includes("/Cellar/");
}
Impact
- A Homebrew user with no recorded method gets the wrong guidance, and the uninstall plan includes deleting
/opt/homebrew/Cellar/sentry/<version>/bin/sentrydirectly. Homebrew still thinks the package is installed, which can break laterbrew upgradeorbrew uninstallruns. sentry cli upgradeandsentry cli uninstalldisagree about how the CLI was installed.- The only brew test passes install info explicitly, so CI doesn't cover this path.
Evidence
packages/cli/src/commands/cli/uninstall.ts:pmMethod(~lines 457-461),isSelfManaged(~lines 272-276),detectRuntimePackageManager()(~line 67).packages/cli/src/lib/upgrade.ts:isHomebrewInstall()(~lines 355-363, not exported),detectInstallationMethod()(~lines 453-459).packages/cli/test/commands/cli/uninstall.test.ts: the "detects brew install and suggests brew uninstall" test callssetInstallInfo({ method: "brew", ... }). Nothing covers empty install info with a CellarexecPath.- Related: #1545, #1555.
Possible fixes
- Move
isHomebrewInstall()into a shared module, e.g.packages/cli/src/lib/binary.ts, and use it first inuninstall.tsfor bothpmMethodandisSelfManaged. It's arealpathSyncplus a substring check, no subprocesses. - Don't call
detectInstallationMethod()from uninstall: it runs legacy subprocess detection and writes install info, which uninstall shouldn't trigger. - Add a test with empty install info and a Cellar
process.execPath(mockrealpathSync) that asserts thebrew uninstall getsentry/tools/sentryhint and that no binary-deletion artifact is produced. - We could also add
--method brewback to the caveat and docs snippet in #1555. That fixes the immediate case but not the general one.
- 主要语言
- TypeScript
- 星标
- 938
- 派生
- 166
- 平均合并
- 1 天 7 小时
- 30 天内合并 PR
- 156
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
getsentry/toolkit 的其他 Issue
-
bug MCP
难度 2/5 1-3 小时 新手友好度 78/100
getsentry/toolkit#1600 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
getsentry/toolkit#1471 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 52/100
getsentry/toolkit#1611 · 1 条评论 ·
维护者通常 1 天内回复
-
enhancement MCP
难度 4/5 1-2 天 新手友好度 55/100
getsentry/toolkit#1601 · 1 条评论 ·
维护者通常 1 天内回复
-
Use typed detector schemas from @sentry/api for metric monitors可能已有人在做 @MathurAditya724 于 1 天前认领。 未关闭
getsentry/toolkit#1595 · 1 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
查看 getsentry/toolkit 的全部 Issue
相似的 Issue
-
area: image-engine bug priority: low
难度 2/5 1-3 小时 新手友好度 88/100
snapotter-hq/SnapOtter#3885 ·
维护者通常 1 天内回复
-
Mend: dependency security vulnerability
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 3 天内回复
-
pending triage
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
bug P3 UI/UX
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
难度 2/5 1-3 小时 新手友好度 73/100
openclaw/openclaw#182077 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复