-
Notifications
You must be signed in to change notification settings - Fork 0
fix(npm-globals): purge bun npm shim that breaks @railway/cli install #2022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,6 +115,20 @@ missing_native_optional_dep() { | |
| [ "$matched" -eq 1 ] && [ "$present" -eq 0 ] | ||
| } | ||
|
|
||
| # Remove the npm "bun" wrapper package from global node_modules. | ||
| # Some transitive deps pull in the "bun" npm package whose postinstall | ||
| # downloads a bun binary. When that postinstall is skipped/fails, it leaves | ||
| # a stub .bin/bun shim that shadows the real system bun, breaking every | ||
| # subsequent postinstall that shells out to bun (e.g. @railway/cli). | ||
| purge_bun_npm_shim() { | ||
| local gm="${HOME}/.bun/install/global/node_modules" | ||
| if [ -d "${gm}/bun" ]; then | ||
| rm -rf "${gm}/bun" | ||
| rm -f "${gm}/.bin/bun" "${gm}/.bin/bunx" | ||
| echo "Removed broken bun npm shim from global node_modules" | ||
| fi | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Purge doesn't cover Today this is not immediately harmful because bash's |
||
|
|
||
| echo "Installing npm global packages from package.json using bun..." | ||
| cd "${HOME}/dotfiles" | ||
|
|
||
|
|
@@ -154,6 +168,8 @@ if [ "${#STALE[@]}" -gt 0 ]; then | |
| done | ||
| fi | ||
|
|
||
| purge_bun_npm_shim | ||
|
|
||
| # Build list of packages that need installing or updating | ||
| GLOBAL_MODULES="${HOME}/.bun/install/global/node_modules" | ||
| DEPS=$(jq -r '.dependencies | to_entries[] | "\(.key)=\(.value)"' "$PACKAGE_JSON" 2>/dev/null || true) | ||
|
|
@@ -198,6 +214,7 @@ if [ "${#MISSING[@]}" -gt 0 ]; then | |
| echo "Installing ${#MISSING[@]} missing packages..." | ||
| for dep in "${MISSING[@]}"; do | ||
| timeout 600 bun add --global "$dep" 2>/dev/null || echo "Install failed: $dep" | ||
| purge_bun_npm_shim | ||
| done | ||
| else | ||
| echo "All npm global packages already installed" | ||
|
|
@@ -222,6 +239,7 @@ if [ -n "$OVERRIDES" ]; then | |
| jq --argjson overrides "$OVERRIDES" '.overrides = $overrides' "$GLOBAL_PKG" >"${GLOBAL_PKG}.tmp" && | ||
| mv "${GLOBAL_PKG}.tmp" "$GLOBAL_PKG" | ||
| (cd "${HOME}/.bun/install/global" && bun install 2>/dev/null || true) | ||
| purge_bun_npm_shim | ||
| echo "Applied dependency overrides to global install" | ||
| fi | ||
| fi | ||
|
|
@@ -319,6 +337,7 @@ if [ -n "$OPTIONAL_DEPS" ]; then | |
| fi | ||
| echo "Installing platform-native: $spec" | ||
| timeout 600 bun add --global "$spec" --minimum-release-age 0 2>/dev/null || echo "Install failed: $spec" | ||
| purge_bun_npm_shim | ||
| # Verify the payload actually materialized; bun can silently no-op. | ||
| if [ ! -f "${GLOBAL_MODULES}/${dep}/package.json" ]; then | ||
| echo "Warning: $dep still missing after install ($spec)" >&2 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -187,6 +187,28 @@ The output should include 'find' | |
| End | ||
| End | ||
|
|
||
| Describe 'bun npm shim purge' | ||
| It 'defines a purge_bun_npm_shim function' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: These tests only verify that certain string patterns exist in the source file (via Prompt for AI agents |
||
| When run bash -c "grep 'purge_bun_npm_shim()' '$SCRIPT'" | ||
| The output should include 'purge_bun_npm_shim' | ||
| End | ||
|
|
||
| It 'removes the bun package from global node_modules' | ||
| When run bash -c "grep 'rm -rf.*gm.*bun' '$SCRIPT'" | ||
| The output should include 'bun' | ||
| End | ||
|
|
||
| It 'removes bun shims from .bin' | ||
| When run bash -c "grep 'rm -f.*\.bin/bun' '$SCRIPT'" | ||
| The output should include '.bin/bun' | ||
| End | ||
|
|
||
| It 'calls purge after each bun add --global' | ||
| When run bash -c "grep -A 1 'bun add --global.*dep.*2>/dev/null' '$SCRIPT' | grep 'purge_bun_npm_shim'" | ||
| The output should include 'purge_bun_npm_shim' | ||
| End | ||
| End | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Behavior not exercised by tests: These four cases only grep the source file for literal strings ( The file already has good precedent for real integration tests — see |
||
|
|
||
| Describe 'native addon repair' | ||
| It 'has a sqlite3 native binding repair step' | ||
| When run bash -c "grep 'repair_sqlite3_native_binding' '$SCRIPT'" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a previous run was interrupted, or if the
${gm}/bundirectory was deleted/cleaned up but the shims in${gm}/.binwere left behind, they will become dangling symlinks.In Unix-like systems, a dangling symlink in a directory that is in the
PATH(likenode_modules/.binduring postinstall scripts) will still shadow the command and cause execution to fail with aNo such file or directoryerror, rather than falling back to the real systembun.Since the current check only looks for the directory
[ -d "${gm}/bun" ], it will skip purging the shims if the directory is gone but the dangling symlinks remain.To make this robust against dangling symlinks, we should also check for the existence of the symlinks/files themselves using
[ -L ... ]and[ -e ... ].