Repository navigation
Keep ruby unit tests off the host Bundler env - #2066
Conversation
The core unit tests read BUNDLE_* vars and the user's ~/.bundle/config straight from the process env. A developer with BUNDLE_GEMFILE exported saw 156 core lib tests fail on a clean checkout, BUNDLE_APP_CONFIG 5, and a ~/.bundle/config with path.system/gemfile 154 (#1919). Under cfg(test) only, ruby_crawler's BUNDLE_* reads and its home lookup now see only values a live EnvGuard holds, the seam go_env (#2057) uses. Non-test builds are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011f9aeNvBQRDzpbqHAEjNAY
|
bugbot run Generated by Claude Code |
PR SummaryLow Risk Overview A serial unit test Reviewed by Cursor Bugbot for commit 75b2596. Configure here. |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 75b2596. Configure here.
|
Ready for review (burn-down agent).
Generated by Claude Code |
Final review briefWhat it does. Test-only change. All 31 Risk: low. The non-test Look here
Verified
Changes I made. None. Open questions. None. Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
/code-review high found bundler_source_mirror still read BUNDLE_MIRROR__* values from the host env. Route the values through bundle_env. The seam test now sets a probe key no code reads, so a gem child spawned by a concurrent test can't see it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011f9aeNvBQRDzpbqHAEjNAY
|
[agent] Heads-up: the final-review brief above covers Generated by Claude Code |
Final review brief (head
|
Problem
CI was healthy this run: the merge queue was empty, all merge_group runs since 11-12 18:56 UTC passed, main's latest push run (43324491043) and today's nightly (43373720347) are green, and nothing was queued. The two recent red nightlies (11-10, 11-12, Windows) were already fixed by #2049 and #2061. So this run takes a priority-4 robustness target from #1919, the same class as #2054–#2057 and #2063–#2065: core unit tests that pass only because CI's env is clean.
The hostile-env probe on #1919 found
BUNDLE_GEMFILEandBUNDLE_APP_CONFIGstill leak into the core lib tests. Measured onorigin/main(de81f1b),cargo test -p socket-patch-core --lib:BUNDLE_GEMFILE=<other dir>/GemfileBUNDLE_APP_CONFIG=<dir with config>HOMEwith.bundle/configsettingBUNDLE_PATH__SYSTEM+BUNDLE_GEMFILEBUNDLE_PATH__SYSTEM=true BUNDLE_IGNORE_CONFIG=1Failing modules on main:
vendor::gem,vex::discover::gem,vendor::lock_inventory,vex::discover,upstream::gem.Root cause
crawlers/ruby_crawler.rsreads everyBUNDLE_*var (31 call sites) withstd::env::var_osand the user's global Bundler config throughambient_home()→home_dir(), with no test seam.BundlerEnv/*_with_envseams exist, but the vendor and vex paths reach the ambient wrappers.Fix
Under
cfg(test)only, two small seams inruby_crawler.rs, same pattern asutils::go_env::process_env(#2057):bundle_env(key)replaces the 31std::env::var_os("BUNDLE_*")reads; in tests it returns only values a liveEnvGuardholds (test_env::guarded_var).ambient_home()in tests resolvesHOME/USERPROFILEthroughhome_from_envover guarded values only, so a developer's~/.bundle/configis never read.Non-test builds are byte-for-byte the old code path (
std::env::var_os,home_dir()), including the CLI integration tests, which link the non-test core. New testbundler_env_sees_only_guarded_variables(#[serial]) pins both halves: an unguarded export is not seen, guarded values are.This is deliberately the minimal seam; it doesn't touch the Bundler-settings parsing that #1935 plans to move, so it shouldn't conflict with that refactor.
Proof
cargo clippy --locked -p socket-patch-core --all-features -- -D warnings(CI invocation) is clean;rustfmt --checkclean on the touched file.--all-targetsonly shows a pre-existingcloned_ref_to_slice_refslint in test code this PR doesn't touch.Review (
/code-review high+ Bugbot)Bugbot: no findings on 75b2596. Fixed in 01c8817 from
/code-review high:bundler_source_mirrorstill readBUNDLE_MIRROR__*values from the host. They now go throughbundle_env. The core lib passes 7721/7721 withBUNDLE_MIRROR__ALLexported, alone and combined with every Bundler row in the table.BUNDLE_GEMFILEraw for a moment. It now sets a probe key that no code reads, so agemchild spawned by a concurrent test can't inherit anything that matters.Not changed, and why:
get_global_gem_pathsuseshome_dir()and thegem envfallback spawnsgemwith the host env. Global crawls ask the host's Ruby by design, and seaming the home lookup there would still leave the subprocess. No core test failed under the hostile envs above. This is a follow-up for Crawler unit tests read the developer's real HOME, YARN_NODE_LINKER and VIRTUAL_ENV: 12 pkg_managers/pnpm_layout tests fail under a user nodeLinker setting #1919.guarded_var(UTF-8String), so a non-UTF-8 guarded value reads as unset. No test guards a non-UTF-8BUNDLE_*value. AnOsStringvariant belongs intest_env.rs, which open Keep composer unit tests off the host's env #2064 edits.BundlerEnv::ambient()instead of 31 call-site swaps. That overlaps the Bundler-settings move planned in Move Bundler settings parsing out of ruby_crawler into formats/gem/settings.rs, and read .bundle/config keys with one parser (two drifted today) #1935, which this PR deliberately stays clear of.Generated by Claude Code