From fef68d2374fbc619fe8db2226f70f1c8352375b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 24 Sep 2018 19:56:16 -0300 Subject: [PATCH 01/24] Root is already a Pathname --- bundler/lib/bundler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 86882062852c..791ea1abbde7 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -299,7 +299,7 @@ def app_config_path if app_config_pathname.absolute? app_config_pathname else - app_config_pathname.expand_path(root) + root.join(app_config_pathname) end else root.join(".bundle") From 1c545628dcd2e7745def35d1c822fde41ec77d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 24 Sep 2018 19:57:07 -0300 Subject: [PATCH 02/24] Small DRY up --- bundler/lib/bundler.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 791ea1abbde7..96c2cd38231a 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -297,13 +297,11 @@ def app_config_path app_config_pathname = Pathname.new(app_config) if app_config_pathname.absolute? - app_config_pathname - else - root.join(app_config_pathname) + return app_config_pathname end - else - root.join(".bundle") end + + root.join(app_config || ".bundle") end def app_cache(custom_path = nil) From edfbbffa60bce3c3a64c60944937276b3111133e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 25 Sep 2018 19:13:06 -0300 Subject: [PATCH 03/24] DRY up settings instantiation --- bundler/lib/bundler.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 96c2cd38231a..c3dec7113538 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -301,7 +301,7 @@ def app_config_path end end - root.join(app_config || ".bundle") + app_config_root.join(app_config || ".bundle") end def app_cache(custom_path = nil) @@ -328,8 +328,6 @@ def rm_rf(path) def settings @settings ||= Settings.new(app_config_path) - rescue GemfileNotFound - @settings = Settings.new(Pathname.new(".bundle").expand_path) end # @return [Hash] Environment present before Bundler was activated @@ -697,5 +695,11 @@ def with_env(env) ensure ENV.replace(backup) end + + def app_config_root + root + rescue GemfileNotFound + Pathname.pwd + end end end From 35f7b7bf10be2d42290b1248f71f129ffe6030a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 16 Feb 2020 21:56:14 +0100 Subject: [PATCH 04/24] Remove unneeded mock --- bundler/spec/bundler/definition_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/bundler/spec/bundler/definition_spec.rb b/bundler/spec/bundler/definition_spec.rb index 2618786e7ce8..32aeb1b91604 100644 --- a/bundler/spec/bundler/definition_spec.rb +++ b/bundler/spec/bundler/definition_spec.rb @@ -5,7 +5,6 @@ RSpec.describe Bundler::Definition do describe "#lock" do before do - allow(Bundler).to receive(:settings) { Bundler::Settings.new(".") } allow(Bundler::SharedHelpers).to receive(:find_gemfile) { Pathname.new("Gemfile") } allow(Bundler).to receive(:ui) { double("UI", :info => "", :debug => "") } end From 492507b317b4534820e3646ec93023131ef57c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 16 Feb 2020 21:59:22 +0100 Subject: [PATCH 05/24] Settings root is already a Pathname --- bundler/lib/bundler/settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundler/lib/bundler/settings.rb b/bundler/lib/bundler/settings.rb index 8f263cd0129e..dbe9b985da31 100644 --- a/bundler/lib/bundler/settings.rb +++ b/bundler/lib/bundler/settings.rb @@ -447,7 +447,7 @@ def global_config_file end def local_config_file - Pathname.new(@root).join("config") if @root + @root.join("config") if @root end def load_config(config_file) From bc204810ba60bf18b3fefe0ab7a4c264164edfe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 25 Sep 2018 20:01:45 -0300 Subject: [PATCH 06/24] bundle_dir is already a Pathname So we can instead call `parent` on it. --- bundler/lib/bundler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index c3dec7113538..fe84f74faedd 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -288,7 +288,7 @@ def root rescue GemfileNotFound bundle_dir = default_bundle_dir raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir - Pathname.new(File.expand_path("..", bundle_dir)) + bundle_dir.parent end end From 8736266d8e541a47e6555c61fe1167b7a676a3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 3 Aug 2021 18:42:07 +0200 Subject: [PATCH 07/24] Extract some common logic to a method --- bundler/lib/bundler/shared_helpers.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index e48010232a81..1ae11617d10c 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -13,13 +13,13 @@ module SharedHelpers def root gemfile = find_gemfile raise GemfileNotFound, "Could not locate Gemfile" unless gemfile - Pathname.new(gemfile).tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path.parent + expand(gemfile).parent end def default_gemfile gemfile = find_gemfile raise GemfileNotFound, "Could not locate Gemfile" unless gemfile - Pathname.new(gemfile).tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path + expand(gemfile) end def default_lockfile @@ -200,6 +200,10 @@ def write_to_gemfile(gemfile_path, contents) private + def expand(file) + Pathname.new(file).tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path + end + def validate_bundle_path path_separator = Bundler.rubygems.path_separator return unless Bundler.bundle_path.to_s.split(path_separator).size > 1 From f203480d2887cc466de5c767829ae63040db5172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 11 Aug 2021 11:53:05 +0200 Subject: [PATCH 08/24] No need for explicit modules here --- bundler/lib/bundler/shared_helpers.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index 1ae11617d10c..6567fc0b8d71 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -240,7 +240,7 @@ def find_directory(*names) def search_up(*names) previous = nil - current = File.expand_path(SharedHelpers.pwd).tap{|x| x.untaint if RUBY_VERSION < "2.7" } + current = File.expand_path(pwd).tap{|x| x.untaint if RUBY_VERSION < "2.7" } until !File.directory?(current) || current == previous if ENV["BUNDLER_SPEC_RUN"] @@ -286,16 +286,16 @@ def set_bundle_variables # bundler is a default gem, exe path is separate exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file) - Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file - Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s - Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION + set_env "BUNDLE_BIN_PATH", exe_file + set_env "BUNDLE_GEMFILE", find_gemfile.to_s + set_env "BUNDLER_VERSION", Bundler::VERSION end def set_path validate_bundle_path paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR) paths.unshift "#{Bundler.bundle_path}/bin" - Bundler::SharedHelpers.set_env "PATH", paths.uniq.join(File::PATH_SEPARATOR) + set_env "PATH", paths.uniq.join(File::PATH_SEPARATOR) end def set_rubyopt @@ -303,13 +303,13 @@ def set_rubyopt setup_require = "-r#{File.expand_path("setup", __dir__)}" return if !rubyopt.empty? && rubyopt.first =~ /#{setup_require}/ rubyopt.unshift setup_require - Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ") + set_env "RUBYOPT", rubyopt.join(" ") end def set_rubylib rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR) rubylib.unshift bundler_ruby_lib unless RbConfig::CONFIG["rubylibdir"] == bundler_ruby_lib - Bundler::SharedHelpers.set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR) + set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR) end def bundler_ruby_lib From 4fd033cfaef1f1ab71a8d5ea0377db35828c683b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 11 Aug 2021 12:26:36 +0200 Subject: [PATCH 09/24] Consistent usage of `Pathname`'s --- bundler/lib/bundler/shared_helpers.rb | 22 ++++++++++----------- bundler/spec/bundler/shared_helpers_spec.rb | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index 6567fc0b8d71..f7fa8cdda535 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -13,13 +13,13 @@ module SharedHelpers def root gemfile = find_gemfile raise GemfileNotFound, "Could not locate Gemfile" unless gemfile - expand(gemfile).parent + gemfile.parent end def default_gemfile gemfile = find_gemfile raise GemfileNotFound, "Could not locate Gemfile" unless gemfile - expand(gemfile) + gemfile end def default_lockfile @@ -35,8 +35,6 @@ def default_bundle_dir bundle_dir = find_directory(".bundle") return nil unless bundle_dir - bundle_dir = Pathname.new(bundle_dir) - global_bundle_dir = Bundler.user_home.join(".bundle") return nil if bundle_dir == global_bundle_dir @@ -218,7 +216,7 @@ def validate_bundle_path def find_gemfile given = ENV["BUNDLE_GEMFILE"] - return given if given && !given.empty? + return expand(given) if given && !given.empty? find_file(*gemfile_names) end @@ -228,21 +226,21 @@ def gemfile_names def find_file(*names) search_up(*names) do |filename| - return filename if File.file?(filename) + return filename if filename.file? end end def find_directory(*names) search_up(*names) do |dirname| - return dirname if File.directory?(dirname) + return dirname if dirname.directory? end end def search_up(*names) previous = nil - current = File.expand_path(pwd).tap{|x| x.untaint if RUBY_VERSION < "2.7" } + current = pwd.tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path - until !File.directory?(current) || current == previous + until !current.directory? || current == previous if ENV["BUNDLER_SPEC_RUN"] # avoid stepping above the tmp directory when testing gemspec = if ENV["GEM_COMMAND"] @@ -253,15 +251,15 @@ def search_up(*names) end # avoid stepping above the tmp directory when testing - return nil if File.file?(File.join(current, gemspec)) + return nil if current.join(gemspec).file? end names.each do |name| - filename = File.join(current, name) + filename = current.join(name) yield filename end previous = current - current = File.expand_path("..", current) + current = current.parent end end diff --git a/bundler/spec/bundler/shared_helpers_spec.rb b/bundler/spec/bundler/shared_helpers_spec.rb index 68a24be31c69..2cd0093c5f2e 100644 --- a/bundler/spec/bundler/shared_helpers_spec.rb +++ b/bundler/spec/bundler/shared_helpers_spec.rb @@ -116,7 +116,7 @@ after { FileUtils.rm(bundled_app_gemfile) } it "returns path of the bundle Gemfile" do - expect(subject.in_bundle?).to eq("#{bundled_app}/Gemfile") + expect(subject.in_bundle?).to eq(bundled_app_gemfile) end end @@ -131,7 +131,7 @@ before { ENV["BUNDLE_GEMFILE"] = "/path/Gemfile" } it "returns ENV['BUNDLE_GEMFILE']" do - expect(subject.in_bundle?).to eq("/path/Gemfile") + expect(subject.in_bundle?).to eq(Pathname.new("/path/Gemfile").expand_path) end end From c446d9d2d55662eafa7a40cb35ce0db509f079dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 11 Aug 2021 12:44:32 +0200 Subject: [PATCH 10/24] Current working directory is already expanded --- bundler/lib/bundler/inline.rb | 2 +- bundler/lib/bundler/settings/validator.rb | 2 +- bundler/lib/bundler/shared_helpers.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bundler/lib/bundler/inline.rb b/bundler/lib/bundler/inline.rb index a718418fceb8..3b658c382629 100644 --- a/bundler/lib/bundler/inline.rb +++ b/bundler/lib/bundler/inline.rb @@ -42,7 +42,7 @@ def gemfile(install = false, options = {}, &gemfile) bundler_module = class << Bundler; self; end bundler_module.send(:remove_method, :root) def Bundler.root - Bundler::SharedHelpers.pwd.expand_path + Bundler::SharedHelpers.pwd end old_gemfile = ENV["BUNDLE_GEMFILE"] Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile" diff --git a/bundler/lib/bundler/settings/validator.rb b/bundler/lib/bundler/settings/validator.rb index 0a57ea7f0389..f054a9958a0f 100644 --- a/bundler/lib/bundler/settings/validator.rb +++ b/bundler/lib/bundler/settings/validator.rb @@ -86,7 +86,7 @@ def self.validate!(key, value, settings) root = begin Bundler.root rescue GemfileNotFound - Pathname.pwd.expand_path + Pathname.pwd end path = begin diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index f7fa8cdda535..766b16c977c6 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -238,7 +238,7 @@ def find_directory(*names) def search_up(*names) previous = nil - current = pwd.tap{|x| x.untaint if RUBY_VERSION < "2.7" }.expand_path + current = pwd.tap{|x| x.untaint if RUBY_VERSION < "2.7" } until !current.directory? || current == previous if ENV["BUNDLER_SPEC_RUN"] From fdfb34dd67ade0fb6207f3eec9026b8a220672c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Aug 2021 13:43:36 +0200 Subject: [PATCH 11/24] Simplify `default_lockfile` logic --- bundler/lib/bundler/shared_helpers.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index 766b16c977c6..92cd7f01c8b4 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -26,9 +26,9 @@ def default_lockfile gemfile = default_gemfile case gemfile.basename.to_s - when "gems.rb" then Pathname.new(gemfile.sub(/.rb$/, ".locked")) - else Pathname.new("#{gemfile}.lock") - end.tap{|x| x.untaint if RUBY_VERSION < "2.7" } + when "gems.rb" then gemfile.sub(/.rb$/, ".locked") + else gemfile.sub(/$/, ".lock") + end end def default_bundle_dir From 7352c0034d842016dddbc6d59f7fc30fdae7afc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Aug 2021 22:45:45 +0200 Subject: [PATCH 12/24] Delay cache access in `LockfileParser` It's the only part that needs "root folder resultion" to figure out the folder for the cache, but it's only needed for some things, so run that logic lazily when needed. The motivation for this refactoring is a bit complicated: * In our development environment, we use `LockfileParser` to figure out the exact version of each development dependency we need to load. We could do this via `bundler/setup` but we have never got that to work for bundler specs themselves (use bundler to test bundler). * Our usage of `LockfileParser` relies on the presence of a `.bundle/config` file in the root of the repo, otherwise "root folder resolution" would fail to find both a `Gemfile` or a `.bundle/config` file and would fail. * An upcoming bug fix to make `bundler/setup` also consider gemfile configured through `.bundle/config`, will make it so that the `.bundle/config` file at the root of this repository will be used by bundler development tasks, and that will break things. So I want to remove the `.bundle/config` file, but to do that I need to make `LockfileParser` not do root folder resolution by default. Hence, this change. --- bundler/lib/bundler/source/rubygems.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bundler/lib/bundler/source/rubygems.rb b/bundler/lib/bundler/source/rubygems.rb index 8bc3aa17e989..816b0cc0d7cf 100644 --- a/bundler/lib/bundler/source/rubygems.rb +++ b/bundler/lib/bundler/source/rubygems.rb @@ -12,7 +12,7 @@ class Rubygems < Source # Ask for X gems per API request API_REQUEST_SIZE = 50 - attr_reader :remotes, :caches + attr_reader :remotes def initialize(options = {}) @options = options @@ -21,11 +21,14 @@ def initialize(options = {}) @allow_remote = false @allow_cached = false @allow_local = options["allow_local"] || false - @caches = [cache_path, *Bundler.rubygems.gem_cache] Array(options["remotes"]).reverse_each {|r| add_remote(r) } end + def caches + @caches ||= [cache_path, *Bundler.rubygems.gem_cache] + end + def local_only! @specs = nil @allow_local = true @@ -362,9 +365,9 @@ def cached_gem(spec) def cached_path(spec) global_cache_path = download_cache_path(spec) - @caches << global_cache_path if global_cache_path + caches << global_cache_path if global_cache_path - possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" } + possibilities = caches.map {|p| "#{p}/#{spec.file_name}" } possibilities.find {|p| File.exist?(p) } end From ced824c0269626abae0530d32b81cfa82c6399c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Aug 2021 22:55:18 +0200 Subject: [PATCH 13/24] Remove committed `.bundle/config` Instead, use `ENV`, just like `bundler` tasks do. --- .bundle/config | 2 -- Rakefile | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 .bundle/config diff --git a/.bundle/config b/.bundle/config deleted file mode 100644 index 1af66845018e..000000000000 --- a/.bundle/config +++ /dev/null @@ -1,2 +0,0 @@ ---- -BUNDLE_PATH__SYSTEM: "true" diff --git a/Rakefile b/Rakefile index 18ebcfb91abc..cd9196cc4594 100644 --- a/Rakefile +++ b/Rakefile @@ -6,7 +6,7 @@ require "rake/testtask" desc "Setup Rubygems dev environment" task :setup do - sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "install", "--gemfile=bundler/tool/bundler/dev_gems.rb" + sh({ "BUNDLE_PATH__SYSTEM" => "true" }, "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "install", "--gemfile=bundler/tool/bundler/dev_gems.rb") sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--gemfile=bundler/tool/bundler/release_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--gemfile=bundler/tool/bundler/test_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--gemfile=bundler/tool/bundler/rubocop_gems.rb" @@ -19,7 +19,7 @@ end desc "Update Rubygems dev environment" task :update do - sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--gemfile=bundler/tool/bundler/dev_gems.rb" + sh({ "BUNDLE_PATH__SYSTEM" => "true" }, "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--gemfile=bundler/tool/bundler/dev_gems.rb") sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--update", "--gemfile=bundler/tool/bundler/release_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--update", "--gemfile=bundler/tool/bundler/test_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "lock", "--update", "--gemfile=bundler/tool/bundler/rubocop_gems.rb" @@ -32,7 +32,7 @@ end desc "Update the locked bundler version in dev environment" task :update_locked_bundler do |_, args| - sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--bundler", "--gemfile=bundler/tool/bundler/dev_gems.rb" + sh({ "BUNDLE_PATH__SYSTEM" => "true" }, "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--bundler", "--gemfile=bundler/tool/bundler/dev_gems.rb") sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--bundler", "--gemfile=bundler/tool/bundler/release_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--bundler", "--gemfile=bundler/tool/bundler/test_gems.rb" sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", "--bundler", "--gemfile=bundler/tool/bundler/rubocop_gems.rb" @@ -45,7 +45,7 @@ end desc "Update specific development dependencies" task :update_dev_dep do |_, args| - sh "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", *args, "--gemfile=bundler/tool/bundler/dev_gems.rb" + sh({ "BUNDLE_PATH__SYSTEM" => "true" }, "ruby", "-I", "lib", "bundler/spec/support/bundle.rb", "update", *args, "--gemfile=bundler/tool/bundler/dev_gems.rb") end desc "Setup git hooks" From 7cc0e73589870feb1097908c2e1ddee8c5445f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 16 Aug 2021 11:05:16 +0200 Subject: [PATCH 14/24] Remove case that doesn't happen in real life Rubygems `Gem.user_home` never returns `nil`. It calls `Dir.home` internally which either raises, or returns something different from `nil`, and when `Dir.home` raises, `Gem.user_home` rescues the error and returns the root path. --- bundler/lib/bundler.rb | 6 ++---- bundler/lib/bundler/settings.rb | 2 +- bundler/spec/bundler/bundler_spec.rb | 10 ---------- bundler/spec/bundler/settings_spec.rb | 4 ++-- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index fe84f74faedd..79b434964d37 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -227,11 +227,9 @@ def ruby_scope def user_home @user_home ||= begin home = Bundler.rubygems.user_home - bundle_home = home ? File.join(home, ".bundle") : nil + bundle_home = File.join(home, ".bundle") - warning = if home.nil? - "Your home directory is not set." - elsif !File.directory?(home) + warning = if !File.directory?(home) "`#{home}` is not a directory." elsif !File.writable?(home) && (!File.directory?(bundle_home) || !File.writable?(bundle_home)) "`#{home}` is not writable." diff --git a/bundler/lib/bundler/settings.rb b/bundler/lib/bundler/settings.rb index dbe9b985da31..d86f60d444fe 100644 --- a/bundler/lib/bundler/settings.rb +++ b/bundler/lib/bundler/settings.rb @@ -441,7 +441,7 @@ def global_config_file Pathname.new(ENV["BUNDLE_USER_CONFIG"]) elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty? Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config") - elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty? + else Pathname.new(Bundler.rubygems.user_home).join(".bundle/config") end end diff --git a/bundler/spec/bundler/bundler_spec.rb b/bundler/spec/bundler/bundler_spec.rb index aeadcf9720b5..f0b257cd4f23 100644 --- a/bundler/spec/bundler/bundler_spec.rb +++ b/bundler/spec/bundler/bundler_spec.rb @@ -256,16 +256,6 @@ end end end - - context "home directory is not set" do - it "should issue warning and return a temporary user home" do - allow(Bundler.rubygems).to receive(:user_home).and_return(nil) - allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom")) - expect(Bundler.ui).to receive(:warn).with("Your home directory is not set.\n") - expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n") - expect(Bundler.user_home).to eq(Pathname("/tmp/trulyrandom")) - end - end end describe "#requires_sudo?" do diff --git a/bundler/spec/bundler/settings_spec.rb b/bundler/spec/bundler/settings_spec.rb index 24e3de7ba80c..e0ab5e3b1120 100644 --- a/bundler/spec/bundler/settings_spec.rb +++ b/bundler/spec/bundler/settings_spec.rb @@ -65,9 +65,9 @@ describe "#global_config_file" do context "when $HOME is not accessible" do it "does not raise" do - expect(Bundler.rubygems).to receive(:user_home).twice.and_return(nil) + expect(Bundler.rubygems).to receive(:user_home).twice.and_return(Pathname.new("/")) - expect(subject.send(:global_config_file)).to be_nil + expect(subject.send(:global_config_file)).to eq(Pathname.new("/.bundle/config")) end end end From d49e6a1b20fb89e43f426c315f69a9aa32b769de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 16 Aug 2021 12:11:03 +0200 Subject: [PATCH 15/24] Use `Pathname`'s consistently --- bundler/lib/bundler.rb | 8 +++--- bundler/lib/bundler/rubygems_integration.rb | 2 +- bundler/lib/bundler/settings.rb | 2 +- bundler/spec/bundler/bundler_spec.rb | 32 ++++++++++----------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 79b434964d37..545a084f239c 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -227,11 +227,11 @@ def ruby_scope def user_home @user_home ||= begin home = Bundler.rubygems.user_home - bundle_home = File.join(home, ".bundle") + bundle_home = home.join(".bundle") - warning = if !File.directory?(home) + warning = if !home.directory? "`#{home}` is not a directory." - elsif !File.writable?(home) && (!File.directory?(bundle_home) || !File.writable?(bundle_home)) + elsif !home.writable? && (!bundle_home.directory? || !bundle_home.writable?) "`#{home}` is not writable." end @@ -241,7 +241,7 @@ def user_home Bundler.ui.warn "Bundler will use `#{user_home}' as your home directory temporarily.\n" user_home else - Pathname.new(home) + home end end end diff --git a/bundler/lib/bundler/rubygems_integration.rb b/bundler/lib/bundler/rubygems_integration.rb index 1c2b374d8bb4..085e43be3321 100644 --- a/bundler/lib/bundler/rubygems_integration.rb +++ b/bundler/lib/bundler/rubygems_integration.rb @@ -135,7 +135,7 @@ def gem_bindir end def user_home - Gem.user_home + Pathname.new(Gem.user_home) end def gem_path diff --git a/bundler/lib/bundler/settings.rb b/bundler/lib/bundler/settings.rb index d86f60d444fe..f28802adc7dc 100644 --- a/bundler/lib/bundler/settings.rb +++ b/bundler/lib/bundler/settings.rb @@ -442,7 +442,7 @@ def global_config_file elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty? Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config") else - Pathname.new(Bundler.rubygems.user_home).join(".bundle/config") + Bundler.rubygems.user_home.join(".bundle/config") end end diff --git a/bundler/spec/bundler/bundler_spec.rb b/bundler/spec/bundler/bundler_spec.rb index f0b257cd4f23..8546d19adaec 100644 --- a/bundler/spec/bundler/bundler_spec.rb +++ b/bundler/spec/bundler/bundler_spec.rb @@ -210,18 +210,18 @@ describe "#user_home" do context "home directory is set" do it "should return the user home" do - path = "/home/oggy" + path = Pathname("/home/oggy") allow(Bundler.rubygems).to receive(:user_home).and_return(path) - allow(File).to receive(:directory?).with(path).and_return true - allow(File).to receive(:writable?).with(path).and_return true - expect(Bundler.user_home).to eq(Pathname(path)) + allow(path).to receive(:directory?).and_return true + allow(path).to receive(:writable?).and_return true + expect(Bundler.user_home).to eq(path) end context "is not a directory" do it "should issue a warning and return a temporary user home" do - path = "/home/oggy" + path = Pathname("/home/oggy") allow(Bundler.rubygems).to receive(:user_home).and_return(path) - allow(File).to receive(:directory?).with(path).and_return false + allow(path).to receive(:directory?).and_return false allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom")) expect(Bundler.ui).to receive(:warn).with("`/home/oggy` is not a directory.\n") expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n") @@ -230,14 +230,14 @@ end context "is not writable" do - let(:path) { "/home/oggy" } - let(:dotbundle) { "/home/oggy/.bundle" } + let(:path) { Pathname("/home/oggy") } + let(:dotbundle) { Pathname("/home/oggy/.bundle") } it "should issue a warning and return a temporary user home" do allow(Bundler.rubygems).to receive(:user_home).and_return(path) - allow(File).to receive(:directory?).with(path).and_return true - allow(File).to receive(:writable?).with(path).and_return false - allow(File).to receive(:directory?).with(dotbundle).and_return false + allow(path).to receive(:directory?).and_return true + allow(path).to receive(:writable?).and_return false + allow(dotbundle).to receive(:directory?).and_return false allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom")) expect(Bundler.ui).to receive(:warn).with("`/home/oggy` is not writable.\n") expect(Bundler.ui).to receive(:warn).with("Bundler will use `/tmp/trulyrandom' as your home directory temporarily.\n") @@ -247,11 +247,11 @@ context ".bundle exists and have correct permissions" do it "should return the user home" do allow(Bundler.rubygems).to receive(:user_home).and_return(path) - allow(File).to receive(:directory?).with(path).and_return true - allow(File).to receive(:writable?).with(path).and_return false - allow(File).to receive(:directory?).with(dotbundle).and_return true - allow(File).to receive(:writable?).with(dotbundle).and_return true - expect(Bundler.user_home).to eq(Pathname(path)) + allow(path).to receive(:directory?).and_return true + allow(path).to receive(:writable?).and_return true + allow(dotbundle).to receive(:directory?).and_return true + allow(dotbundle).to receive(:writable?).and_return true + expect(Bundler.user_home).to eq(path) end end end From 16a940d2af395ee47a316fc640b31d825df35b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 25 Sep 2018 16:38:09 -0300 Subject: [PATCH 16/24] New criteria to find configuration folder Now the directory hierarchy is searched up for a ".bundle" directory. If none is found, we use the folder of the current Gemfile (which we know won't come from configuration, since none was found). If none is found either, the current folder is used. This is more intuitive than choosing the configuration location to be the folder of the Gemfile being used, but also it will allow us to respect the Gemfile configured via settings when requiring `bundler/setup`, since the current workaround to make that work doesn't apply to that case since it lives at `bundler/cli`. --- bundler/lib/bundler.rb | 39 ++++++++++++------ bundler/lib/bundler/cli.rb | 5 ++- bundler/lib/bundler/shared_helpers.rb | 44 +++++++-------------- bundler/spec/bundler/bundler_spec.rb | 39 ++++++++++++++++++ bundler/spec/bundler/plugin/index_spec.rb | 2 +- bundler/spec/bundler/plugin_spec.rb | 5 ++- bundler/spec/bundler/settings_spec.rb | 2 +- bundler/spec/bundler/shared_helpers_spec.rb | 35 ---------------- bundler/spec/commands/config_spec.rb | 30 ++++++++++++++ bundler/spec/plugins/install_spec.rb | 4 +- bundler/spec/plugins/source_spec.rb | 6 +-- bundler/spec/runtime/load_spec.rb | 6 +-- 12 files changed, 125 insertions(+), 92 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 545a084f239c..4018b8ddf867 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -281,13 +281,7 @@ def specs_path end def root - @root ||= begin - SharedHelpers.root - rescue GemfileNotFound - bundle_dir = default_bundle_dir - raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir - bundle_dir.parent - end + @root ||= resolve_root end def app_config_path @@ -450,8 +444,14 @@ def default_lockfile SharedHelpers.default_lockfile end - def default_bundle_dir - SharedHelpers.default_bundle_dir + def default_bundle_dir(base = Pathname.pwd) + bundle_dir = SharedHelpers.find_directory(".bundle", :base => base) + return nil unless bundle_dir + + global_bundle_dir = Bundler.rubygems.user_home.join(".bundle") + return nil if bundle_dir == global_bundle_dir + + bundle_dir end def system_bindir @@ -605,7 +605,8 @@ def reset! reset_rubygems! end - def reset_settings_and_root! + def reset_settings_and_root!(base) + @app_config_root = resolve_config_root(base) @settings = nil @root = nil end @@ -619,6 +620,7 @@ def reset_paths! @definition = nil @load = nil @locked_gems = nil + @app_config_root = nil @root = nil @settings = nil @setup = nil @@ -695,9 +697,20 @@ def with_env(env) end def app_config_root - root - rescue GemfileNotFound - Pathname.pwd + @app_config_root ||= resolve_config_root + end + + def resolve_config_root(base = Pathname.pwd) + bundle_dir = default_bundle_dir(base) || SharedHelpers.find_gemfile + + bundle_dir ? bundle_dir.parent : base + end + + def resolve_root + bundle_dir = SharedHelpers.find_gemfile || default_bundle_dir + raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir + + bundle_dir.parent end end end diff --git a/bundler/lib/bundler/cli.rb b/bundler/lib/bundler/cli.rb index 16651dfad94f..474cc56e2f08 100644 --- a/bundler/lib/bundler/cli.rb +++ b/bundler/lib/bundler/cli.rb @@ -57,8 +57,9 @@ def initialize(*args) custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile] if custom_gemfile && !custom_gemfile.empty? - Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile) - Bundler.reset_settings_and_root! + expanded_custom_gemfile = Pathname.new(custom_gemfile).expand_path + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", expanded_custom_gemfile.to_s + Bundler.reset_settings_and_root!(expanded_custom_gemfile.parent) end Bundler.self_manager.restart_with_locked_bundler_if_needed diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index 92cd7f01c8b4..e1424bf50a90 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -10,12 +10,6 @@ module Bundler module SharedHelpers - def root - gemfile = find_gemfile - raise GemfileNotFound, "Could not locate Gemfile" unless gemfile - gemfile.parent - end - def default_gemfile gemfile = find_gemfile raise GemfileNotFound, "Could not locate Gemfile" unless gemfile @@ -31,16 +25,6 @@ def default_lockfile end end - def default_bundle_dir - bundle_dir = find_directory(".bundle") - return nil unless bundle_dir - - global_bundle_dir = Bundler.user_home.join(".bundle") - return nil if bundle_dir == global_bundle_dir - - bundle_dir - end - def in_bundle? find_gemfile end @@ -51,6 +35,18 @@ def chdir(dir, &blk) end end + def find_gemfile + given = ENV["BUNDLE_GEMFILE"] + return expand(given) if given && !given.empty? + find_file(*gemfile_names) + end + + def find_directory(*names, base: pwd) + search_up(*names, :base => base) do |dirname| + return dirname if dirname.directory? + end + end + def pwd Bundler.rubygems.ext_lock.synchronize do Pathname.pwd @@ -214,12 +210,6 @@ def validate_bundle_path raise Bundler::PathError, message end - def find_gemfile - given = ENV["BUNDLE_GEMFILE"] - return expand(given) if given && !given.empty? - find_file(*gemfile_names) - end - def gemfile_names ["gems.rb", "Gemfile"] end @@ -230,15 +220,9 @@ def find_file(*names) end end - def find_directory(*names) - search_up(*names) do |dirname| - return dirname if dirname.directory? - end - end - - def search_up(*names) + def search_up(*names, base: pwd) previous = nil - current = pwd.tap{|x| x.untaint if RUBY_VERSION < "2.7" } + current = base.tap{|x| x.untaint if RUBY_VERSION < "2.7" } until !current.directory? || current == previous if ENV["BUNDLER_SPEC_RUN"] diff --git a/bundler/spec/bundler/bundler_spec.rb b/bundler/spec/bundler/bundler_spec.rb index 8546d19adaec..276bf53e9cd2 100644 --- a/bundler/spec/bundler/bundler_spec.rb +++ b/bundler/spec/bundler/bundler_spec.rb @@ -370,6 +370,45 @@ def clear_cached_requires_sudo end end + describe "#default_bundle_dir" do + before do + allow(Pathname).to receive(:pwd).and_return(bundled_app) + end + + context ".bundle does not exist" do + it "returns nil" do + expect(subject.default_bundle_dir).to be_nil + end + end + + context ".bundle is global .bundle" do + let(:global_rubygems_dir) { Pathname.new(bundled_app) } + + before do + Dir.mkdir bundled_app(".bundle") + allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir) + end + + it "returns nil" do + expect(subject.default_bundle_dir).to be_nil + end + end + + context ".bundle is not global .bundle" do + let(:global_rubygems_dir) { Pathname.new("/path/rubygems") } + let(:expected_bundle_dir_path) { Pathname.new("#{bundled_app}/.bundle") } + + before do + Dir.mkdir bundled_app(".bundle") + allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir) + end + + it "returns the .bundle path" do + expect(subject.default_bundle_dir).to eq(expected_bundle_dir_path) + end + end + end + context "user cache dir" do let(:home_path) { Pathname.new(ENV["HOME"]) } diff --git a/bundler/spec/bundler/plugin/index_spec.rb b/bundler/spec/bundler/plugin/index_spec.rb index d34b0de34210..144d49445419 100644 --- a/bundler/spec/bundler/plugin/index_spec.rb +++ b/bundler/spec/bundler/plugin/index_spec.rb @@ -4,7 +4,7 @@ Index = Bundler::Plugin::Index before do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) gemfile "source \"#{file_uri_for(gem_repo1)}\"" path = lib_path(plugin_name) index.register_plugin("new-plugin", path.to_s, [path.join("lib").to_s], commands, sources, hooks) diff --git a/bundler/spec/bundler/plugin_spec.rb b/bundler/spec/bundler/plugin_spec.rb index 8a1a6cd97ab7..566b835dd9ff 100644 --- a/bundler/spec/bundler/plugin_spec.rb +++ b/bundler/spec/bundler/plugin_spec.rb @@ -243,7 +243,8 @@ describe "#root" do context "in app dir" do before do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) + FileUtils.touch(bundled_app.join("Gemfile")) end it "returns plugin dir in app .bundle path" do @@ -253,7 +254,7 @@ context "outside app dir" do before do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(nil) + allow(Bundler::SharedHelpers).to receive(:pwd).and_return(root) end it "returns plugin dir in global bundle path" do diff --git a/bundler/spec/bundler/settings_spec.rb b/bundler/spec/bundler/settings_spec.rb index e0ab5e3b1120..6f82969e1416 100644 --- a/bundler/spec/bundler/settings_spec.rb +++ b/bundler/spec/bundler/settings_spec.rb @@ -127,7 +127,7 @@ describe "#temporary" do it "reset after used" do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) Bundler.settings.set_command_option :no_install, true diff --git a/bundler/spec/bundler/shared_helpers_spec.rb b/bundler/spec/bundler/shared_helpers_spec.rb index 2cd0093c5f2e..3822c159fa44 100644 --- a/bundler/spec/bundler/shared_helpers_spec.rb +++ b/bundler/spec/bundler/shared_helpers_spec.rb @@ -69,41 +69,6 @@ end end - describe "#default_bundle_dir" do - context ".bundle does not exist" do - it "returns nil" do - expect(subject.default_bundle_dir).to be_nil - end - end - - context ".bundle is global .bundle" do - let(:global_rubygems_dir) { Pathname.new(bundled_app) } - - before do - Dir.mkdir bundled_app(".bundle") - allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir) - end - - it "returns nil" do - expect(subject.default_bundle_dir).to be_nil - end - end - - context ".bundle is not global .bundle" do - let(:global_rubygems_dir) { Pathname.new("/path/rubygems") } - let(:expected_bundle_dir_path) { Pathname.new("#{bundled_app}/.bundle") } - - before do - Dir.mkdir bundled_app(".bundle") - allow(Bundler.rubygems).to receive(:user_home).and_return(global_rubygems_dir) - end - - it "returns the .bundle path" do - expect(subject.default_bundle_dir).to eq(expected_bundle_dir_path) - end - end - end - describe "#in_bundle?" do it "calls the find_gemfile method" do expect(subject).to receive(:find_gemfile) diff --git a/bundler/spec/commands/config_spec.rb b/bundler/spec/commands/config_spec.rb index fb7aa3cc67f0..7a2d6d94c8c3 100644 --- a/bundler/spec/commands/config_spec.rb +++ b/bundler/spec/commands/config_spec.rb @@ -70,6 +70,36 @@ expect(bundled_app("../foo/config")).to exist expect(the_bundle).to include_gems "rack 1.0.0", :dir => bundled_app("omg") end + + it "is relative to the Gemfile if there's no previous configuration" do + FileUtils.mkdir_p bundled_app("omg/gmo") + + gemfile bundled_app("omg/gmo/AnotherGemfile"), <<-G + source "#{file_uri_for(gem_repo1)}" + G + + bundle "config set --local foo bar", :env => { "BUNDLE_GEMFILE" => bundled_app("omg/gmo/AnotherGemfile").to_s }, :dir => bundled_app("omg") + + expect(bundled_app("omg/gmo/.bundle")).to exist + expect(bundled_app("omg/.bundle")).not_to exist + end + + it "reuses the first existing local config from the pwd and not from the gemfile" do + bundle "install" + + FileUtils.mkdir_p bundled_app("omg/gmo") + + bundle "config set --local foo bar", :dir => bundled_app("omg/gmo") + + gemfile bundled_app("omg/gmo/AnotherGemfile"), <<-G + source "#{file_uri_for(gem_repo1)}" + G + + bundle "config set --local foo baz", :dir => bundled_app("omg") + run "puts Bundler.settings[:foo]", :env => { "BUNDLE_GEMFILE" => bundled_app("omg/gmo/AnotherGemfile").to_s }, :dir => bundled_app("omg") + + expect(out).to eq("baz") + end end describe "location without a gemfile" do diff --git a/bundler/spec/plugins/install_spec.rb b/bundler/spec/plugins/install_spec.rb index 009516260ad9..6bb6a75aa56a 100644 --- a/bundler/spec/plugins/install_spec.rb +++ b/bundler/spec/plugins/install_spec.rb @@ -184,7 +184,7 @@ def exec(command, args) context "Gemfile eval" do before do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) end it "installs plugins listed in gemfile" do @@ -293,7 +293,7 @@ def exec(command, args) describe "local plugin" do it "is installed when inside an app" do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) gemfile "" bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" diff --git a/bundler/spec/plugins/source_spec.rb b/bundler/spec/plugins/source_spec.rb index 14643e5c81dc..cbcf6f26f346 100644 --- a/bundler/spec/plugins/source_spec.rb +++ b/bundler/spec/plugins/source_spec.rb @@ -21,7 +21,7 @@ class OPSource < Bundler::Plugin::API end G - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) plugin_should_be_installed("bundler-source-psource") end @@ -76,7 +76,7 @@ class Cheater < Bundler::Plugin::API end it "installs the explicit one" do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) plugin_should_be_installed("another-psource") end @@ -102,7 +102,7 @@ class Cheater < Bundler::Plugin::API end it "installs the default one" do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) plugin_should_be_installed("bundler-source-psource") end end diff --git a/bundler/spec/runtime/load_spec.rb b/bundler/spec/runtime/load_spec.rb index 96a22a46cc99..d1543c739536 100644 --- a/bundler/spec/runtime/load_spec.rb +++ b/bundler/spec/runtime/load_spec.rb @@ -7,7 +7,7 @@ source "#{file_uri_for(gem_repo1)}" gem "rack" G - allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app) + allow(Pathname).to receive(:pwd).and_return(bundled_app) end it "provides a list of the env dependencies" do @@ -33,7 +33,7 @@ gem "rack" G bundle :install - allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app) + allow(Pathname).to receive(:pwd).and_return(bundled_app) end it "provides a list of the env dependencies" do @@ -103,7 +103,7 @@ source "#{file_uri_for(gem_repo1)}" gem "activerecord" G - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + allow(Pathname).to receive(:pwd).and_return(bundled_app) Bundler.load.specs.each do |spec| expect(spec.to_yaml).not_to match(/^\s+source:/) expect(spec.to_yaml).not_to match(/^\s+groups:/) From 59a599e404e591208d092fa50f969aac581f33a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 11 Aug 2021 14:23:01 +0200 Subject: [PATCH 17/24] Simplify settings instantiation Root is compulsory. --- bundler/lib/bundler/settings.rb | 6 ++---- bundler/spec/bundler/settings_spec.rb | 21 --------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/bundler/lib/bundler/settings.rb b/bundler/lib/bundler/settings.rb index f28802adc7dc..9284b957b698 100644 --- a/bundler/lib/bundler/settings.rb +++ b/bundler/lib/bundler/settings.rb @@ -86,7 +86,7 @@ class Settings "BUNDLE_TIMEOUT" => 10, }.freeze - def initialize(root = nil) + def initialize(root) @root = root @local_config = load_config(local_config_file) @env_config = ENV.to_h.select {|key, _value| key =~ /\ABUNDLE_.+/ } @@ -116,8 +116,6 @@ def set_command_option_if_given(key, value) end def set_local(key, value) - local_config_file || raise(GemfileNotFound, "Could not locate Gemfile") - set_key(key, value, @local_config, local_config_file) end @@ -447,7 +445,7 @@ def global_config_file end def local_config_file - @root.join("config") if @root + @root.join("config") end def load_config(config_file) diff --git a/bundler/spec/bundler/settings_spec.rb b/bundler/spec/bundler/settings_spec.rb index 6f82969e1416..149519318f6b 100644 --- a/bundler/spec/bundler/settings_spec.rb +++ b/bundler/spec/bundler/settings_spec.rb @@ -5,17 +5,6 @@ RSpec.describe Bundler::Settings do subject(:settings) { described_class.new(bundled_app) } - describe "#set_local" do - context "when the local config file is not found" do - subject(:settings) { described_class.new(nil) } - - it "raises a GemfileNotFound error with explanation" do - expect { subject.set_local("foo", "bar") }. - to raise_error(Bundler::GemfileNotFound, "Could not locate Gemfile") - end - end - end - describe "load_config" do let(:hash) do { @@ -73,16 +62,6 @@ end describe "#[]" do - context "when the local config file is not found" do - subject(:settings) { described_class.new } - - it "does not raise" do - expect do - subject["foo"] - end.not_to raise_error - end - end - context "when not set" do context "when default value present" do it "retrieves value" do From 1236fb17814efb96b2f1487acbe2d26cba590e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 25 Sep 2018 16:31:25 -0300 Subject: [PATCH 18/24] Resolve gemfile from config in the general case Previously it was being set when initializing the CLI, but that wouldn't apply to directly using `bundler` via `-rbundler/setup`. Since now resolving the settings root doesn't need a Gemfile, we can move the logic to the `SharedHelpers.find_gemfile` method, so that it happily applies to `bundler/setup` as well. --- bundler/lib/bundler.rb | 2 +- bundler/lib/bundler/cli.rb | 2 +- bundler/lib/bundler/shared_helpers.rb | 8 +++++-- bundler/spec/commands/config_spec.rb | 33 ++++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 4018b8ddf867..33fc4cfd5878 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -701,7 +701,7 @@ def app_config_root end def resolve_config_root(base = Pathname.pwd) - bundle_dir = default_bundle_dir(base) || SharedHelpers.find_gemfile + bundle_dir = default_bundle_dir(base) || SharedHelpers.find_gemfile_if_empty(ENV["BUNDLE_GEMFILE"]) bundle_dir ? bundle_dir.parent : base end diff --git a/bundler/lib/bundler/cli.rb b/bundler/lib/bundler/cli.rb index 474cc56e2f08..8d343e81a212 100644 --- a/bundler/lib/bundler/cli.rb +++ b/bundler/lib/bundler/cli.rb @@ -55,7 +55,7 @@ def self.aliases_for(command_name) def initialize(*args) super - custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile] + custom_gemfile = options[:gemfile] if custom_gemfile && !custom_gemfile.empty? expanded_custom_gemfile = Pathname.new(custom_gemfile).expand_path Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", expanded_custom_gemfile.to_s diff --git a/bundler/lib/bundler/shared_helpers.rb b/bundler/lib/bundler/shared_helpers.rb index e1424bf50a90..9f3c38a604d3 100644 --- a/bundler/lib/bundler/shared_helpers.rb +++ b/bundler/lib/bundler/shared_helpers.rb @@ -36,8 +36,12 @@ def chdir(dir, &blk) end def find_gemfile - given = ENV["BUNDLE_GEMFILE"] - return expand(given) if given && !given.empty? + require_relative "../bundler" + find_gemfile_if_empty(Bundler.settings[:gemfile]) + end + + def find_gemfile_if_empty(candidate) + return expand(candidate) if candidate && !candidate.empty? find_file(*gemfile_names) end diff --git a/bundler/spec/commands/config_spec.rb b/bundler/spec/commands/config_spec.rb index 7a2d6d94c8c3..afb8b1ad87df 100644 --- a/bundler/spec/commands/config_spec.rb +++ b/bundler/spec/commands/config_spec.rb @@ -71,6 +71,21 @@ expect(the_bundle).to include_gems "rack 1.0.0", :dir => bundled_app("omg") end + it "allows configuring Gemfile" do + FileUtils.mkdir_p bundled_app("omg/gmo") + + gemfile bundled_app("omg/gmo/AnotherGemfile"), <<-G + source "#{file_uri_for(gem_repo1)}" + G + + bundle "config set --local gemfile omg/gmo/AnotherGemfile" + + bundle "install" + + expect(out).to include("0 Gemfile dependencies") + expect(the_bundle).not_to include_gems "rack 1.0.0" + end + it "is relative to the Gemfile if there's no previous configuration" do FileUtils.mkdir_p bundled_app("omg/gmo") @@ -570,17 +585,33 @@ RSpec.describe "setting gemfile via config" do context "when only the non-default Gemfile exists" do - it "persists the gemfile location to .bundle/config" do + before do gemfile bundled_app("NotGemfile"), <<-G source "#{file_uri_for(gem_repo1)}" gem 'rack' G bundle "config set --local gemfile #{bundled_app("NotGemfile")}" + end + + it "persists the gemfile location to .bundle/config" do expect(File.exist?(bundled_app(".bundle/config"))).to eq(true) bundle "config list" expect(out).to include("NotGemfile") end + + it "gets used when requiring bundler/setup" do + bundle :install + code = "puts $LOAD_PATH.count {|path| path =~ /rack/} == 1" + + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + G + + ruby code, :env => { "RUBYOPT" => "-r#{lib_dir}/bundler/setup" } + + expect(out).to eq("true") + end end end From 8ad15de6fe3872e2b71d942e128d3147a30f68b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Aug 2021 13:37:55 +0200 Subject: [PATCH 19/24] This should be a temporary setting It shouldn't make a difference but CLI flags should map to temporary settings, which have higher priority than ENV. --- bundler/lib/bundler/cli.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundler/lib/bundler/cli.rb b/bundler/lib/bundler/cli.rb index 8d343e81a212..5a6bd7fb85ed 100644 --- a/bundler/lib/bundler/cli.rb +++ b/bundler/lib/bundler/cli.rb @@ -58,8 +58,8 @@ def initialize(*args) custom_gemfile = options[:gemfile] if custom_gemfile && !custom_gemfile.empty? expanded_custom_gemfile = Pathname.new(custom_gemfile).expand_path - Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", expanded_custom_gemfile.to_s Bundler.reset_settings_and_root!(expanded_custom_gemfile.parent) + Bundler.settings.temporary(:gemfile => expanded_custom_gemfile) end Bundler.self_manager.restart_with_locked_bundler_if_needed From 7e5e2c42384dd7742111a61c4585cf3652428fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Aug 2021 14:16:28 +0200 Subject: [PATCH 20/24] Add a comment to clarify some hacky code It took me a while to figure out why we were doing this, add a comment to try clarify. --- bundler/lib/bundler/cli.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bundler/lib/bundler/cli.rb b/bundler/lib/bundler/cli.rb index 5a6bd7fb85ed..843656ef4f7c 100644 --- a/bundler/lib/bundler/cli.rb +++ b/bundler/lib/bundler/cli.rb @@ -55,6 +55,15 @@ def self.aliases_for(command_name) def initialize(*args) super + # At this point, settings have been already resolved, unfortunately, + # because some CLI help messages, flag aliases or even whole commands need + # to be defined according to some settings being activated or not. So once + # we know the `--gemfile` has been passed, we need to force a reload of + # everything. This logic seems buggy, since the settings we have used + # before this point might not be correct, but so far it has worked fine. + # The ideal solution would be to add some features to thor so that stuff + # can be defined via procs and lazily loaded, and thus we can be sure we + # haven't yet loaded settings at all at this point. custom_gemfile = options[:gemfile] if custom_gemfile && !custom_gemfile.empty? expanded_custom_gemfile = Pathname.new(custom_gemfile).expand_path From 9f2de1b349d5df2a5d94a4a94dcd8629fee98dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 13 Aug 2021 11:45:01 +0200 Subject: [PATCH 21/24] Remove unnecessary RUBYOPT This seems to be causing some issues with the new test, but it does not seem needed. I don't recall why I added. As long as our development binstubs load the rubygems version switcher initially, the proper path to rubygems will be added to RUBYOPT and preserved for all future subprocesses. I don't think further manipulations are needed. --- bundler/spec/support/helpers.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/bundler/spec/support/helpers.rb b/bundler/spec/support/helpers.rb index d7556102b4c2..767b55e4328d 100644 --- a/bundler/spec/support/helpers.rb +++ b/bundler/spec/support/helpers.rb @@ -180,7 +180,6 @@ def git(cmd, path, options = {}) def sys_exec(cmd, options = {}) env = options[:env] || {} - env["RUBYOPT"] = opt_add(opt_add("-r#{spec_dir}/support/switch_rubygems.rb", env["RUBYOPT"]), ENV["RUBYOPT"]) dir = options[:dir] || bundled_app command_execution = CommandExecution.new(cmd.to_s, dir) From 644c405fe84242ef7cabd2a4b3530019ea934288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 2 Feb 2022 12:43:57 +0100 Subject: [PATCH 22/24] All supported RubyGems versions have this defined --- bundler/lib/bundler/fetcher.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bundler/lib/bundler/fetcher.rb b/bundler/lib/bundler/fetcher.rb index e07f925107f5..c9ae3a5b8adc 100644 --- a/bundler/lib/bundler/fetcher.rb +++ b/bundler/lib/bundler/fetcher.rb @@ -250,9 +250,7 @@ def connection con.cert_store = bundler_cert_store end - ssl_client_cert = Bundler.settings[:ssl_client_cert] || - (Gem.configuration.ssl_client_cert if - Gem.configuration.respond_to?(:ssl_client_cert)) + ssl_client_cert = Bundler.settings[:ssl_client_cert] || Gem.configuration.ssl_client_cert if ssl_client_cert pem = File.read(ssl_client_cert) con.cert = OpenSSL::X509::Certificate.new(pem) From 23010a199788ec106595845d5273f77437936315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 4 Feb 2022 12:12:06 +0100 Subject: [PATCH 23/24] Workaround bundler issue --- .github/workflows/ruby-core.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-core.yml b/.github/workflows/ruby-core.yml index 292986d3c833..06580460e565 100644 --- a/.github/workflows/ruby-core.yml +++ b/.github/workflows/ruby-core.yml @@ -29,7 +29,8 @@ jobs: run: echo "REF=$(ruby -v | cut -d')' -f1 | cut -d' ' -f5)" >> $GITHUB_ENV - uses: actions/checkout@v2 with: - repository: ruby/ruby + repository: deivid-rodriguez/ruby + ref: workaround-bundler-issue path: ruby/ruby fetch-depth: 10 - name: Checkout the latest buildable revision From 9eca72f6926e04e234d289518f2895f0543ffe00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 9 Feb 2022 10:17:21 +0100 Subject: [PATCH 24/24] Revert "Workaround bundler issue" This reverts commit 23010a199788ec106595845d5273f77437936315. --- .github/workflows/ruby-core.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ruby-core.yml b/.github/workflows/ruby-core.yml index 06580460e565..292986d3c833 100644 --- a/.github/workflows/ruby-core.yml +++ b/.github/workflows/ruby-core.yml @@ -29,8 +29,7 @@ jobs: run: echo "REF=$(ruby -v | cut -d')' -f1 | cut -d' ' -f5)" >> $GITHUB_ENV - uses: actions/checkout@v2 with: - repository: deivid-rodriguez/ruby - ref: workaround-bundler-issue + repository: ruby/ruby path: ruby/ruby fetch-depth: 10 - name: Checkout the latest buildable revision