@@ -249,6 +249,16 @@ def self.bin_path(name, exec_name = nil, *requirements)
249249 find_spec_for_exe ( name , exec_name , requirements ) . bin_file exec_name
250250 end
251251
252+ def self . find_and_activate_spec_for_exe ( name , exec_name , requirements )
253+ spec = find_spec_for_exe name , exec_name , requirements
254+ Gem ::LOADED_SPECS_MUTEX . synchronize do
255+ spec . activate
256+ finish_resolve
257+ end
258+ spec
259+ end
260+ private_class_method :find_and_activate_spec_for_exe
261+
252262 def self . find_spec_for_exe ( name , exec_name , requirements )
253263 raise ArgumentError , "you must supply exec_name" unless exec_name
254264
@@ -273,6 +283,35 @@ def self.find_spec_for_exe(name, exec_name, requirements)
273283 end
274284 private_class_method :find_spec_for_exe
275285
286+ ##
287+ # Find and load the full path to the executable for gem +name+. If the
288+ # +exec_name+ is not given, an exception will be raised, otherwise the
289+ # specified executable's path is returned. +requirements+ allows
290+ # you to specify specific gem versions.
291+ #
292+ # A side effect of this method is that it will activate the gem that
293+ # contains the executable.
294+ #
295+ # This method should *only* be used in bin stub files.
296+
297+ def self . activate_and_load_bin_path ( name , exec_name = nil , *requirements )
298+ spec = find_and_activate_spec_for_exe name , exec_name , requirements
299+
300+ if spec . name == "bundler"
301+ # Make sure there's no version of Bundler in `$LOAD_PATH` that's different
302+ # from the version we just activated. If that was the case (it happens
303+ # when testing Bundler from ruby/ruby), we would load Bundler extensions
304+ # to RubyGems from the copy in `$LOAD_PATH` but then load the binstub from
305+ # an installed copy, causing those copies to be mixed and yet more
306+ # redefinition warnings.
307+ #
308+ require_path = $LOAD_PATH. resolve_feature_path ( "bundler" ) . last . delete_suffix ( "/bundler.rb" )
309+ Gem . load_bundler_extensions ( spec . version ) if spec . full_require_paths . include? ( require_path )
310+ end
311+
312+ load spec . bin_file ( exec_name )
313+ end
314+
276315 ##
277316 # Find the full path to the executable for gem +name+. If the +exec_name+
278317 # is not given, an exception will be raised, otherwise the
@@ -285,12 +324,7 @@ def self.find_spec_for_exe(name, exec_name, requirements)
285324 # This method should *only* be used in bin stub files.
286325
287326 def self . activate_bin_path ( name , exec_name = nil , *requirements ) # :nodoc:
288- spec = find_spec_for_exe name , exec_name , requirements
289- Gem ::LOADED_SPECS_MUTEX . synchronize do
290- spec . activate
291- finish_resolve
292- end
293- spec . bin_file exec_name
327+ find_and_activate_spec_for_exe ( name , exec_name , requirements ) . bin_file exec_name
294328 end
295329
296330 ##
@@ -636,6 +670,30 @@ def self.load_safe_marshal
636670 @safe_marshal_loaded = true
637671 end
638672
673+ ##
674+ # Load Bundler extensions to RubyGems, making sure to avoid redefinition
675+ # warnings in platform constants
676+
677+ def self . load_bundler_extensions ( version )
678+ return unless version <= "2.6.9"
679+
680+ previous_platforms = { }
681+
682+ platform_const_list = [ "JAVA" , "MSWIN" , "MSWIN64" , "MINGW" , "X64_MINGW_LEGACY" , "X64_MINGW" , "UNIVERSAL_MINGW" , "WINDOWS" , "X64_LINUX" , "X64_LINUX_MUSL" ]
683+
684+ platform_const_list . each do |platform |
685+ previous_platforms [ platform ] = Gem ::Platform . const_get ( platform )
686+ Gem ::Platform . send ( :remove_const , platform )
687+ end
688+
689+ require "bundler/rubygems_ext"
690+
691+ platform_const_list . each do |platform |
692+ Gem ::Platform . send ( :remove_const , platform ) if Gem ::Platform . const_defined? ( platform )
693+ Gem ::Platform . const_set ( platform , previous_platforms [ platform ] )
694+ end
695+ end
696+
639697 ##
640698 # The file name and line number of the caller of the caller of this method.
641699 #
@@ -1144,7 +1202,7 @@ def self.use_gemdeps(path = nil)
11441202
11451203 ENV [ "BUNDLE_GEMFILE" ] ||= File . expand_path ( path )
11461204 require_relative "rubygems/user_interaction"
1147- require_relative "rubygems/bundler_integration "
1205+ require "bundler "
11481206 begin
11491207 Gem ::DefaultUserInteraction . use_ui ( ui ) do
11501208 Bundler . ui . silence do
0 commit comments