Skip to content

Commit b47f6b0

Browse files
committed
Fix Bundler removing executables after creating them
When running a fresh `bundle install` with gems that contains executables, Bundler will generate binstubs but soon after will remove them. This is a regression introduced in 573ffad. This results in doing `bundle install && bundle exec foo` to raise an error saying `foo` couldn't be found. This issue only appears if `BUNDLE_CLEAN` is set. At the end of the installation process, when Bundler has installed gems and generated binstubs, it runs the cleanup. 1. It [detects](https://github.com/ruby/rubygems/blob/4f8aa3b40cded3465bb2cd761e9ce7f8673b7fcb/bundler/lib/bundler/runtime.rb#L182) the executable for the current specs 2. Any existing executables not detected is then removed https://github.com/ruby/rubygems/blob/4f8aa3b40cded3465bb2cd761e9ce7f8673b7fcb/bundler/lib/bundler/runtime.rb#L194. The issue being that 1. now returns an empty array where as it should return the executables of the gems from the current bundle. The problem is in 573ffad where we removed the `executables` method from the `EndpointSpecification`. When Bundler reads the lockfile, it creates a `EndpointSpecification` object for each spec. At this point, the EndpointSpecification doesn't know about the `executables` of a gem. Once Bundler fetches the `gemspec` from the remote, it swaps the the "spec" with the real one and from here knows what executables the gem has. Reintroduce the `executables` method and the `bindir` in the EndpointSpecification class. From what I'm seeing, the removal of those wasn't needed to resolve the issue where Bundler remembers CLI flags. This is probably an oversight.
1 parent 4f8aa3b commit b47f6b0

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

bundler/lib/bundler/endpoint_specification.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,28 @@ def load_paths
6060
end
6161
end
6262

63+
# needed for binstubs
64+
def executables
65+
if @remote_specification
66+
@remote_specification.executables
67+
elsif _local_specification
68+
_local_specification.executables
69+
else
70+
super
71+
end
72+
end
73+
74+
# needed for bundle clean
75+
def bindir
76+
if @remote_specification
77+
@remote_specification.bindir
78+
elsif _local_specification
79+
_local_specification.bindir
80+
else
81+
super
82+
end
83+
end
84+
6385
# needed for post_install_messages during install
6486
def post_install_message
6587
if @remote_specification

bundler/spec/commands/install_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,25 @@ def run
18851885
expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables)
18861886
end
18871887

1888+
it "prevents removing binstubs when BUNDLE_CLEAN is set" do
1889+
build_repo4 do
1890+
build_gem "kamal", "4.0.6" do |s|
1891+
s.executables = ["kamal"]
1892+
end
1893+
end
1894+
1895+
gemfile = <<~G
1896+
source "https://gem.repo4"
1897+
gem "kamal"
1898+
G
1899+
1900+
install_gemfile(gemfile, env: { "BUNDLE_CLEAN" => "true", "BUNDLE_PATH" => "vendor/bundle" })
1901+
1902+
expected_executables = [vendored_gems("bin/kamal").to_s]
1903+
expected_executables << vendored_gems("bin/kamal.bat").to_s if Gem.win_platform?
1904+
expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables)
1905+
end
1906+
18881907
it "preserves lockfile versions conservatively" do
18891908
build_repo4 do
18901909
build_gem "mypsych", "4.0.6" do |s|

0 commit comments

Comments
 (0)