Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
Auto merge of #6628 - bundler:segiddins/bundler-2-global-path-ruby-sc…
Browse files Browse the repository at this point in the history
…ope, r=colby-swandale

[Settings] Append the ruby scope on Bundler 2 with a global path setting

### What was the end-user problem that led to this PR?

The problem was `bundle config path` behaving differently depending on whether the config is local or global was... confusing.

Closes #6619 (comment).

### What was your diagnosis of the problem?

My diagnosis was setting the `path` setting should be consistent, regardless of the level of configuration it is set at.

### What is your fix for the problem, implemented in this PR?

My fix appends the "ruby scope" to the path when set globally on Bundler 2.

### Why did you choose this fix out of the possible options?

I chose this fix because it means users won't have to re-install gems when switching rubies with a global `BUNDLE_PATH` set.
  • Loading branch information
bundlerbot committed Jul 31, 2018
2 parents 1a10427 + 9b38bcb commit 0fc64a6
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 31 deletions.
1 change: 1 addition & 0 deletions lib/bundler/feature_flag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def self.settings_method(name, key, &default)
settings_flag(:disable_multisource) { bundler_2_mode? }
settings_flag(:error_on_stderr) { bundler_2_mode? }
settings_flag(:forget_cli_options) { bundler_2_mode? }
settings_flag(:global_path_appends_ruby_scope) { bundler_2_mode? }
settings_flag(:global_gem_cache) { bundler_2_mode? }
settings_flag(:init_gems_rb) { bundler_2_mode? }
settings_flag(:list_command) { bundler_2_mode? }
Expand Down
5 changes: 3 additions & 2 deletions lib/bundler/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Settings
frozen
gem.coc
gem.mit
global_path_appends_ruby_scope
global_gem_cache
ignore_messages
init_gems_rb
Expand Down Expand Up @@ -219,13 +220,13 @@ def pretty_values_for(exposed_key)
locations
end

# for legacy reasons, the ruby scope isnt appended when the setting comes from ENV or the global config,
# for legacy reasons, in Bundler 1, the ruby scope isnt appended when the setting comes from ENV or the global config,
# nor do we respect :disable_shared_gems
def path
key = key_for(:path)
path = ENV[key] || @global_config[key]
if path && !@temporary.key?(key) && !@local_config.key?(key)
return Path.new(path, false, false, false)
return Path.new(path, Bundler.feature_flag.global_path_appends_ruby_scope?, false, false)
end

system_path = self["path.system"] || (self[:disable_shared_gems] == false)
Expand Down
3 changes: 3 additions & 0 deletions man/bundle-config.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
* `global_gem_cache` (`BUNDLE_GLOBAL_GEM_CACHE`):
Whether Bundler should cache all gems globally, rather than locally to the
installing Ruby installation.
* `global_path_appends_ruby_scope` (`BUNDLE_GLOBAL_PATH_APPENDS_RUBY_SCOPE`):
Whether Bundler should append the Ruby scope (e.g. engine and ABI version)
to a globally-configured path.
* `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`): When set, no post install
messages will be printed. To silence a single gem, use dot notation like
`ignore_messages.httparty true`.
Expand Down
1 change: 1 addition & 0 deletions spec/install/bundler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@

it "can install dependencies with newer bundler version with a local path", :ruby => "> 2" do
bundle! "config path .bundle"
bundle! "config global_path_appends_ruby_scope true"
install_gemfile! <<-G
source "file://#{gem_repo2}"
gem "rails", "3.0"
Expand Down
4 changes: 4 additions & 0 deletions spec/install/gems/sudo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
end

it "installs when BUNDLE_PATH is owned by root" do
bundle! "config global_path_appends_ruby_scope false" # consistency in tests between 1.x and 2.x modes

bundle_path = tmp("owned_by_root")
FileUtils.mkdir_p bundle_path
sudo "chown -R root #{bundle_path}"
Expand All @@ -68,6 +70,8 @@
end

it "installs when BUNDLE_PATH does not exist" do
bundle! "config global_path_appends_ruby_scope false" # consistency in tests between 1.x and 2.x modes

root_path = tmp("owned_by_root")
FileUtils.mkdir_p root_path
sudo "chown -R root #{root_path}"
Expand Down
96 changes: 67 additions & 29 deletions spec/install/path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,44 +103,82 @@ def set_bundle_path(type, location)
end

[:env, :global].each do |type|
it "installs gems to a path if one is specified" do
set_bundle_path(type, bundled_app("vendor2").to_s)
bundle! :install, forgotten_command_line_options(:path => "vendor/bundle")
context "when set via #{type}" do
it "installs gems to a path if one is specified" do
set_bundle_path(type, bundled_app("vendor2").to_s)
bundle! :install, forgotten_command_line_options(:path => "vendor/bundle")

expect(vendored_gems("gems/rack-1.0.0")).to be_directory
expect(bundled_app("vendor2")).not_to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end

expect(vendored_gems("gems/rack-1.0.0")).to be_directory
expect(bundled_app("vendor2")).not_to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
context "with global_path_appends_ruby_scope set", :bundler => "2" do
it "installs gems to ." do
set_bundle_path(type, ".")
bundle! "config --global disable_shared_gems true"

it "installs gems to ." do
set_bundle_path(type, ".")
bundle! "config --global disable_shared_gems true"
bundle! :install

bundle! :install
paths_to_exist = %w[cache/rack-1.0.0.gem gems/rack-1.0.0 specifications/rack-1.0.0.gemspec].map {|path| bundled_app(Bundler.ruby_scope, path) }
expect(paths_to_exist).to all exist
expect(the_bundle).to include_gems "rack 1.0.0"
end

expect([bundled_app("cache/rack-1.0.0.gem"), bundled_app("gems/rack-1.0.0"), bundled_app("specifications/rack-1.0.0.gemspec")]).to all exist
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "installs gems to the path" do
set_bundle_path(type, bundled_app("vendor").to_s)

it "installs gems to BUNDLE_PATH with #{type}" do
set_bundle_path(type, bundled_app("vendor").to_s)
bundle! :install

bundle :install
expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end

expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "installs gems to the path relative to root when relative" do
set_bundle_path(type, "vendor")

it "installs gems to BUNDLE_PATH relative to root when relative" do
set_bundle_path(type, "vendor")
FileUtils.mkdir_p bundled_app("lol")
Dir.chdir(bundled_app("lol")) do
bundle! :install
end

FileUtils.mkdir_p bundled_app("lol")
Dir.chdir(bundled_app("lol")) do
bundle :install
expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
end

expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
context "with global_path_appends_ruby_scope unset", :bundler => "< 2" do
it "installs gems to ." do
set_bundle_path(type, ".")
bundle! "config --global disable_shared_gems true"

bundle! :install

expect([bundled_app("cache/rack-1.0.0.gem"), bundled_app("gems/rack-1.0.0"), bundled_app("specifications/rack-1.0.0.gemspec")]).to all exist
expect(the_bundle).to include_gems "rack 1.0.0"
end

it "installs gems to BUNDLE_PATH with #{type}" do
set_bundle_path(type, bundled_app("vendor").to_s)

bundle :install

expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end

it "installs gems to BUNDLE_PATH relative to root when relative" do
set_bundle_path(type, "vendor")

FileUtils.mkdir_p bundled_app("lol")
Dir.chdir(bundled_app("lol")) do
bundle :install
end

expect(bundled_app("vendor/gems/rack-1.0.0")).to be_directory
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
end
end

Expand Down Expand Up @@ -201,7 +239,7 @@ def set_bundle_path(type, location)
describe "to a file" do
before do
in_app_root do
`touch /tmp/idontexist bundle`
FileUtils.touch "bundle"
end
end

Expand All @@ -212,7 +250,7 @@ def set_bundle_path(type, location)
G

bundle :install, forgotten_command_line_options(:path => "bundle")
expect(out).to match(/file already exists/)
expect(out).to include("file already exists")
end
end
end

0 comments on commit 0fc64a6

Please sign in to comment.