Skip to content

Commit 9b56482

Browse files
authored
[codex] Document and harden helper binstub PATH fix (#1201)
## Summary - Adds an `[Unreleased]` changelog entry for #1200 as the `10.2.1` patch-release item. - Treats `PATH=""` as a single empty PATH entry, matching shell lookup semantics by resolving it to the launch directory in helper binstubs. - Adds regression coverage for a wholly empty PATH alongside the existing leading/trailing empty PATH entry cases. ## Review context - Adversarial Claude review was triggered on the merged #1200 fix and completed successfully: https://github.com/shakacode/shakapacker/actions/runs/28724619218 - Claude final review comment: #1200 (comment) - Claude found no blocker in the #1200 code path, but flagged the missing changelog entry as a release-process blocker and noted the untested `PATH=""` edge case addressed here. - Local Codex review of `v10.2.0..main` found no actionable issues. ## Validation - `bundle exec rspec spec/shakapacker/helper_binstubs_spec.rb spec/shakapacker/binstub_sync_spec.rb` - `ruby -c lib/install/bin/shakapacker-config && ruby -c lib/install/bin/diff-bundler-config && ruby -c spec/dummy/bin/shakapacker-config` - `yarn test --runInBand test/configExporter/createBinStub.test.js test/package/configExporter/cli.test.js` - `bundle exec rubocop --cache false lib/install/bin/shakapacker-config lib/install/bin/diff-bundler-config spec/dummy/bin/shakapacker-config spec/shakapacker/helper_binstubs_spec.rb` - `yarn type-check` - `git diff --check` - `.agents/bin/validate` ## Release note Yes: because `v10.2.0` shipped the Ruby-binstub regression and #1200 is the only code delta from `v10.2.0` to `main`, this should be released as `10.2.1`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed shell-compatible helper binstub behavior to restore reliable Node lookup when `PATH` is unset/empty. * Improved `PATH` normalization by defensively handling empty/blank values and preserving trailing-empty fields, ensuring consistent absolute-path `PATH` construction. * Applied the same more robust `PATH` handling to generated Ruby binstubs and related helper scripts. * **Tests** * Expanded helper binstubs coverage to include a wholly empty (`""`) `PATH` case. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent aa94c79 commit 9b56482

6 files changed

Lines changed: 22 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
## [Unreleased]
1111

12+
### Fixed
13+
14+
- **Fixed helper binstubs delegating Node resolution to Ruby `exec` in unset and empty `PATH` environments.** [PR #1200](https://github.com/shakacode/shakapacker/pull/1200) and [PR #1201](https://github.com/shakacode/shakapacker/pull/1201) by [justin808](https://github.com/justin808). Restores shell-compatible Node lookup for `bin/shakapacker-config` and `bin/diff-bundler-config` after the `v10.2.0` Ruby-binstub regression, while keeping friendly missing-Node errors for `ENOENT` and `EACCES`.
15+
1216
## [v10.2.0] - July 3, 2026
1317

1418
### Added

lib/install/bin/diff-bundler-config

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ end
2626
def shakapacker_exec_env(launch_dir)
2727
return {} unless ENV.key?("PATH")
2828

29-
normalized_path = ENV["PATH"].split(File::PATH_SEPARATOR, -1).map do |entry|
29+
path_entries = ENV["PATH"].split(File::PATH_SEPARATOR, -1)
30+
path_entries = [""] if path_entries.empty?
31+
32+
normalized_path = path_entries.map do |entry|
3033
entry.empty? ? launch_dir : File.absolute_path(entry, launch_dir)
3134
end.join(File::PATH_SEPARATOR)
3235

lib/install/bin/shakapacker-config

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ end
2626
def shakapacker_exec_env(launch_dir)
2727
return {} unless ENV.key?("PATH")
2828

29-
normalized_path = ENV["PATH"].split(File::PATH_SEPARATOR, -1).map do |entry|
29+
path_entries = ENV["PATH"].split(File::PATH_SEPARATOR, -1)
30+
path_entries = [""] if path_entries.empty?
31+
32+
normalized_path = path_entries.map do |entry|
3033
entry.empty? ? launch_dir : File.absolute_path(entry, launch_dir)
3134
end.join(File::PATH_SEPARATOR)
3235

package/configExporter/cli.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,10 @@ end
560560
def shakapacker_exec_env(launch_dir)
561561
return {} unless ENV.key?("PATH")
562562
563-
normalized_path = ENV["PATH"].split(File::PATH_SEPARATOR, -1).map do |entry|
563+
path_entries = ENV["PATH"].split(File::PATH_SEPARATOR, -1)
564+
path_entries = [""] if path_entries.empty?
565+
566+
normalized_path = path_entries.map do |entry|
564567
entry.empty? ? launch_dir : File.absolute_path(entry, launch_dir)
565568
end.join(File::PATH_SEPARATOR)
566569

spec/dummy/bin/shakapacker-config

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ end
2626
def shakapacker_exec_env(launch_dir)
2727
return {} unless ENV.key?("PATH")
2828

29-
normalized_path = ENV["PATH"].split(File::PATH_SEPARATOR, -1).map do |entry|
29+
path_entries = ENV["PATH"].split(File::PATH_SEPARATOR, -1)
30+
path_entries = [""] if path_entries.empty?
31+
32+
normalized_path = path_entries.map do |entry|
3033
entry.empty? ? launch_dir : File.absolute_path(entry, launch_dir)
3134
end.join(File::PATH_SEPARATOR)
3235

spec/shakapacker/helper_binstubs_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,11 @@ def exec(*args)
537537
end
538538

539539
{
540+
"wholly empty" => "",
540541
"leading" => "#{File::PATH_SEPARATOR}/nonexistent",
541542
"trailing" => "/nonexistent#{File::PATH_SEPARATOR}"
542543
}.each do |position, path_value|
543-
it "honors a #{position} empty PATH entry as the current directory for #{command}" do
544+
it "honors a #{position} PATH entry as the current directory for #{command}" do
544545
Dir.mktmpdir("shakapacker-binstub-") do |app_path|
545546
File.write(File.join(app_path, "Gemfile"), "")
546547
FileUtils.mkdir_p(File.join(app_path, "bin"))

0 commit comments

Comments
 (0)