Dashboard › cli › Distillation
c1e8e064-8562-46b9-b5ed-b86507c955da["lore_tm_v1_PqfjdfJsJqcnkAdXiZNCC9WZn4jGZHgKMr35A26_Vy0","lore_tm_v1_qpIJxZhCBxSE-HCL3jkyvviQTLBuZhz1O1y7OrlXYak","lore_tm_v1_DCWWseh0ypg1Reqr6MKGSYlR_Z1WzQC_P9rWubqxxpk","lore_tm_v1_TaR-dJebLcq_740ldyMG9MBo015kNr_CyimO1TJ5L_E","lore_tm_v1_WemmVfEVFt7akW0Fh7WmXi-zcvROrxA33igmzyfuZJ8"]
packages/cli/src/lib/binary.ts defines KNOWN_CURL_DIRS = [".local/bin", "bin", ".sentry/bin"].packages/cli/src/lib/binary.ts defines InstallationMethod as "curl" | "brew" | "npm" | "pnpm" | "bun" | "yarn" | "unknown"; VALID_METHODS accepts all except "unknown" for the --method flag.packages/cli/src/lib/binary.ts:parseInstallationMethod(value) lowercases input and throws Error(\Invalid method: ${value}. Must be one of: ${VALID_METHODS.join(", ")}`)` for an unsupported method.packages/cli/src/lib/binary.ts:isMusl() only checks Linux, caches its result in cachedIsMusl, first probes /lib/ld-musl-${muslArch}.so.1 where muslArch is "x86_64" for x64 and "aarch64" otherwise, then checks combined stdout/stderr from ldd --version for "musl"; failure to run ldd defaults to glibc (false).packages/cli/src/lib/binary.ts:getPlatformBinaryName() maps platforms to darwin, windows, or linux; maps architecture to arm64 or x64; adds -musl when isMusl() is true and .exe on Windows; resulting convention is sentry-<os>-<arch>[-musl][.exe].packages/cli/src/lib/binary.ts:getBinaryDownloadUrl(version) returns https://github.com/getsentry/cli/releases/download/${version}/${getPlatformBinaryName()}.packages/cli/src/lib/binary.ts exports GITHUB_RELEASES_URL = "https://api.github.com/repos/getsentry/cli/releases".packages/cli/src/lib/binary.ts:isNightlyVersion(version) identifies a nightly when the string contains "-dev.".packages/cli/src/lib/binary.ts:compareVersions(a, b) uses semver.compare (imported as semverCompare) and returns -1 | 0 | 1; isDowngrade(current, target) returns true when compareVersions(current, target) === 1.packages/cli/src/lib/binary.ts:getBinaryFilename() returns "sentry.exe" on Windows and "sentry" elsewhere.packages/cli/src/lib/binary.ts:getBinaryPaths(installPath) derives tempPath = \${installPath}.download`, oldPath = `${installPath}.old`, and lockPath = `${installPath}.lock``.packages/cli/src/lib/upgrade.ts imports binary-management helpers from ./binary.js, re-exports InstallationMethod and parseInstallationMethod for backward compatibility, and defines NIGHTLY_TAG = "nightly" plus NPM_REGISTRY_URL = "https://registry.npmjs.org/sentry".packages/cli/src/lib/upgrade.ts:getKnownCurlPaths() lazily maps KNOWN_CURL_DIRS under homedir() and appends sep to enforce directory-boundary matching; lazy computation avoids temporal-dead-zone issues from circular imports.packages/cli/src/lib/upgrade.ts:getCurlInstallPaths() prioritizes: 1. a stored DB path only when stored.method === "curl" and existsSync(dirname(stored.path)); 2. process.execPath when it starts with a known curl directory; 3. ~/.sentry/bin/<getBinaryFilename()>.SENTRY_INSTALL_DIR such as /tmp/sentry-test-install could leave a DB row after its directory was purged, causing upgrade to lock/install into a dead location and fail with ENOENT ... open '.../sentry.lock'; fix is to trust the stored path only if its directory still exists and otherwise fall through to process.execPath or ~/.sentry/bin.packages/cli/src/lib/upgrade.ts:startCleanupOldBinary() obtains oldPath from getCurlInstallPaths() and invokes cleanupOldBinary(oldPath) as fire-and-forget startup cleanup.packages/cli/src/lib/upgrade.ts:runCommand(command, args) uses spawn() with stdio: ["ignore", "pipe", "pipe"] and shell: process.platform === "win32" so Windows .cmd package-manager executables work; it accumulates stdout, intentionally drains/discards stderr via proc.stderr.resume(), trims stdout on close, maps a null close code to 1, and rejects on process error.packages/cli/src/lib/upgrade.ts:isInstalledWith(pm) runs Yarn as yarn global list --depth=0, other package managers as <pm> list -g sentry, and returns true only for exit code 0 with stdout containing "sentry@"; exceptions return false.packages/cli/src/lib/upgrade.ts:isHomebrewInstall() resolves process.execPath with realpathSync(), falls back to the unresolved path if resolution throws, and identifies Homebrew when the path contains "/Cellar/".packages/cli/src/lib/upgrade.ts:detectPackageManagerFromPath() inspects process.argv[1]; it returns null without a node_modules segment, "pnpm" when the path includes ".pnpm", "bun" when it includes ".bun", and otherwise "npm" for npm/Yarn-classic-style node_modules layouts.packages/cli/src/lib/upgrade.ts:detectLegacyInstallationMethod() checks known curl paths first, then package managers in exact order ["npm", "pnpm", "bun", "yarn"], then detectPackageManagerFromPath(), and finally returns "unknown".packages/cli/src/lib/upgrade.ts:detectInstallationMethod() uses exact priority: 1. Homebrew realpath detection; 2. stored getInstallInfo().method; 3. legacy detection; 4. best-effort persistence of a non-"unknown" legacy result using setInstallInfo({ method: legacyMethod, path: process.execPath, version: CLI_VERSION }).Failed to persist install info (DB may be read-only) with the "upgrade" scoped logger.packages/cli/src/lib/upgrade.ts must preserve the original stream error when closing/flushing also fails."drain" after failure; the implementation must not remain hung waiting for "drain" and must account for the error path while backpressure waiting is active.packages/cli/src/lib/upgrade.ts listens for writer "error", writes chunks with writer.write(chunk), and conditionally waits for "drain" when write() returns false.packages/cli/src/lib/upgrade.ts verifies that a download produced a real, non-empty file before allowing the caller to proceed.packages/cli/test/lib/patch-cache.test.ts, packages/cli/test/lib/db/release-channel.test.ts, and packages/cli/test/lib/db/install-info.test.ts.packages/cli/src/lib/db/release-channel.ts, packages/cli/src/lib/db/install-info.ts, and packages/cli/src/lib/patch-cache.ts.