Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

fix(cli): sentry cli uninstall does not detect Homebrew from the Cellar path

已关闭 适合新手
#1,581 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #1592 来自 @sentry-junior —— 已合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
74/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
领域
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/sentry directly. Homebrew still thinks the package is installed, which can break later brew upgrade or brew uninstall runs.
  • sentry cli upgrade and sentry cli uninstall disagree 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 calls setInstallInfo({ method: "brew", ... }). Nothing covers empty install info with a Cellar execPath.
  • Related: #1545, #1555.

Possible fixes

  • Move isHomebrewInstall() into a shared module, e.g. packages/cli/src/lib/binary.ts, and use it first in uninstall.ts for both pmMethod and isSelfManaged. It's a realpathSync plus 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 (mock realpathSync) that asserts the brew uninstall getsentry/tools/sentry hint and that no binary-deletion artifact is produced.
  • We could also add --method brew back 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,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

getsentry/toolkit 的其他 Issue

查看 getsentry/toolkit 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。