Skip to content

fix(upgrade): detectBunLink fails because bun resolves symlinks in argv[1]#704

Closed
MrAladdin wants to merge 1 commit into
garrytan:masterfrom
MrAladdin:fix/bun-link-detection
Closed

fix(upgrade): detectBunLink fails because bun resolves symlinks in argv[1]#704
MrAladdin wants to merge 1 commit into
garrytan:masterfrom
MrAladdin:fix/bun-link-detection

Conversation

@MrAladdin
Copy link
Copy Markdown

@MrAladdin MrAladdin commented May 7, 2026

Problem

gbrain upgrade returns unknown for bun-link installs — the README's recommended standalone install path (git clone && bun install && bun link).

$ gbrain upgrade
Detected install method: unknown
Could not detect installation method.

Root cause: detectBunLink() (added in v0.28.5, closes #656) gates on lstatSync(process.argv[1]).isSymbolicLink(). But bun resolves the entire symlink chain before setting process.argv[1], so argv[1] is already the real path (e.g. /path/to/gbrain/src/cli.ts), never a symlink. The check always returns false, short-circuiting the git-config walk that would have correctly identified the repo.

Verified with a minimal reproduction:

// Create a symlink and run via shebang
ln -sf /tmp/test.ts /tmp/test-link
/tmp/test-link
// process.argv[1] = "/private/tmp/test.ts" (resolved), NOT "/tmp/test-link"
// lstatSync(argv1).isSymbolicLink() === false

Related: #368 (open — the broader bun-link upgrade story), #656 (closed by v0.28.5 but fix incomplete), #538 (open PR with alternative approach, stale against master).

Fix

Minimal change to the existing detectBunLink():

  1. Remove the broken symlink gatelstatSync / isSymbolicLink check deleted. argv[1] is already the real path inside the checkout, which is exactly what the git-config walk needs.

  2. Return { repoRoot } instead of 'bun-link' — the upgrade path now knows the checkout location and can auto-execute the upgrade.

  3. Auto-upgrade instead of printing manual instructions — the bun-link case in runUpgrade() now runs:

    execFileSync('git', ['-C', repoRoot, 'pull', '--ff-only'], ...);
    execFileSync('bun', ['install'], { cwd: repoRoot, ... });

    Uses execFileSync with array args (no shell) per the codebase pattern in dry-fix.ts:172, addressing the shell-injection concern raised in fix(upgrade): detect README "Standalone CLI" installs as 'source' #538's review. Falls back to a clear manual command on failure.

  4. --ff-only prevents surprise merge commits — if the user has local commits, git gives a clear error rather than silently creating a merge.

Before

$ gbrain upgrade
Detected install method: unknown
Could not detect installation method.

After

$ gbrain upgrade
Detected install method: bun-link
Upgrading bun-link source clone at /path/to/gbrain...
Already up to date.

Tests

test/upgrade.test.ts — 3 new tests (12 → 15 total, all pass):

  • detectBunLink does not gate on isSymbolicLink — regression guard; extracts the function body and asserts no isSymbolicLink / lstatSync
  • detectBunLink returns repoRoot, not a string literal — pins the return shape contract
  • bun-link upgrade uses execFileSync for shell-injection safety — pins execFileSync with array args (not execSync with template strings)
$ bun test test/upgrade.test.ts
 15 pass, 0 fail, 32 expect() calls

Typecheck passes (bun run typecheck).

Out of scope


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

…gv[1]

bun resolves the entire symlink chain before setting process.argv[1],
so lstatSync(argv1).isSymbolicLink() always returns false for bun-link
installs, short-circuiting the git-config walk that would correctly
identify the repo. Remove the symlink gate — argv[1] is already the
real path inside the checkout, which is what the walk needs.

Also: return { repoRoot } so the upgrade path can auto-execute
git pull + bun install via execFileSync (no shell injection surface).

Fixes garrytan#368, supersedes incomplete v0.28.5 fix for garrytan#656.
@garrytan
Copy link
Copy Markdown
Owner

Closing — your fix landed in master via the v0.30.3 fix-wave PR #776 (merged at ff53a4c9): "detectBunLink symlink-in-argv[1] fix".

Thank you for the contribution — credit is preserved in the v0.30.3 CHANGELOG entry. 🙏

@garrytan garrytan closed this May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gbrain upgrade returns 'unknown' install method for bun-link installs

2 participants