diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bundler/cli.rb | 2 | ||||
-rw-r--r-- | lib/bundler/definition.rb | 104 | ||||
-rw-r--r-- | lib/bundler/gem_helper.rb | 4 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/standard.yml.tt | 2 | ||||
-rw-r--r-- | lib/bundler/version.rb | 2 | ||||
-rw-r--r-- | lib/rubygems.rb | 34 | ||||
-rw-r--r-- | lib/rubygems/installer.rb | 12 | ||||
-rw-r--r-- | lib/rubygems/specification.rb | 60 |
8 files changed, 85 insertions, 135 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 02c2d19c83..f178560938 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -552,7 +552,7 @@ module Bundler method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version." method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group." def viz - SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/rubygems/bundler-graph" + SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph" require_relative "cli/viz" Viz.new(options.dup).run end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index b88e41ea39..ebfc78c031 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -649,25 +649,16 @@ module Bundler end def converge_dependencies - frozen = Bundler.frozen_bundle? (@dependencies + locked_dependencies).each do |dep| - locked_source = @locked_deps[dep.name] - # This is to make sure that if bundler is installing in deployment mode and - # after locked_source and sources don't match, we still use locked_source. - if frozen && !locked_source.nil? && - locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist? - dep.source = locked_source.source - elsif dep.source + if dep.source dep.source = sources.get(dep.source) end end changes = false - # We want to know if all match, but don't want to check all entries - # This means we need to return false if any dependency doesn't match - # the lock or doesn't exist in the lock. - @dependencies.each do |dependency| - unless locked_dep = @locked_deps[dependency.name] + + @dependencies.each do |dep| + unless locked_dep = @locked_deps[dep.name] changes = true next end @@ -678,11 +669,11 @@ module Bundler # directive, the lockfile dependencies and resolved dependencies end up # with a mismatch on #type. Work around that by setting the type on the # dep from the lockfile. - locked_dep.instance_variable_set(:@type, dependency.type) + locked_dep.instance_variable_set(:@type, dep.type) # We already know the name matches from the hash lookup # so we only need to check the requirement now - changes ||= dependency.requirement != locked_dep.requirement + changes ||= dep.requirement != locked_dep.requirement end changes @@ -692,34 +683,34 @@ module Bundler # commonly happen if the Gemfile has changed since the lockfile was last # generated def converge_locked_specs - deps = [] - - # Build a list of dependencies that are the same in the Gemfile - # and Gemfile.lock. If the Gemfile modified a dependency, but - # the gem in the Gemfile.lock still satisfies it, this is fine - # too. - @dependencies.each do |dep| - locked_dep = @locked_deps[dep.name] + resolve = converge_specs(@locked_specs) - # If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep - locked_dep = nil unless locked_dep == dep + diff = nil - if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep) - deps << dep - elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source) - @locked_specs.each do |s| - @unlock[:gems] << s.name if s.source == dep.source - end + # Now, we unlock any sources that do not have anymore gems pinned to it + sources.all_sources.each do |source| + next unless source.respond_to?(:unlock!) - dep.source.unlock! if dep.source.respond_to?(:unlock!) - dep.source.specs.each {|s| @unlock[:gems] << s.name } + unless resolve.any? {|s| s.source == source } + diff ||= @locked_specs.to_a - resolve.to_a + source.unlock! if diff.any? {|s| s.source == source } end end + resolve + end + + def converge_specs(specs) + deps = [] converged = [] - @locked_specs.each do |s| + specs.each do |s| # Replace the locked dependency's source with the equivalent source from the Gemfile dep = @dependencies.find {|d| s.satisfies?(d) } + + if dep && (!dep.source || s.source.include?(dep.source)) + deps << dep + end + s.source = (dep && dep.source) || sources.get(s.source) unless multisource_allowed? # Don't add a spec to the list if its source is expired. For example, @@ -737,7 +728,7 @@ module Bundler rescue PathError, GitError # if we won't need the source (according to the lockfile), # don't error if the path/git source isn't available - next if @locked_specs. + next if specs. for(requested_dependencies, false, true). none? {|locked_spec| locked_spec.source == s.source } @@ -753,35 +744,15 @@ module Bundler s.dependencies.replace(new_spec.dependencies) end - converged << s - end - - resolve = SpecSet.new(converged) - resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) }) - diff = nil - - # Now, we unlock any sources that do not have anymore gems pinned to it - sources.all_sources.each do |source| - next unless source.respond_to?(:unlock!) - - unless resolve.any? {|s| s.source == source } - diff ||= @locked_specs.to_a - resolve.to_a - source.unlock! if diff.any? {|s| s.source == source } + if dep.nil? && @dependencies.find {|d| s.name == d.name } + @unlock[:gems] << s.name + else + converged << s end end - resolve - end - - def in_locked_deps?(dep, locked_dep) - # Because the lockfile can't link a dep to a specific remote, we need to - # treat sources as equivalent anytime the locked dep has all the remotes - # that the Gemfile dep does. - locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source) - end - - def satisfies_locked_spec?(dep) - @locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) } + resolve = SpecSet.new(converged) + SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) }) end def metadata_dependencies @@ -874,16 +845,11 @@ module Bundler def additional_base_requirements_for_resolve return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) - dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) } - @locked_gems.specs.reduce({}) do |requirements, locked_spec| + converge_specs(@locked_gems.specs).map do |locked_spec| name = locked_spec.name - dependency = dependencies_by_name[name] - next requirements if @locked_gems.dependencies[name] != dependency - next requirements if dependency && dependency.source.is_a?(Source::Path) dep = Gem::Dependency.new(name, ">= #{locked_spec.version}") - requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform) - requirements - end.values + DepProxy.get_proxy(dep, locked_spec.platform) + end end def equivalent_rubygems_remotes?(source) diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index 60b9e57887..034f2e5960 100644 --- a/lib/bundler/gem_helper.rb +++ b/lib/bundler/gem_helper.rb @@ -129,8 +129,8 @@ module Bundler def git_push(remote = nil) remote ||= default_remote - sh(%W[git push #{remote} refs/heads/#{current_branch}]) - sh(%W[git push #{remote} refs/tags/#{version_tag}]) + sh("git push #{remote} refs/heads/#{current_branch}".shellsplit) + sh("git push #{remote} refs/tags/#{version_tag}".shellsplit) Bundler.ui.confirm "Pushed git commits and release tag." end diff --git a/lib/bundler/templates/newgem/standard.yml.tt b/lib/bundler/templates/newgem/standard.yml.tt index e720f41031..9e88fbbe8b 100644 --- a/lib/bundler/templates/newgem/standard.yml.tt +++ b/lib/bundler/templates/newgem/standard.yml.tt @@ -1,4 +1,2 @@ # For available configuration options, see: # https://github.com/testdouble/standard - -default_ignores: false diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index a540110962..9abcdbc657 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.2.31".freeze + VERSION = "2.2.32".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 717546e3ec..79857b80b9 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = "3.2.31".freeze + VERSION = "3.2.32".freeze end # Must be first since it unloads the prelude from 1.9.2 @@ -1327,22 +1327,6 @@ require_relative 'rubygems/exceptions' # REFACTOR: This should be pulled out into some kind of hacks file. begin ## - # Defaults the operating system (or packager) wants to provide for RubyGems. - - require 'rubygems/defaults/operating_system' -rescue LoadError - # Ignored -rescue StandardError => e - msg = "#{e.message}\n" \ - "Loading the rubygems/defaults/operating_system.rb file caused an error. " \ - "This file is owned by your OS, not by rubygems upstream. " \ - "Please find out which OS package this file belongs to and follow the guidelines from your OS to report " \ - "the problem and ask for help." - raise e.class, msg -end - -begin - ## # Defaults the Ruby implementation wants to provide for RubyGems require "rubygems/defaults/#{RUBY_ENGINE}" @@ -1356,3 +1340,19 @@ Gem::Specification.load_defaults require_relative 'rubygems/core_ext/kernel_gem' require_relative 'rubygems/core_ext/kernel_require' require_relative 'rubygems/core_ext/kernel_warn' + +begin + ## + # Defaults the operating system (or packager) wants to provide for RubyGems. + + require 'rubygems/defaults/operating_system' +rescue LoadError + # Ignored +rescue StandardError => e + msg = "#{e.message}\n" \ + "Loading the rubygems/defaults/operating_system.rb file caused an error. " \ + "This file is owned by your OS, not by rubygems upstream. " \ + "Please find out which OS package this file belongs to and follow the guidelines from your OS to report " \ + "the problem and ask for help." + raise e.class, msg +end diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index dd6dd06eef..10341a9398 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -67,8 +67,6 @@ class Gem::Installer @path_warning = false - @install_lock = Thread::Mutex.new - class << self # # Changes in rubygems to lazily loading `rubygems/command` (in order to @@ -93,12 +91,6 @@ class Gem::Installer attr_accessor :path_warning ## - # Certain aspects of the install process are not thread-safe. This lock is - # used to allow multiple threads to install Gems at the same time. - - attr_reader :install_lock - - ## # Overrides the executable format. # # This is a sprintf format with a "%s" which will be replaced with the @@ -342,7 +334,7 @@ class Gem::Installer say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil? - Gem::Installer.install_lock.synchronize { Gem::Specification.reset } + Gem::Specification.reset run_post_install_hooks @@ -527,7 +519,7 @@ class Gem::Installer end def generate_plugins # :nodoc: - latest = Gem::Installer.install_lock.synchronize { Gem::Specification.latest_spec_for(spec.name) } + latest = Gem::Specification.latest_spec_for(spec.name) return if latest && latest.version > spec.version ensure_writable_dir @plugins_dir diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 7e49620381..2b3792ed94 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -102,12 +102,8 @@ class Gem::Specification < Gem::BasicSpecification today = Time.now.utc TODAY = Time.utc(today.year, today.month, today.day) # :nodoc: - # rubocop:disable Style/MutableConstant - LOAD_CACHE = {} # :nodoc: - # rubocop:enable Style/MutableConstant - LOAD_CACHE_MUTEX = Thread::Mutex.new - - private_constant :LOAD_CACHE if defined? private_constant + @load_cache = {} # :nodoc: + @load_cache_mutex = Thread::Mutex.new VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc: @@ -182,13 +178,23 @@ class Gem::Specification < Gem::BasicSpecification @@default_value[k].nil? end - @@stubs = nil - @@stubs_by_name = {} + def self.clear_specs # :nodoc: + @@all_specs_mutex.synchronize do + @@all = nil + @@stubs = nil + @@stubs_by_name = {} + @@spec_with_requirable_file = {} + @@active_stub_with_requirable_file = {} + end + end + private_class_method :clear_specs + + @@all_specs_mutex = Thread::Mutex.new + + clear_specs # Sentinel object to represent "not found" stubs NOT_FOUND = Struct.new(:to_spec, :this).new # :nodoc: - @@spec_with_requirable_file = {} - @@active_stub_with_requirable_file = {} # Tracking removed method calls to warn users during build time. REMOVED_METHODS = [:rubyforge_project=].freeze # :nodoc: @@ -748,23 +754,15 @@ class Gem::Specification < Gem::BasicSpecification attr_accessor :specification_version def self._all # :nodoc: - unless defined?(@@all) && @@all - @@all = stubs.map(&:to_spec) - - # After a reset, make sure already loaded specs - # are still marked as activated. - specs = {} - Gem.loaded_specs.each_value{|s| specs[s] = true } - @@all.each{|s| s.activated = true if specs[s] } - end - @@all + @@all_specs_mutex.synchronize { @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec) } end - def self._clear_load_cache # :nodoc: - LOAD_CACHE_MUTEX.synchronize do - LOAD_CACHE.clear + def self.clear_load_cache # :nodoc: + @load_cache_mutex.synchronize do + @load_cache.clear end end + private_class_method :clear_load_cache def self.each_gemspec(dirs) # :nodoc: dirs.each do |dir| @@ -1112,7 +1110,7 @@ class Gem::Specification < Gem::BasicSpecification def self.load(file) return unless file - _spec = LOAD_CACHE_MUTEX.synchronize { LOAD_CACHE[file] } + _spec = @load_cache_mutex.synchronize { @load_cache[file] } return _spec if _spec file = file.dup.tap(&Gem::UNTAINT) @@ -1127,12 +1125,12 @@ class Gem::Specification < Gem::BasicSpecification if Gem::Specification === _spec _spec.loaded_from = File.expand_path file.to_s - LOAD_CACHE_MUTEX.synchronize do - prev = LOAD_CACHE[file] + @load_cache_mutex.synchronize do + prev = @load_cache[file] if prev _spec = prev else - LOAD_CACHE[file] = _spec + @load_cache[file] = _spec end end return _spec @@ -1230,12 +1228,8 @@ class Gem::Specification < Gem::BasicSpecification def self.reset @@dirs = nil Gem.pre_reset_hooks.each {|hook| hook.call } - @@all = nil - @@stubs = nil - @@stubs_by_name = {} - @@spec_with_requirable_file = {} - @@active_stub_with_requirable_file = {} - _clear_load_cache + clear_specs + clear_load_cache unresolved = unresolved_deps unless unresolved.empty? w = "W" + "ARN" |