diff options
author | Samuel Giddins <segiddins@segiddins.me> | 2017-07-14 17:59:30 +0300 |
---|---|---|
committer | Samuel Giddins <segiddins@segiddins.me> | 2017-07-23 12:39:02 -0500 |
commit | 07fedc3f9ee972d5da43f8a77a162bf2c9ca4b1b (patch) | |
tree | 49eb8accade0d3f6ae19cd350c357dd6193eaeaa | |
parent | 1223f932c0790687d1743e5449e54b67f60f4c45 (diff) | |
download | bundler-07fedc3f9ee972d5da43f8a77a162bf2c9ca4b1b.tar.gz |
Default the install path to ./bundle in Bundler 2
-rw-r--r-- | lib/bundler.rb | 27 | ||||
-rw-r--r-- | lib/bundler/cli/check.rb | 5 | ||||
-rw-r--r-- | lib/bundler/cli/clean.rb | 2 | ||||
-rw-r--r-- | lib/bundler/cli/install.rb | 17 | ||||
-rw-r--r-- | lib/bundler/cli/update.rb | 2 | ||||
-rw-r--r-- | lib/bundler/feature_flag.rb | 1 | ||||
-rw-r--r-- | lib/bundler/installer.rb | 4 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 2 | ||||
-rw-r--r-- | lib/bundler/settings.rb | 51 | ||||
-rw-r--r-- | lib/bundler/settings/validator.rb | 6 | ||||
-rw-r--r-- | lib/bundler/source/rubygems.rb | 2 | ||||
-rw-r--r-- | man/bundle-config.ronn | 5 | ||||
-rw-r--r-- | spec/bundler/bundler_spec.rb | 4 | ||||
-rw-r--r-- | spec/install/path_spec.rb | 4 | ||||
-rw-r--r-- | spec/install/post_bundle_message_spec.rb | 4 |
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 |