fix(init): detect Bun and invoking package manager reliably#139
Conversation
|
/bigbonk review |
commit: |
There was a problem hiding this comment.
Good fix for #109. The detection priority (lockfile > package.json#packageManager > npm_config_user_agent > npm fallback) is well-chosen and matches how tools like Corepack and @antfu/ni handle this. Tests pass, deploy tests are unaffected.
A few observations:
Dual-purpose parsePackageManagerName — This function silently handles two different string formats (the name@version packageManager field and the name/version ... user-agent). It works correctly today, but the implicit format detection could be a source of subtle bugs if a new format is added later. Consider either splitting into two functions or adding a comment that the dual-format behavior is intentional. Not blocking.
Deterministic npm fallback test — The old "calls exec with npm when no lock file exists" test was implicitly relying on whatever npm_config_user_agent happened to be set in the environment. The new version explicitly clears it via withUserAgent(undefined, ...), making it deterministic. Good improvement.
withUserAgent and parallelism — The helper mutates process.env globally. Tests within a describe block run sequentially by default in Vitest, so this is fine today. If the test runner config ever enables concurrent execution within a file, this would need isolated workers or a different approach. Worth a brief comment in the helper.
Overall this is a clean, well-tested fix. The code is straightforward and the test coverage is solid.
| } | ||
|
|
||
| return null; | ||
| } |
There was a problem hiding this comment.
Nit: the Bun lockfile check on line 121 returns inline (return "bun") while the npm lockfile check on lines 122-124 uses a block with braces. Consider using the block form for both for consistency:
| } | |
| if ( | |
| fs.existsSync(path.join(root, "bun.lockb")) || | |
| fs.existsSync(path.join(root, "bun.lock")) | |
| ) { | |
| return "bun"; | |
| } |
(This comment is on the wrong line due to GitHub API constraints — it refers to line 121.)
| const fromPkg = detectPackageManagerFromPackageJson(root); | ||
| if (fromPkg) return fromPkg; | ||
|
|
||
| const fromUA = parsePackageManagerName(process.env.npm_config_user_agent); |
There was a problem hiding this comment.
Reading process.env.npm_config_user_agent directly makes this function impure — the same root can return different results depending on the environment. This is the correct behavior for the use case (detecting the invoking PM), but it makes the function harder to test in isolation. If you ever need to unit-test detectPackageManagerName directly (rather than through init()), consider accepting an optional env parameter with process.env as the default.
|
Review submitted successfully. Here's a summary of what I reviewed: PR #139: fix(init): detect Bun and invoking package manager reliably The PR fixes issue #109 where What's good:
Feedback posted:
|
b409eb7 to
e20e62b
Compare
- Combine bun.lock/bun.lockb checks into block form for consistency with the npm lockfile check - Accept optional env parameter (defaults to process.env) so the function can be unit-tested without mutating global state
Summary
Fixes package manager detection for
vinext init/ deploy dependency installs when lock files are missing or Bun is used.What changed
bun.lockb(legacy)bun.lock(current)package.json#packageManagerwhen no lockfile exists.npm_config_user_agentas a final hint (e.g.bun x vinext init,pnpm dlx vinext init).detectPackageManagerName()indetectPackageManager()to keep behavior consistent.Why
Issue #109 reports that running
bun x vinext initstill installs deps via npm. This happened because detection only checked lock files and only recognizedbun.lockb.Fixes #109
Test plan
pnpm -s test tests/init.test.tspnpm -s test tests/deploy.test.tsNew coverage (init tests)
bun.lockexistspackageManagerfrom package.json when lockfiles are missingnpm_config_user_agent