diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-11-01 23:29:38 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-11-01 23:29:38 +0000 |
commit | be7b5929126cb3e696ef222339237faba9b8fe5a (patch) | |
tree | 51eae376f93c09bc82dde5a657a91df2c89062e4 /lib/bundler/installer.rb | |
parent | ae49dbd392083f69026f2a0fff4a1d5f42d172a7 (diff) | |
download | ruby-be7b5929126cb3e696ef222339237faba9b8fe5a.tar.gz |
Update bundled bundler to 1.16.0.
* lib/bundler, spec/bundler: Merge bundler-1.16.0.
* common.mk: rspec examples of bundler-1.16.0 needs require option.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/bundler/installer.rb')
-rw-r--r-- | lib/bundler/installer.rb | 154 |
1 files changed, 104 insertions, 50 deletions
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index bce0e46393..d1066c9c19 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "erb" require "rubygems/dependency_installer" require "bundler/worker" @@ -33,25 +34,26 @@ module Bundler # Runs the install procedures for a specific Gemfile. # - # Firstly, this method will check to see if Bundler.bundle_path exists - # and if not then will create it. This is usually the location of gems - # on the system, be it RVM or at a system path. + # Firstly, this method will check to see if `Bundler.bundle_path` exists + # and if not then Bundler will create the directory. This is usually the same + # location as RubyGems which typically is the `~/.gem` directory + # unless other specified. # - # Secondly, it checks if Bundler has been configured to be "frozen" + # Secondly, it checks if Bundler has been configured to be "frozen". # Frozen ensures that the Gemfile and the Gemfile.lock file are matching. # This stops a situation where a developer may update the Gemfile but may not run # `bundle install`, which leads to the Gemfile.lock file not being correctly updated. # If this file is not correctly updated then any other developer running # `bundle install` will potentially not install the correct gems. # - # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile using - # Bundler::Environment#dependencies. If there are no dependencies specified then - # Bundler returns a warning message stating so and this method returns. + # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile. + # If there are no dependencies specified then Bundler returns a warning message stating + # so and this method returns. # - # Fourthly, Bundler checks if the default lockfile (Gemfile.lock) exists, and if so - # then proceeds to set up a definition based on the default gemfile (Gemfile) and the - # default lock file (Gemfile.lock). However, this is not the case if the platform is different - # to that which is specified in Gemfile.lock, or if there are any missing specs for the gems. + # Fourthly, Bundler checks if the Gemfile.lock exists, and if so + # then proceeds to set up a definition based on the Gemfile and the Gemfile.lock. + # During this step Bundler will also download information about any new gems + # that are not in the Gemfile.lock and resolve any dependencies if needed. # # Fifthly, Bundler resolves the dependencies either through a cache of gems or by remote. # This then leads into the gems being installed, along with stubs for their executables, @@ -61,26 +63,36 @@ module Bundler # Sixthly, a new Gemfile.lock is created from the installed gems to ensure that the next time # that a user runs `bundle install` they will receive any updates from this process. # - # Finally: TODO add documentation for how the standalone process works. + # Finally, if the user has specified the standalone flag, Bundler will generate the needed + # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more + # information. def run(options) create_bundle_path - if Bundler.settings[:frozen] - @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment]) - end + ProcessLock.lock do + if Bundler.frozen? + @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment]) + end - if @definition.dependencies.empty? - Bundler.ui.warn "The Gemfile specifies no dependencies" - lock - return - end + if @definition.dependencies.empty? + Bundler.ui.warn "The Gemfile specifies no dependencies" + lock + return + end - resolve_if_need(options) - ensure_specs_are_compatible! - install(options) + if resolve_if_needed(options) + ensure_specs_are_compatible! + warn_on_incompatible_bundler_deps + load_plugins + options.delete(:jobs) + else + options[:jobs] = 1 # to avoid the overhead of Bundler::Worker + end + install(options) - lock unless Bundler.settings[:frozen] - Standalone.new(options[:standalone], @definition).generate if options[:standalone] + lock unless Bundler.frozen? + Standalone.new(options[:standalone], @definition).generate if options[:standalone] + end end def generate_bundler_executable_stubs(spec, options = {}) @@ -101,15 +113,21 @@ module Bundler end # double-assignment to avoid warnings about variables that will be used by ERB - bin_path = bin_path = Bundler.bin_path - template = template = File.read(File.expand_path("../templates/Executable", __FILE__)) - relative_gemfile_path = relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path) - ruby_command = ruby_command = Thor::Util.ruby_command + bin_path = Bundler.bin_path + bin_path = bin_path + relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path) + relative_gemfile_path = relative_gemfile_path + ruby_command = Thor::Util.ruby_command + ruby_command = ruby_command + template_path = File.expand_path("../templates/Executable", __FILE__) + if spec.name == "bundler" + template_path += ".bundler" + spec.executables = %(bundle) + end + template = File.read(template_path) exists = [] spec.executables.each do |executable| - next if executable == "bundle" - binstub_path = "#{bin_path}/#{executable}" if File.exist?(binstub_path) && !options[:force] exists << executable @@ -139,13 +157,19 @@ module Bundler def generate_standalone_bundler_executable_stubs(spec) # double-assignment to avoid warnings about variables that will be used by ERB bin_path = Bundler.bin_path - standalone_path = standalone_path = Bundler.root.join(Bundler.settings[:path]).relative_path_from(bin_path) + unless path = Bundler.settings[:path] + raise "Can't standalone without an explicit path set" + end + standalone_path = Bundler.root.join(path).relative_path_from(bin_path) + standalone_path = standalone_path template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__)) - ruby_command = ruby_command = Thor::Util.ruby_command + ruby_command = Thor::Util.ruby_command + ruby_command = ruby_command spec.executables.each do |executable| next if executable == "bundle" - executable_path = executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path) + executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path) + executable_path = executable_path File.open "#{bin_path}/#{executable}", "w", 0o755 do |f| f.puts ERB.new(template, nil, "-").result(binding) end @@ -159,13 +183,32 @@ module Bundler # that said, it's a rare situation (other than rake), and parallel # installation is SO MUCH FASTER. so we let people opt in. def install(options) - Bundler.rubygems.load_plugins force = options["force"] - jobs = 1 - jobs = [Bundler.settings[:jobs].to_i - 1, 1].max if can_install_in_parallel? + jobs = options.delete(:jobs) do + if can_install_in_parallel? + [Bundler.settings[:jobs].to_i - 1, 1].max + else + 1 + end + end install_in_parallel jobs, options[:standalone], force end + def load_plugins + Bundler.rubygems.load_plugins + + requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } + path_plugin_files = requested_path_gems.map do |spec| + begin + Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") + rescue TypeError + error_message = "#{spec.name} #{spec.version} has an invalid gemspec" + raise Gem::InvalidSpecificationException, error_message + end + end.flatten + Bundler.rubygems.load_plugin_files(path_plugin_files) + end + def ensure_specs_are_compatible! system_ruby = Bundler::RubyVersion.system rubygems_version = Gem::Version.create(Gem::VERSION) @@ -184,12 +227,28 @@ module Bundler end end + def warn_on_incompatible_bundler_deps + bundler_version = Gem::Version.create(Bundler::VERSION) + @definition.specs.each do |spec| + spec.dependencies.each do |dep| + next if dep.type == :development + next unless dep.name == "bundler".freeze + next if dep.requirement.satisfied_by?(bundler_version) + + Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \ + " #{SharedHelpers.pretty_dependency(dep)}" \ + ", which is unsatisfied by the current bundler version #{VERSION}" \ + ", so the dependency is being ignored" + end + end + end + def can_install_in_parallel? if Bundler.rubygems.provides?(">= 2.1.0") true else - Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\ - "gems will be installed one at a time. Upgrade to Rubygems 2.1.0 " \ + Bundler.ui.warn "RubyGems #{Gem::VERSION} is not threadsafe, so your "\ + "gems will be installed one at a time. Upgrade to RubyGems 2.1.0 " \ "or higher to enable parallel gem installation." false end @@ -207,23 +266,18 @@ 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 - def resolve_if_need(options) - if !options["update"] && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file? - local = Bundler.ui.silence do - begin - tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil) - true unless tmpdef.new_platform? || tmpdef.missing_dependencies.any? - rescue BundlerError - end - end + # returns whether or not a re-resolve was needed + def resolve_if_needed(options) + if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file? + return false if @definition.nothing_changed? && !@definition.missing_specs? end - return if local options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely! + true end def lock(opts = {}) |