From e2097be55e5c5acf1268a66d31c0c97fceb9a02a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 19 Apr 2019 17:04:23 -0700 Subject: [PATCH 1/2] Fixes #10800, Fixes #9148: Ensure rubygems is loading gemrc properly on Windows Prior to this commit, when Vagrant attempted to use the Gem library, it would attempt to pass in a gemrc through an environment variable that the rubygems library would try to split and parse. This is normally fine, as the method in question would return empty if that file did not exist. However if the user had a file that matches the drive that Vagrant was installed on, rubygems would fail saying the folder was not a file (or a gemrc, in this case). This commit works around that by instead configuring the gemrc location through ruby with `Gem.configuration`. Related rubygems issue [#2733](https://github.com/rubygems/rubygems/issues/2733) --- lib/vagrant/bundler.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/vagrant/bundler.rb b/lib/vagrant/bundler.rb index 28ec66674..9273fc2ef 100644 --- a/lib/vagrant/bundler.rb +++ b/lib/vagrant/bundler.rb @@ -12,6 +12,8 @@ require "rubygems/name_tuple" require_relative "shared_helpers" require_relative "version" require_relative "util/safe_env" +require_relative "util/platform" +require "vagrant/util/subprocess" module Vagrant # This class manages Vagrant's interaction with Bundler. Vagrant uses @@ -40,6 +42,17 @@ module Vagrant def initialize @plugin_gem_path = Vagrant.user_data_path.join("gems", RUBY_VERSION).freeze @logger = Log4r::Logger.new("vagrant::bundler") + + # Because of a rubygems bug, we need to set the gemrc file path + # through this method rather than relying on the environment varible + # GEMRC. On windows, that path gets split on `:`: and `;`, which means + # the drive letter gets treated as its own path. If that path exists locally, + # (like having a random folder called `c` where the library was invoked), + # it fails thinking the folder `c` is a gemrc file. + gemrc_val = ENV["GEMRC"] + ENV["GEMRC"] = "" + Gem.configuration = Gem::ConfigFile.new(["--config-file", gemrc_val]) + ENV["GEMRC"] = gemrc_val end # Enable Vagrant environment specific plugins at given data path From 757175b94ec0d2160107d8492c94ed6dd9891183 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 22 Apr 2019 10:36:25 -0700 Subject: [PATCH 2/2] Add note about removing patch fix and add test --- lib/vagrant/bundler.rb | 5 +++-- test/unit/vagrant/bundler_test.rb | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/bundler.rb b/lib/vagrant/bundler.rb index 9273fc2ef..6124eb181 100644 --- a/lib/vagrant/bundler.rb +++ b/lib/vagrant/bundler.rb @@ -12,8 +12,6 @@ require "rubygems/name_tuple" require_relative "shared_helpers" require_relative "version" require_relative "util/safe_env" -require_relative "util/platform" -require "vagrant/util/subprocess" module Vagrant # This class manages Vagrant's interaction with Bundler. Vagrant uses @@ -43,6 +41,9 @@ module Vagrant @plugin_gem_path = Vagrant.user_data_path.join("gems", RUBY_VERSION).freeze @logger = Log4r::Logger.new("vagrant::bundler") + # TODO: Remove fix when https://github.com/rubygems/rubygems/pull/2735 + # gets merged and released + # # Because of a rubygems bug, we need to set the gemrc file path # through this method rather than relying on the environment varible # GEMRC. On windows, that path gets split on `:`: and `;`, which means diff --git a/test/unit/vagrant/bundler_test.rb b/test/unit/vagrant/bundler_test.rb index 4428be470..99fe9d0cd 100644 --- a/test/unit/vagrant/bundler_test.rb +++ b/test/unit/vagrant/bundler_test.rb @@ -28,6 +28,19 @@ describe Vagrant::Bundler do expect(subject.env_plugin_gem_path).to be_nil end + describe "#initialize" do + let(:gemrc_location) { "C:\\My\\Config\\File" } + + it "should set up GEMRC through a flag instead of GEMRC" do + allow(ENV).to receive(:[]).with("VAGRANT_HOME") + allow(ENV).to receive(:[]).with("USERPROFILE") + + allow(ENV).to receive(:[]).with("GEMRC").and_return(gemrc_location) + expect(Gem::ConfigFile).to receive(:new).with(["--config-file", gemrc_location]) + init_subject = described_class.new + end + end + describe "#deinit" do it "should provide method for backwards compatibility" do subject.deinit