summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2017-07-14 17:59:30 +0300
committerSamuel Giddins <segiddins@segiddins.me>2017-07-23 12:39:02 -0500
commit07fedc3f9ee972d5da43f8a77a162bf2c9ca4b1b (patch)
tree49eb8accade0d3f6ae19cd350c357dd6193eaeaa
parent1223f932c0790687d1743e5449e54b67f60f4c45 (diff)
downloadbundler-07fedc3f9ee972d5da43f8a77a162bf2c9ca4b1b.tar.gz
Default the install path to ./bundle in Bundler 2
-rw-r--r--lib/bundler.rb27
-rw-r--r--lib/bundler/cli/check.rb5
-rw-r--r--lib/bundler/cli/clean.rb2
-rw-r--r--lib/bundler/cli/install.rb17
-rw-r--r--lib/bundler/cli/update.rb2
-rw-r--r--lib/bundler/feature_flag.rb1
-rw-r--r--lib/bundler/installer.rb4
-rw-r--r--lib/bundler/resolver.rb2
-rw-r--r--lib/bundler/settings.rb51
-rw-r--r--lib/bundler/settings/validator.rb6
-rw-r--r--lib/bundler/source/rubygems.rb2
-rw-r--r--man/bundle-config.ronn5
-rw-r--r--spec/bundler/bundler_spec.rb4
-rw-r--r--spec/install/path_spec.rb4
-rw-r--r--spec/install/post_bundle_message_spec.rb4
15 files changed, 90 insertions, 46 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index d0ae913216..0e334b232f 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -75,7 +75,11 @@ module Bundler
# Returns absolute path of where gems are installed on the filesystem.
def bundle_path
- @bundle_path ||= Pathname.new(settings.path).expand_path(root)
+ @bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root)
+ end
+
+ def configured_bundle_path
+ @configured_bundle_path ||= settings.path.tap(&:validate!)
end
# Returns absolute location of where binstubs are installed to.
@@ -329,6 +333,10 @@ EOF
Bundler.settings[:system_bindir] || Bundler.rubygems.gem_bindir
end
+ def use_system_gems?
+ configured_bundle_path.use_system_gems?
+ end
+
def requires_sudo?
return @requires_sudo if defined?(@requires_sudo_ran)
@@ -457,14 +465,15 @@ EOF
end
def reset_paths!
- @root = nil
- @settings = nil
+ @bin_path = nil
+ @bundle_path = nil
+ @configured_bundle_path = nil
@definition = nil
- @setup = nil
@load = nil
@locked_gems = nil
- @bundle_path = nil
- @bin_path = nil
+ @root = nil
+ @settings = nil
+ @setup = nil
@user_home = nil
end
@@ -503,14 +512,14 @@ EOF
bundle_path
end
- def configure_gem_path(env = ENV, settings = self.settings)
+ def configure_gem_path(env = ENV)
blank_home = env["GEM_HOME"].nil? || env["GEM_HOME"].empty?
- if settings[:disable_shared_gems]
+ if !use_system_gems?
# this needs to be empty string to cause
# PathSupport.split_gem_path to only load up the
# Bundler --path setting as the GEM_PATH.
env["GEM_PATH"] = ""
- elsif blank_home || Bundler.rubygems.gem_dir != bundle_path.to_s
+ elsif blank_home
possibles = [Bundler.rubygems.gem_dir, Bundler.rubygems.gem_path]
paths = possibles.flatten.compact.uniq.reject(&:empty?)
env["GEM_PATH"] = paths.join(File::PATH_SEPARATOR)
diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb
index c7367b2f42..e572787dc4 100644
--- a/lib/bundler/cli/check.rb
+++ b/lib/bundler/cli/check.rb
@@ -9,10 +9,7 @@ module Bundler
end
def run
- if path = options[:path]
- Bundler.settings.set_command_option :path, path
- Bundler.settings.set_command_option :disable_shared_gems, true
- end
+ Bundler.settings.set_command_option_if_given :path, options[:path]
begin
definition = Bundler.definition
diff --git a/lib/bundler/cli/clean.rb b/lib/bundler/cli/clean.rb
index 231127cf97..71b2969192 100644
--- a/lib/bundler/cli/clean.rb
+++ b/lib/bundler/cli/clean.rb
@@ -16,7 +16,7 @@ module Bundler
protected
def require_path_or_force
- if !Bundler.settings[:path] && !options[:force]
+ if Bundler.use_system_gems? && !options[:force]
raise InvalidOption, "Cleaning all the gems on your system is dangerous! " \
"If you're sure you want to remove every system gem not in this " \
"bundle, run `bundle clean --force`."
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index fed2cf0b22..53db0026f8 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -70,19 +70,19 @@ module Bundler
Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
Bundler::CLI::Common.output_without_groups_message
- if path = Bundler.settings[:path]
- absolute_path = File.expand_path(path)
- relative_path = absolute_path.sub(File.expand_path(".") + File::SEPARATOR, "." + File::SEPARATOR)
- Bundler.ui.confirm "Bundled gems are installed into #{relative_path}."
- else
+ if Bundler.use_system_gems?
Bundler.ui.confirm "Use `bundle info [gemname]` to see where a bundled gem is installed."
+ else
+ absolute_path = File.expand_path(Bundler.configured_bundle_path.base_path)
+ relative_path = absolute_path.sub(File.expand_path(".") + File::SEPARATOR, "." + File::SEPARATOR)
+ Bundler.ui.confirm "Bundled gems are installed into `#{relative_path}`"
end
Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
warn_ambiguous_gems
- if Bundler.settings[:clean] && Bundler.settings[:path]
+ if Bundler.settings[:clean] && !Bundler.use_system_gems?
require "bundler/cli/clean"
Bundler::CLI::Clean.new(options).run
end
@@ -196,11 +196,6 @@ module Bundler
Bundler.settings.set_command_option :without, options[:without] - options[:with]
Bundler.settings.set_command_option :with, options[:with]
end
-
- disable_shared_gems = Bundler.settings[:path] ? true : nil
- Bundler.settings.set_command_option :disable_shared_gems, disable_shared_gems unless Bundler.settings[:disable_shared_gems] == disable_shared_gems
-
- options[:force] = options[:redownload]
end
def warn_ambiguous_gems
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index c2391fa76d..fcf5397bf7 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -62,7 +62,7 @@ module Bundler
installer = Installer.install Bundler.root, Bundler.definition, opts
Bundler.load.cache if Bundler.app_cache.exist?
- if Bundler.settings[:clean] && Bundler.settings[:path]
+ if Bundler.settings[:clean] && !Bundler.use_system_gems?
require "bundler/cli/clean"
Bundler::CLI::Clean.new(options).run
end
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index 9956411a4b..67b89d89d3 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -47,6 +47,7 @@ module Bundler
settings_flag(:suppress_install_using_messages) { bundler_2_mode? }
settings_flag(:unlock_source_unlocks_spec) { !bundler_2_mode? }
settings_flag(:update_requires_all_flag) { bundler_2_mode? }
+ settings_flag(:default_install_uses_path) { bundler_2_mode? }
settings_option(:default_cli_command) { bundler_2_mode? ? :cli_help : :install }
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index 5996d185da..6a86cc59c5 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -152,7 +152,7 @@ module Bundler
# double-assignment to avoid warnings about variables that will be used by ERB
bin_path = Bundler.bin_path
unless path = Bundler.settings[:path]
- raise "Can't standalone without a path set"
+ raise "Can't standalone without an explicit path set"
end
standalone_path = standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
@@ -257,7 +257,7 @@ module Bundler
Bundler.mkdir_p(p)
end unless Bundler.bundle_path.exist?
rescue Errno::EEXIST
- raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " \
+ raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index aa512cb2e9..4aeffa7265 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -28,7 +28,7 @@ module Bundler
trees.reject! {|t| !maximal.include?(t.last) } if maximal
trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
- trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
+ trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement.to_s] } }
o << trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
t = String.new
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 9cc80a0f99..78dcf89160 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -16,6 +16,7 @@ module Bundler
cache_all_platforms
cache_command_is_package
console_command
+ default_install_uses_path
deployment
deployment_means_frozen
disable_checksum_validation
@@ -38,6 +39,7 @@ module Bundler
no_install
no_prune
only_update_to_newer_versions
+ path.system
plugins
prefer_gems_rb
setup_makes_kernel_gem_public
@@ -206,21 +208,56 @@ module Bundler
locations
end
- # @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
+ # for legacy reasons, 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]
- return path if path && !@local_config.key?(key)
+ if path && !@temporary.key?(key) && !@local_config.key?(key)
+ return Path.new(path, false, false, false)
+ end
- if path = self[:path]
- "#{path}/#{Bundler.ruby_scope}"
- else
- Bundler.rubygems.gem_dir
+ system_path = self["path.system"] || (self[:disable_shared_gems] == false)
+ Path.new(self[:path], true, system_path, Bundler.feature_flag.default_install_uses_path?)
+ end
+
+ Path = Struct.new(:explicit_path, :append_ruby_scope, :system_path, :default_install_uses_path) do
+ def path
+ path = base_path
+ path = File.join(path, Bundler.ruby_scope) if append_ruby_scope && !use_system_gems?
+ path
+ end
+
+ def use_system_gems?
+ return true if system_path
+ return false if explicit_path
+ !default_install_uses_path
+ end
+
+ def base_path
+ path = explicit_path
+ path ||= ".bundle" if default_install_uses_path
+ path ||= Bundler.rubygems.gem_dir
+ path
+ end
+
+ def validate!
+ return unless explicit_path && system_path
+ path = Bundler.settings.pretty_values_for(:path)
+ path.unshift(nil, "path:") unless path.empty?
+ system_path = Bundler.settings.pretty_values_for("path.system")
+ system_path.unshift(nil, "path.system:") unless system_path.empty?
+ disable_shared_gems = Bundler.settings.pretty_values_for(:disable_shared_gems)
+ disable_shared_gems.unshift(nil, "disable_shared_gems:") unless disable_shared_gems.empty?
+ raise InvalidOption,
+ "Using a custom path while using system gems is unsupported.\n#{path.join("\n")}\n#{system_path.join("\n")}\n#{disable_shared_gems.join("\n")}"
end
end
def allow_sudo?
- !@local_config.key?(key_for(:path))
+ key = key_for(:path)
+ path_configured = @temporary.key?(key) || @local_config.key?(key)
+ !path_configured
end
def ignore_config?
diff --git a/lib/bundler/settings/validator.rb b/lib/bundler/settings/validator.rb
index 263e6d9325..cacb9f91da 100644
--- a/lib/bundler/settings/validator.rb
+++ b/lib/bundler/settings/validator.rb
@@ -54,10 +54,10 @@ module Bundler
rules_to_validate.each {|rule| rule.validate(key, value, settings) }
end
- rule %w[path disable_shared_gems], "path and disable_shared_gems are mutually exclusive" do |key, value, settings|
+ rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings|
if key == "path" && value
- set(settings, :disabled_shared_gems, nil)
- elsif key == "disable_shared_gems" && value
+ set(settings, "path.system", nil)
+ elsif key == "path.system" && value
set(settings, :path, nil)
end
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 0ac45b3d70..511216a5c5 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -377,7 +377,6 @@ module Bundler
return false unless spec.remote
spec.fetch_platform
- Bundler.ui.confirm("Fetching #{version_message(spec)}")
download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
@@ -443,6 +442,7 @@ module Bundler
end
else
uri = spec.remote.uri
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
Bundler.rubygems.download_gem(spec, uri, download_path)
cache_globally(spec, local_path)
end
diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn
index 99746d57bb..dd315b9955 100644
--- a/man/bundle-config.ronn
+++ b/man/bundle-config.ronn
@@ -141,6 +141,9 @@ learn more about their operation in [bundle install(1)][bundle-install].
`bundle install`.
* `console` (`BUNDLE_CONSOLE`):
The console that `bundle console` starts. Defaults to `irb`.
+* `default_install_uses_path` (`BUNDLE_DEFAULT_INSTALL_USES_PATH`):
+ Whether a `bundle install` without an explicit `--path` argument defaults
+ to installing gems in `.bundle`.
* `deployment` (`BUNDLE_DEPLOYMENT`):
Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the
lockfile has not been updated, running Bundler commands will be blocked.
@@ -205,6 +208,8 @@ learn more about their operation in [bundle install(1)][bundle-install].
of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location
will be installed by `bundle install`. Defaults to `Gem.dir`. When --deployment
is used, defaults to vendor/bundle.
+* `path.system` (`BUNDLE_PATH__SYSTEM`):
+ Whether Bundler will install gems into the default system path (`Gem.dir`).
* `plugins` (`BUNDLE_PLUGINS`):
Enable Bundler's experimental plugin system.
* `prefer_gems_rb` (`BUNDLE_PREFER_GEMS_RB`)
diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb
index 882d368358..633aed12db 100644
--- a/spec/bundler/bundler_spec.rb
+++ b/spec/bundler/bundler_spec.rb
@@ -145,8 +145,8 @@ RSpec.describe Bundler do
context "disable_shared_gems" do
it "should unset GEM_PATH with empty string" do
env = {}
- settings = { :disable_shared_gems => true }
- Bundler.send(:configure_gem_path, env, settings)
+ expect(Bundler).to receive(:use_system_gems?).and_return(false)
+ Bundler.send(:configure_gem_path, env)
expect(env.keys).to include("GEM_PATH")
expect(env["GEM_PATH"]).to eq ""
end
diff --git a/spec/install/path_spec.rb b/spec/install/path_spec.rb
index f3e17845e3..fb356899a6 100644
--- a/spec/install/path_spec.rb
+++ b/spec/install/path_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe "bundle install" do
Dir.chdir(dir) do
bundle! :install, forgotten_command_line_options(:path => "vendor/bundle")
- expect(out).to include("installed into ./vendor/bundle")
+ expect(out).to include("installed into `./vendor/bundle`")
end
dir.rmtree
@@ -32,7 +32,7 @@ RSpec.describe "bundle install" do
it "prints a warning to let the user know what has happened with bundle --path vendor/bundle" do
bundle! :install, forgotten_command_line_options(:path => "vendor/bundle")
- expect(out).to include("gems are installed into ./vendor")
+ expect(out).to include("gems are installed into `./vendor/bundle`")
end
it "disallows --path vendor/bundle --system", :bundler => "< 2" do
diff --git a/spec/install/post_bundle_message_spec.rb b/spec/install/post_bundle_message_spec.rb
index 248ef2166a..36d578cb95 100644
--- a/spec/install/post_bundle_message_spec.rb
+++ b/spec/install/post_bundle_message_spec.rb
@@ -83,14 +83,14 @@ RSpec.describe "post bundle message" do
it "with an absolute --path inside the cwd" do
bundle! :install, forgotten_command_line_options(:path => bundled_app("cache"))
- expect(out).to include("Bundled gems are installed into ./cache")
+ expect(out).to include("Bundled gems are installed into `./cache`")
expect(out).to_not include("Gems in the group")
expect(out).to include(bundle_complete_message)
end
it "with an absolute --path outside the cwd" do
bundle! :install, forgotten_command_line_options(:path => tmp("not_bundled_app"))
- expect(out).to include("Bundled gems are installed into #{tmp("not_bundled_app")}")
+ expect(out).to include("Bundled gems are installed into `#{tmp("not_bundled_app")}`")
expect(out).to_not include("Gems in the group")
expect(out).to include(bundle_complete_message)
end