diff --git a/lib/bundler.rb b/lib/bundler.rb index 7df22ab3a5..24785ef5eb 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -53,13 +53,12 @@ module Bundler autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) autoload :Graph, File.expand_path("bundler/graph", __dir__) - autoload :IncompleteSpecification, File.expand_path("bundler/incomplete_specification", __dir__) autoload :Index, File.expand_path("bundler/index", __dir__) autoload :Injector, File.expand_path("bundler/injector", __dir__) autoload :Installer, File.expand_path("bundler/installer", __dir__) autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__) autoload :LockfileParser, File.expand_path("bundler/lockfile_parser", __dir__) - autoload :MatchPlatform, File.expand_path("bundler/match_platform", __dir__) + autoload :MatchRemoteMetadata, File.expand_path("bundler/match_remote_metadata", __dir__) autoload :ProcessLock, File.expand_path("bundler/process_lock", __dir__) autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__) autoload :Resolver, File.expand_path("bundler/resolver", __dir__) @@ -332,9 +331,9 @@ module Bundler FileUtils.remove_entry_secure(path) if path && File.exist?(path) rescue ArgumentError message = < e @resolve = nil + @resolver = nil @specs = nil @gem_version_promoter = nil @@ -288,7 +287,7 @@ module Bundler end else Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") - @reresolve = reresolve + resolver.start(expanded_dependencies) end end @@ -482,11 +481,18 @@ module Bundler private - def reresolve - last_resolve = converge_locked_specs - remove_ruby_from_platforms_if_necessary!(dependencies) - expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true) - Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) + def resolver + @resolver ||= begin + last_resolve = converge_locked_specs + Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) + end + end + + def expanded_dependencies + @expanded_dependencies ||= begin + remove_ruby_from_platforms_if_necessary!(dependencies) + expand_dependencies(dependencies + metadata_dependencies, true) + end end def filter_specs(specs, deps) @@ -514,15 +520,13 @@ module Bundler raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}" end - if @reresolve.nil? + loop do incomplete_specs = specs.incomplete_specs + break if incomplete_specs.empty? - if incomplete_specs.any? - Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies") - @unlock[:gems].concat(incomplete_specs.map(&:name)) - @resolve = reresolve - specs = resolve.materialize(dependencies) - end + Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies") + @resolve = resolver.start(expanded_dependencies, :exclude_specs => incomplete_specs) + specs = resolve.materialize(dependencies) end bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last @@ -715,7 +719,9 @@ module Bundler # commonly happen if the Gemfile has changed since the lockfile was last # generated def converge_locked_specs - resolve = converge_specs(@locked_specs) + converged = converge_specs(@locked_specs) + + resolve = SpecSet.new(converged.reject {|s| @unlock[:gems].include?(s.name) }) diff = nil @@ -788,7 +794,7 @@ module Bundler end end - SpecSet.new(filter_specs(converged, deps).reject {|s| @unlock[:gems].include?(s.name) }) + filter_specs(converged, deps) end def metadata_dependencies @@ -877,10 +883,8 @@ module Bundler def additional_base_requirements_for_resolve return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) converge_specs(@originally_locked_specs).map do |locked_spec| - name = locked_spec.name - dep = Dependency.new(name, ">= #{locked_spec.version}") - DepProxy.get_proxy(dep, locked_spec.platform) - end + Dependency.new(locked_spec.name, ">= #{locked_spec.version}") + end.uniq end def remove_ruby_from_platforms_if_necessary!(dependencies) @@ -888,10 +892,11 @@ module Bundler Bundler.local_platform == Gem::Platform::RUBY || !platforms.include?(Gem::Platform::RUBY) || (@new_platform && platforms.last == Gem::Platform::RUBY) || - !@originally_locked_specs.incomplete_ruby_specs?(dependencies) + !@originally_locked_specs.incomplete_ruby_specs?(expand_dependencies(dependencies)) remove_platform(Gem::Platform::RUBY) add_current_platform + resolver.platforms = @platforms end def source_map diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb index e9aa366b41..ea197328ba 100644 --- a/lib/bundler/endpoint_specification.rb +++ b/lib/bundler/endpoint_specification.rb @@ -3,7 +3,7 @@ module Bundler # used for Creating Specifications from the Gemcutter Endpoint class EndpointSpecification < Gem::Specification - include MatchPlatform + include MatchRemoteMetadata attr_reader :name, :version, :platform, :checksum attr_accessor :source, :remote, :dependencies @@ -22,17 +22,6 @@ module Bundler parse_metadata(metadata) end - def required_ruby_version - @required_ruby_version ||= _remote_specification.required_ruby_version - end - - # A fallback is included because the original version of the specification - # API didn't include that field, so some marshalled specs in the index have it - # set to +nil+. - def required_rubygems_version - @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default - end - def fetch_platform @platform end diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb index 3cce3f2139..ddf7446dd2 100644 --- a/lib/bundler/gem_version_promoter.rb +++ b/lib/bundler/gem_version_promoter.rb @@ -88,6 +88,10 @@ module Bundler end end + def reset + @sort_versions = {} + end + # @return [bool] Convenience method for testing value of level variable. def major? level == :major diff --git a/lib/bundler/incomplete_specification.rb b/lib/bundler/incomplete_specification.rb deleted file mode 100644 index 6d0b9b901c..0000000000 --- a/lib/bundler/incomplete_specification.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Bundler - class IncompleteSpecification - attr_reader :name, :platform - - def initialize(name, platform) - @name = name - @platform = platform - end - end -end diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb index 8ef580f1f0..25e055fbe4 100644 --- a/lib/bundler/inline.rb +++ b/lib/bundler/inline.rb @@ -54,7 +54,7 @@ def gemfile(install = false, options = {}, &gemfile) Bundler.ui = install ? ui : Bundler::UI::Silent.new if install || definition.missing_specs? - Bundler.settings.temporary(:inline => true) do + Bundler.settings.temporary(:inline => true, :no_install => false) do installer = Bundler::Installer.install(Bundler.root, definition, :system => true) installer.post_install_messages.each do |name, message| Bundler.ui.info "Post-install message from #{name}:\n#{message}" diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index b7b0e36dfd..1b17de5d4e 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -238,19 +238,14 @@ module Bundler end def ensure_specs_are_compatible! - system_ruby = Bundler::RubyVersion.system - rubygems_version = Bundler.rubygems.version @definition.specs.each do |spec| - if required_ruby_version = spec.required_ruby_version - unless required_ruby_version.satisfied_by?(system_ruby.gem_version) - raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \ - "which is incompatible with the current version, #{system_ruby}" - end + unless spec.matches_current_ruby? + raise InstallError, "#{spec.full_name} requires ruby version #{spec.required_ruby_version}, " \ + "which is incompatible with the current version, #{Gem.ruby_version}" end - next unless required_rubygems_version = spec.required_rubygems_version - unless required_rubygems_version.satisfied_by?(rubygems_version) - raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \ - "which is incompatible with the current version, #{rubygems_version}" + unless spec.matches_current_rubygems? + raise InstallError, "#{spec.full_name} requires rubygems version #{spec.required_rubygems_version}, " \ + "which is incompatible with the current version, #{Gem.rubygems_version}" end end end diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 5b40bec5a8..ec141cfa27 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require_relative "match_platform" - module Bundler class LazySpecification include MatchPlatform @@ -97,8 +95,8 @@ module Bundler @specification = begin search = candidates.reverse.find do |spec| spec.is_a?(StubSpecification) || - (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && - spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) + (spec.matches_current_ruby? && + spec.matches_current_rubygems?) end if search.nil? && Bundler.frozen_bundle? search = candidates.last diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1 index 20430a78a0..f6e5004b5b 100644 --- a/lib/bundler/man/bundle-add.1 +++ b/lib/bundler/man/bundle-add.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-ADD" "1" "July 2022" "" "" +.TH "BUNDLE\-ADD" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1 index 9c57c7c9c5..d1204104b1 100644 --- a/lib/bundler/man/bundle-binstubs.1 +++ b/lib/bundler/man/bundle-binstubs.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-BINSTUBS" "1" "July 2022" "" "" +.TH "BUNDLE\-BINSTUBS" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1 index fdaaa3b92a..1393caec65 100644 --- a/lib/bundler/man/bundle-cache.1 +++ b/lib/bundler/man/bundle-cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CACHE" "1" "July 2022" "" "" +.TH "BUNDLE\-CACHE" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1 index 5be7886274..71ddb5cee3 100644 --- a/lib/bundler/man/bundle-check.1 +++ b/lib/bundler/man/bundle-check.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CHECK" "1" "July 2022" "" "" +.TH "BUNDLE\-CHECK" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1 index 2bb95ed2de..e5dc4ccf92 100644 --- a/lib/bundler/man/bundle-clean.1 +++ b/lib/bundler/man/bundle-clean.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CLEAN" "1" "July 2022" "" "" +.TH "BUNDLE\-CLEAN" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 9f7887ca91..ffc91ed492 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -1,13 +1,22 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CONFIG" "1" "July 2022" "" "" +.TH "BUNDLE\-CONFIG" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-config\fR \- Set bundler configuration options . .SH "SYNOPSIS" -\fBbundle config\fR [list|get|set|unset] [\fIname\fR [\fIvalue\fR]] +\fBbundle config\fR list +. +.br +\fBbundle config\fR [get] NAME +. +.br +\fBbundle config\fR [set] NAME VALUE +. +.br +\fBbundle config\fR unset NAME . .SH "DESCRIPTION" This command allows you to interact with Bundler\'s configuration system\. diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 905c85fcd9..6f9edc9c39 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -3,7 +3,10 @@ bundle-config(1) -- Set bundler configuration options ## SYNOPSIS -`bundle config` [list|get|set|unset] [ []] +`bundle config` list
+`bundle config` [get] NAME
+`bundle config` [set] NAME VALUE
+`bundle config` unset NAME ## DESCRIPTION diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1 index 6aad9858db..3f18aaf569 100644 --- a/lib/bundler/man/bundle-doctor.1 +++ b/lib/bundler/man/bundle-doctor.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-DOCTOR" "1" "July 2022" "" "" +.TH "BUNDLE\-DOCTOR" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-doctor\fR \- Checks the bundle for common problems diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1 index 210dd178e8..7f6a892f6c 100644 --- a/lib/bundler/man/bundle-exec.1 +++ b/lib/bundler/man/bundle-exec.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-EXEC" "1" "July 2022" "" "" +.TH "BUNDLE\-EXEC" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-exec\fR \- Execute a command in the context of the bundle diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1 index 0fb6f7d0ab..63d611bdd2 100644 --- a/lib/bundler/man/bundle-gem.1 +++ b/lib/bundler/man/bundle-gem.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-GEM" "1" "July 2022" "" "" +.TH "BUNDLE\-GEM" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1 index d3bad843b8..ae9bc48539 100644 --- a/lib/bundler/man/bundle-info.1 +++ b/lib/bundler/man/bundle-info.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INFO" "1" "July 2022" "" "" +.TH "BUNDLE\-INFO" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-info\fR \- Show information for the given gem in your bundle diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1 index 0b3abfeefc..0b06ce8997 100644 --- a/lib/bundler/man/bundle-init.1 +++ b/lib/bundler/man/bundle-init.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INIT" "1" "July 2022" "" "" +.TH "BUNDLE\-INIT" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-init\fR \- Generates a Gemfile into the current working directory diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1 index 53f2eaae0a..4ad37ec3eb 100644 --- a/lib/bundler/man/bundle-inject.1 +++ b/lib/bundler/man/bundle-inject.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INJECT" "1" "July 2022" "" "" +.TH "BUNDLE\-INJECT" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1 index 8e94fe2437..f219a062b1 100644 --- a/lib/bundler/man/bundle-install.1 +++ b/lib/bundler/man/bundle-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INSTALL" "1" "July 2022" "" "" +.TH "BUNDLE\-INSTALL" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1 index 3a9cc9a237..6e89f810a1 100644 --- a/lib/bundler/man/bundle-list.1 +++ b/lib/bundler/man/bundle-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LIST" "1" "July 2022" "" "" +.TH "BUNDLE\-LIST" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-list\fR \- List all the gems in the bundle diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1 index ac03c5478e..f5f0ce2bdb 100644 --- a/lib/bundler/man/bundle-lock.1 +++ b/lib/bundler/man/bundle-lock.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LOCK" "1" "July 2022" "" "" +.TH "BUNDLE\-LOCK" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1 index be6c5af248..7bda0afd33 100644 --- a/lib/bundler/man/bundle-open.1 +++ b/lib/bundler/man/bundle-open.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OPEN" "1" "July 2022" "" "" +.TH "BUNDLE\-OPEN" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1 index fc3d5e8caf..a2b8e2bf92 100644 --- a/lib/bundler/man/bundle-outdated.1 +++ b/lib/bundler/man/bundle-outdated.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OUTDATED" "1" "July 2022" "" "" +.TH "BUNDLE\-OUTDATED" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-outdated\fR \- List installed gems with newer versions available diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1 index f5a90c59e9..7fda4ef046 100644 --- a/lib/bundler/man/bundle-platform.1 +++ b/lib/bundler/man/bundle-platform.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PLATFORM" "1" "July 2022" "" "" +.TH "BUNDLE\-PLATFORM" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-platform\fR \- Displays platform compatibility information diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1 new file mode 100644 index 0000000000..7210806327 --- /dev/null +++ b/lib/bundler/man/bundle-plugin.1 @@ -0,0 +1,81 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "BUNDLE\-PLUGIN" "1" "August 2022" "" "" +. +.SH "NAME" +\fBbundle\-plugin\fR \- Manage Bundler plugins +. +.SH "SYNOPSIS" +\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git|\-\-local_git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR] +. +.br +\fBbundle plugin\fR uninstall PLUGINS +. +.br +\fBbundle plugin\fR list +. +.br +\fBbundle plugin\fR help [COMMAND] +. +.SH "DESCRIPTION" +You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler\. +. +.SH "SUB\-COMMANDS" +. +.SS "install" +Install the given plugin(s)\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph\fR: Install bundler\-graph gem from RubyGems\.org\. The global source, specified in source in Gemfile is ignored\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR: Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR: You can specify the version of the gem via \fB\-\-version\fR\. +. +.IP "\(bu" 4 +\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR: Install bundler\-graph gem from Git repository\. \fB\-\-git\fR can be replaced with \fB\-\-local\-git\fR\. You cannot use both \fB\-\-git\fR and \fB\-\-local\-git\fR\. You can use standard Git URLs like: +. +.IP "\(bu" 4 +\fBssh://[user@]host\.xz[:port]/path/to/repo\.git\fR +. +.IP "\(bu" 4 +\fBhttp[s]://host\.xz[:port]/path/to/repo\.git\fR +. +.IP "\(bu" 4 +\fB/path/to/repo\fR +. +.IP "\(bu" 4 +\fBfile:///path/to/repo\fR +. +.IP "" 0 +. +.IP +When you specify \fB\-\-git\fR/\fB\-\-local\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\. When you specify both, only the latter is used\. +. +.IP "" 0 +. +.SS "uninstall" +Uninstall the plugin(s) specified in PLUGINS\. +. +.SS "list" +List the installed plugins and available commands\. +. +.P +No options\. +. +.SS "help" +Describe subcommands or one specific subcommand\. +. +.P +No options\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR +. +.IP "" 0 + diff --git a/lib/bundler/man/bundle-plugin.1.ronn b/lib/bundler/man/bundle-plugin.1.ronn new file mode 100644 index 0000000000..4f234eeba7 --- /dev/null +++ b/lib/bundler/man/bundle-plugin.1.ronn @@ -0,0 +1,59 @@ +bundle-plugin(1) -- Manage Bundler plugins +========================================== + +## SYNOPSIS + +`bundle plugin` install PLUGINS [--source=] [--version=] + [--git|--local_git=] [--branch=|--ref=]
+`bundle plugin` uninstall PLUGINS
+`bundle plugin` list
+`bundle plugin` help [COMMAND] + +## DESCRIPTION + +You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler. + +## SUB-COMMANDS + +### install + +Install the given plugin(s). + +* `bundle plugin install bundler-graph`: + Install bundler-graph gem from RubyGems.org. The global source, specified in source in Gemfile is ignored. + +* `bundle plugin install bundler-graph --source https://example.com`: + Install bundler-graph gem from example.com. The global source, specified in source in Gemfile is not considered. + +* `bundle plugin install bundler-graph --version 0.2.1`: + You can specify the version of the gem via `--version`. + +* `bundle plugin install bundler-graph --git https://github.com/rubygems/bundler-graph`: + Install bundler-graph gem from Git repository. `--git` can be replaced with `--local-git`. You cannot use both `--git` and `--local-git`. You can use standard Git URLs like: + + * `ssh://[user@]host.xz[:port]/path/to/repo.git` + * `http[s]://host.xz[:port]/path/to/repo.git` + * `/path/to/repo` + * `file:///path/to/repo` + + When you specify `--git`/`--local-git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use. When you specify both, only the latter is used. + +### uninstall + +Uninstall the plugin(s) specified in PLUGINS. + +### list + +List the installed plugins and available commands. + +No options. + +### help + +Describe subcommands or one specific subcommand. + +No options. + +## SEE ALSO + +* [How to write a Bundler plugin](https://bundler.io/guides/bundler_plugins.html) diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1 index 44e5a83a01..d635d24e2d 100644 --- a/lib/bundler/man/bundle-pristine.1 +++ b/lib/bundler/man/bundle-pristine.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PRISTINE" "1" "July 2022" "" "" +.TH "BUNDLE\-PRISTINE" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1 index 29ec246018..4952e8094e 100644 --- a/lib/bundler/man/bundle-remove.1 +++ b/lib/bundler/man/bundle-remove.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-REMOVE" "1" "July 2022" "" "" +.TH "BUNDLE\-REMOVE" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-remove\fR \- Removes gems from the Gemfile diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1 index 227b1c8a1e..72ef3283cc 100644 --- a/lib/bundler/man/bundle-show.1 +++ b/lib/bundler/man/bundle-show.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-SHOW" "1" "July 2022" "" "" +.TH "BUNDLE\-SHOW" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1 index 7d0988bfa5..06ceef85db 100644 --- a/lib/bundler/man/bundle-update.1 +++ b/lib/bundler/man/bundle-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-UPDATE" "1" "July 2022" "" "" +.TH "BUNDLE\-UPDATE" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-update\fR \- Update your gems to the latest available versions diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1 index f6f51cde0e..cf63dd8f9e 100644 --- a/lib/bundler/man/bundle-viz.1 +++ b/lib/bundler/man/bundle-viz.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-VIZ" "1" "July 2022" "" "" +.TH "BUNDLE\-VIZ" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1 index f683e78cc6..22e102e053 100644 --- a/lib/bundler/man/bundle.1 +++ b/lib/bundler/man/bundle.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE" "1" "July 2022" "" "" +.TH "BUNDLE" "1" "August 2022" "" "" . .SH "NAME" \fBbundle\fR \- Ruby Dependency Management @@ -120,6 +120,10 @@ Display warnings about common problems \fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR Removes gems from the Gemfile . +.TP +\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR +Manage Bundler plugins +. .SH "PLUGINS" When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-\fR and execute it, passing down any extra arguments to it\. . diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn index 8f0159eee5..94106b183c 100644 --- a/lib/bundler/man/bundle.1.ronn +++ b/lib/bundler/man/bundle.1.ronn @@ -97,6 +97,9 @@ We divide `bundle` subcommands into primary commands and utilities: * [`bundle remove(1)`](bundle-remove.1.html): Removes gems from the Gemfile +* [`bundle plugin(1)`](bundle-plugin.1.html): + Manage Bundler plugins + ## PLUGINS When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES, diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5 index 63a16ca3ff..3d3994153b 100644 --- a/lib/bundler/man/gemfile.5 +++ b/lib/bundler/man/gemfile.5 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GEMFILE" "5" "July 2022" "" "" +.TH "GEMFILE" "5" "August 2022" "" "" . .SH "NAME" \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs diff --git a/lib/bundler/man/index.txt b/lib/bundler/man/index.txt index ef2956b2f9..b895aa537d 100644 --- a/lib/bundler/man/index.txt +++ b/lib/bundler/man/index.txt @@ -18,6 +18,7 @@ bundle-lock(1) bundle-lock.1 bundle-open(1) bundle-open.1 bundle-outdated(1) bundle-outdated.1 bundle-platform(1) bundle-platform.1 +bundle-plugin(1) bundle-plugin.1 bundle-pristine(1) bundle-pristine.1 bundle-remove(1) bundle-remove.1 bundle-show(1) bundle-show.1 diff --git a/lib/bundler/match_metadata.rb b/lib/bundler/match_metadata.rb new file mode 100644 index 0000000000..499036ca93 --- /dev/null +++ b/lib/bundler/match_metadata.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Bundler + module MatchMetadata + def matches_current_ruby? + @required_ruby_version.satisfied_by?(Gem.ruby_version) + end + + def matches_current_rubygems? + @required_rubygems_version.satisfied_by?(Gem.rubygems_version) + end + end +end diff --git a/lib/bundler/match_remote_metadata.rb b/lib/bundler/match_remote_metadata.rb new file mode 100644 index 0000000000..e1b2f4d0e2 --- /dev/null +++ b/lib/bundler/match_remote_metadata.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Bundler + module FetchMetadata + def matches_current_ruby? + @required_ruby_version ||= _remote_specification.required_ruby_version + + super + end + + def matches_current_rubygems? + # A fallback is included because the original version of the specification + # API didn't include that field, so some marshalled specs in the index have it + # set to +nil+. + @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default + + super + end + end + + module MatchRemoteMetadata + include MatchMetadata + + prepend FetchMetadata + end +end diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index 158c69e1a1..26458bd596 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -36,6 +36,8 @@ module Bundler # @param [Hash] options various parameters as described in description. # Refer to cli/plugin for available options def install(names, options) + raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"] + specs = Installer.new.install(names, options) save_plugins names, specs diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb index b5d7e3a6c9..601957746f 100644 --- a/lib/bundler/remote_specification.rb +++ b/lib/bundler/remote_specification.rb @@ -6,6 +6,7 @@ module Bundler # be seeded with what we're given from the source's abbreviated index - the # full specification will only be fetched when necessary. class RemoteSpecification + include MatchRemoteMetadata include MatchPlatform include Comparable @@ -28,13 +29,6 @@ module Bundler @platform = _remote_specification.platform end - # A fallback is included because the original version of the specification - # API didn't include that field, so some marshalled specs in the index have it - # set to +nil+. - def required_rubygems_version - @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default - end - def full_name if @original_platform == Gem::Platform::RUBY "#{@name}-#{@version}" diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index ca1bdbda7b..e382319112 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -7,6 +7,8 @@ module Bundler include GemHelpers + attr_writer :platforms + # Figures out the best possible configuration of gems that satisfies # the list of passed dependencies and any child dependencies without # causing any gem activation errors. @@ -19,41 +21,48 @@ module Bundler # collection of gemspecs is returned. Otherwise, nil is returned. def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil) base = SpecSet.new(base) unless base.is_a?(SpecSet) - metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") } - resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements) - result = resolver.start(requirements) - SpecSet.new(SpecSet.new(result).for(regular_requirements, false, platforms)) + resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms) + resolver.start(requirements) end - def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements) + def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms) @source_requirements = source_requirements - @metadata_requirements = metadata_requirements @base = base @resolver = Molinillo::Resolver.new(self, self) + @results_for = {} @search_for = {} - @base_dg = Molinillo::DependencyGraph.new - base.each do |ls| - dep = Dependency.new(ls.name, ls.version) - @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true) - end - additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) } - @platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } } + @additional_base_requirements = additional_base_requirements + @platforms = platforms @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY] @gem_version_promoter = gem_version_promoter @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major? end - def start(requirements) + def start(requirements, exclude_specs: []) + @metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") } + + exclude_specs.each do |spec| + remove_from_candidates(spec) + end + + @base_dg = Molinillo::DependencyGraph.new + @base.each do |ls| + dep = Dependency.new(ls.name, ls.version) + @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true) + end + @additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) } + @gem_version_promoter.prerelease_specified = @prerelease_specified = {} requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? } verify_gemfile_dependencies_are_found!(requirements) - dg = @resolver.resolve(requirements, @base_dg) - dg. + result = @resolver.resolve(requirements, @base_dg). map(&:payload). reject {|sg| sg.name.end_with?("\0") }. map(&:to_specs). flatten + + SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms)) rescue Molinillo::VersionConflict => e message = version_conflict_message(e) raise VersionConflict.new(e.conflicts.keys.uniq, message) @@ -177,7 +186,7 @@ module Bundler end def results_for(dependency) - index_for(dependency).search(dependency) + @results_for[dependency] ||= index_for(dependency).search(dependency) end def name_for(dependency) @@ -228,6 +237,19 @@ module Bundler private + def remove_from_candidates(spec) + @base.delete(spec) + @gem_version_promoter.reset + + @results_for.keys.each do |dep| + next unless dep.name == spec.name + + @results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version } + end + + @search_for = {} + end + # returns an integer \in (-\infty, 0] # a number closer to 0 means the dependency is less constraining # diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb index 4de5b91aa6..4e5b0082d3 100644 --- a/lib/bundler/resolver/spec_group.rb +++ b/lib/bundler/resolver/spec_group.rb @@ -97,14 +97,17 @@ module Bundler def metadata_dependencies(platform) spec = @specs[platform].first return [] if spec.is_a?(LazySpecification) - dependencies = [] - unless spec.required_ruby_version.none? - dependencies << DepProxy.get_proxy(Dependency.new("Ruby\0", spec.required_ruby_version), platform) - end - unless spec.required_rubygems_version.none? - dependencies << DepProxy.get_proxy(Dependency.new("RubyGems\0", spec.required_rubygems_version), platform) - end - dependencies + + [ + metadata_dependency("Ruby", spec.required_ruby_version, platform), + metadata_dependency("RubyGems", spec.required_rubygems_version, platform), + ].compact + end + + def metadata_dependency(name, requirement, platform) + return if requirement.nil? || requirement.none? + + DepProxy.get_proxy(Dependency.new("#{name}\0", requirement), platform) end end end diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index 938c58e64d..d976170f12 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -15,6 +15,7 @@ require "rubygems/specification" # `Gem::Source` from the redefined `Gem::Specification#source`. require "rubygems/source" +require_relative "match_metadata" require_relative "match_platform" # Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler @@ -28,6 +29,7 @@ end module Gem class Specification + include ::Bundler::MatchMetadata include ::Bundler::MatchPlatform attr_accessor :remote, :location, :relative_loaded_from @@ -235,6 +237,32 @@ module Gem MINGW = Gem::Platform.new("x86-mingw32") X64_MINGW = [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw-ucrt")].freeze + + if Gem::Platform.new("x86_64-linux-musl") === Gem::Platform.new("x86_64-linux") + remove_method :=== + + def ===(other) + return nil unless Gem::Platform === other + + # universal-mingw32 matches x64-mingw-ucrt + return true if (@cpu == "universal" || other.cpu == "universal") && + @os.start_with?("mingw") && other.os.start_with?("mingw") + + # cpu + ([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu || + (@cpu == "arm" && other.cpu.start_with?("arm"))) && + + # os + @os == other.os && + + # version + ( + (@os != "linux" && (@version.nil? || other.version.nil?)) || + (@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) || + @version == other.version + ) + end + end end Platform.singleton_class.module_eval do diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 14733269d6..4965ca9e60 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -7,8 +7,11 @@ module Bundler include Enumerable include TSort - def initialize(specs) + attr_reader :incomplete_specs + + def initialize(specs, incomplete_specs = []) @specs = specs + @incomplete_specs = incomplete_specs end def for(dependencies, check = false, platforms = [nil]) @@ -19,7 +22,10 @@ module Bundler loop do break unless dep = deps.shift - key = [dep[0].name, dep[1]] + name = dep[0].name + platform = dep[1] + + key = [name, platform] next if handled.key?(key) handled[key] = true @@ -33,7 +39,7 @@ module Bundler deps << [d, dep[1]] end elsif check - specs << IncompleteSpecification.new(*key) + @incomplete_specs += lookup[name] end end @@ -51,6 +57,12 @@ module Bundler @sorted = nil end + def delete(spec) + @specs.delete(spec) + @lookup = nil + @sorted = nil + end + def sort! self end @@ -66,7 +78,7 @@ module Bundler def materialize(deps) materialized = self.for(deps, true) - SpecSet.new(materialized) + SpecSet.new(materialized, incomplete_specs) end # Materialize for all the specs in the spec set, regardless of what platform they're for @@ -83,17 +95,15 @@ module Bundler end def incomplete_ruby_specs?(deps) - self.class.new(self.for(deps, true, [Gem::Platform::RUBY])).incomplete_specs.any? + self.for(deps, true, [Gem::Platform::RUBY]) + + @incomplete_specs.any? end def missing_specs @specs.select {|s| s.is_a?(LazySpecification) } end - def incomplete_specs - @specs.select {|s| s.is_a?(IncompleteSpecification) } - end - def merge(set) arr = sorted.dup set.each do |set_spec| diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index f15165f86d..a37c989aa8 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.3.20".freeze + VERSION = "2.3.21".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 616428475f..afe9a73b9c 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require "rbconfig" module Gem - VERSION = "3.3.20".freeze + VERSION = "3.3.21".freeze end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index ed3571dbff..8c5e7993ca 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -25,7 +25,7 @@ class Gem::Platform platforms.any? do |local_platform| platform.nil? || local_platform == platform || - (local_platform != Gem::Platform::RUBY && local_platform =~ platform) + (local_platform != Gem::Platform::RUBY && platform =~ local_platform) end end private_class_method :match_platforms? @@ -70,7 +70,7 @@ class Gem::Platform when String then arch = arch.split "-" - if arch.length > 2 && arch.last !~ (/\d/) # reassemble x86-linux-gnu + if arch.length > 2 && arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc} extra = arch.pop arch.last << "-#{extra}" end @@ -102,7 +102,7 @@ class Gem::Platform when /^dalvik(\d+)?$/ then [ "dalvik", $1 ] when /^dotnet$/ then [ "dotnet", nil ] when /^dotnet([\d.]*)/ then [ "dotnet", $1 ] - when /linux-?((?!gnu)\w+)?/ then [ "linux", $1 ] + when /linux-?(\w+)?/ then [ "linux", $1 ] when /mingw32/ then [ "mingw32", nil ] when /mingw-?(\w+)?/ then [ "mingw", $1 ] when /(mswin\d+)(\_(\d+))?/ then @@ -151,10 +151,17 @@ class Gem::Platform ## # Does +other+ match this platform? Two platforms match if they have the # same CPU, or either has a CPU of 'universal', they have the same OS, and - # they have the same version, or either has no version. + # they have the same version, or either one has no version # # Additionally, the platform will match if the local CPU is 'arm' and the # other CPU starts with "arm" (for generic ARM family support). + # + # Of note, this method is not commutative. Indeed the OS 'linux' has a + # special case: the version is the libc name, yet while "no version" stands + # as a wildcard for a binary gem platform (as for other OSes), for the + # runtime platform "no version" stands for 'gnu'. To be able to disinguish + # these, the method receiver is the gem platform, while the argument is + # the runtime platform. def ===(other) return nil unless Gem::Platform === other @@ -171,7 +178,11 @@ class Gem::Platform @os == other.os && # version - (@version.nil? || other.version.nil? || @version == other.version) + ( + (@os != "linux" && (@version.nil? || other.version.nil?)) || + (@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) || + @version == other.version + ) end ## diff --git a/spec/bundler/bundler/bundler_spec.rb b/spec/bundler/bundler/bundler_spec.rb index aeadcf9720..9e79bc165f 100644 --- a/spec/bundler/bundler/bundler_spec.rb +++ b/spec/bundler/bundler/bundler_spec.rb @@ -167,9 +167,9 @@ RSpec.describe Bundler do allow(::Bundler::FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError) allow(File).to receive(:world_writable?).and_return(true) message = <= 0.17.3", "< 3.0" + end + + build_gem "oauth2", "1.4.10" do |s| + s.add_dependency "faraday", ">= 0.17.3", "< 3.0" + s.add_dependency "multi_json", "~> 1.3" + end + + build_gem "faraday", "2.5.2" + + build_gem "multi_json", "1.15.0" + + build_gem "quickbooks-ruby", "1.0.19" do |s| + s.add_dependency "oauth2", "~> 1.4" + end + + build_gem "quickbooks-ruby", "0.1.9" do |s| + s.add_dependency "oauth2" + end + end + + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + + gem "oauth2" + gem "quickbooks-ruby" + G + + lockfile <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + faraday (2.5.2) + multi_json (1.15.0) + oauth2 (1.4.10) + faraday (>= 0.17.3, < 3.0) + multi_json (~> 1.3) + quickbooks-ruby (1.0.19) + oauth2 (~> 1.4) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + oauth2 + quickbooks-ruby + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "update --conservative --verbose" + + expect(out).not_to include("Installing quickbooks-ruby 0.1.9") + expect(out).to include("Installing quickbooks-ruby 1.0.19").and include("Installing oauth2 1.4.10") + end + it "does not downgrade indirect dependencies unnecessarily" do build_repo4 do build_gem "a" do |s| diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index fe1c3b71fe..bb5526203f 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -445,6 +445,47 @@ RSpec.describe "bundle install with specific platforms" do L end + it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do + build_repo4 do + build_gem "nokogiri", "1.13.8" + build_gem "nokogiri", "1.13.8" do |s| + s.platform = Gem::Platform.local + end + end + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + + gem "tzinfo", "~> 1.2", platform: :#{not_local_tag} + G + + original_lockfile = <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.13.8) + nokogiri (1.13.8-#{Gem::Platform.local}) + + PLATFORMS + #{lockfile_platforms_for([specific_local_platform, "ruby"])} + + DEPENDENCIES + nokogiri + tzinfo (~> 1.2) + + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile original_lockfile + + bundle "lock --update" + + expect(lockfile).to eq(original_lockfile) + end + it "can fallback to a source gem when platform gems are incompatible with current ruby version" do setup_multiplatform_gem_with_source_gem diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb index 79317a7fad..a3c5bc32aa 100644 --- a/spec/bundler/install/gems/dependency_api_spec.rb +++ b/spec/bundler/install/gems/dependency_api_spec.rb @@ -443,6 +443,22 @@ RSpec.describe "gemcutter's dependency API" do expect(the_bundle).to include_gems "back_deps 1.0" end + it "does not fetch all marshaled specs" do + build_repo2 do + build_gem "foo", "1.0" + build_gem "foo", "2.0" + end + + install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :verbose => true + source "#{source_uri}" + + gem "foo" + G + + expect(out).to include("foo-2.0.gemspec.rz") + expect(out).not_to include("foo-1.0.gemspec.rz") + end + it "does not refetch if the only unmet dependency is bundler" do build_repo2 do build_gem "bundler_dep" do |s| diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index 9c0d6bfe56..9405f146b9 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -305,6 +305,77 @@ RSpec.describe "bundle install with install-time dependencies" do end end + context "in a transitive dependencies in a lockfile" do + before do + build_repo2 do + build_gem "rubocop", "1.28.2" do |s| + s.required_ruby_version = ">= #{current_ruby_minor}" + + s.add_dependency "rubocop-ast", ">= 1.17.0", "< 2.0" + end + + build_gem "rubocop", "1.35.0" do |s| + s.required_ruby_version = ">= #{next_ruby_minor}" + + s.add_dependency "rubocop-ast", ">= 1.20.1", "< 2.0" + end + + build_gem "rubocop-ast", "1.17.0" do |s| + s.required_ruby_version = ">= #{current_ruby_minor}" + end + + build_gem "rubocop-ast", "1.21.0" do |s| + s.required_ruby_version = ">= #{next_ruby_minor}" + end + end + + gemfile <<-G + source "http://localgemserver.test/" + gem 'rubocop' + G + + lockfile <<~L + GEM + remote: http://localgemserver.test/ + specs: + rubocop (1.35.0) + rubocop-ast (>= 1.20.1, < 2.0) + rubocop-ast (1.21.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + parallel_tests + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "automatically updates lockfile to use the older compatible versions" do + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + + expect(lockfile).to eq <<~L + GEM + remote: http://localgemserver.test/ + specs: + rubocop (1.28.2) + rubocop-ast (>= 1.17.0, < 2.0) + rubocop-ast (1.17.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + rubocop + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + it "gives a meaningful error on ruby version mismatches between dependencies" do build_repo4 do build_gem "requires-old-ruby" do |s| diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb index 009516260a..efee5fdd23 100644 --- a/spec/bundler/plugins/install_spec.rb +++ b/spec/bundler/plugins/install_spec.rb @@ -32,7 +32,8 @@ RSpec.describe "bundler plugin install" do it "shows help when --help flag is given" do bundle "plugin install --help" - expect(out).to include("bundle plugin install PLUGINS # Install the plugin from the source") + # The help message defined in ../../lib/bundler/man/bundle-plugin.1.ronn will be output. + expect(out).to include("You can install, uninstall, and list plugin(s)") end context "plugin is already installed" do @@ -84,6 +85,26 @@ RSpec.describe "bundler plugin install" do expect(out).to include("Using foo 1.1") end + it "installs when --branch specified" do + bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}" + + expect(out).to include("Installed plugin foo") + end + + it "installs when --ref specified" do + bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}" + + expect(out).to include("Installed plugin foo") + end + + it "raises error when both --branch and --ref options are specified" do + bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", :raise_on_error => false + + expect(out).not_to include("Installed plugin foo") + + expect(err).to include("You cannot specify `--branch` and `--ref` at the same time.") + end + it "works with different load paths" do build_repo2 do build_plugin "testing" do |s| diff --git a/spec/bundler/resolver/platform_spec.rb b/spec/bundler/resolver/platform_spec.rb index 8eaed4220a..418293365c 100644 --- a/spec/bundler/resolver/platform_spec.rb +++ b/spec/bundler/resolver/platform_spec.rb @@ -82,6 +82,79 @@ RSpec.describe "Resolving platform craziness" do should_resolve_as %w[foo-1.0.0-x64-mingw32] end + describe "on a linux platform", :rubygems => ">= 3.1.0.pre.1" do + # Ruby's platform is *-linux => platform's libc is glibc, so not musl + # Ruby's platform is *-linux-musl => platform's libc is musl, so not glibc + # Gem's platform is *-linux => gem is glibc + maybe musl compatible + # Gem's platform is *-linux-musl => gem is musl compatible but not glibc + + it "favors the platform version-specific gem on a version-specifying linux platform" do + @index = build_index do + gem "foo", "1.0.0" + gem "foo", "1.0.0", "x86_64-linux" + gem "foo", "1.0.0", "x86_64-linux-musl" + end + dep "foo" + platforms "x86_64-linux-musl" + + should_resolve_as %w[foo-1.0.0-x86_64-linux-musl] + end + + it "favors the version-less gem over the version-specific gem on a gnu linux platform" do + @index = build_index do + gem "foo", "1.0.0" + gem "foo", "1.0.0", "x86_64-linux" + gem "foo", "1.0.0", "x86_64-linux-musl" + end + dep "foo" + platforms "x86_64-linux" + + should_resolve_as %w[foo-1.0.0-x86_64-linux] + end + + it "ignores the platform version-specific gem on a gnu linux platform" do + @index = build_index do + gem "foo", "1.0.0", "x86_64-linux-musl" + end + dep "foo" + platforms "x86_64-linux" + + should_not_resolve + end + + it "falls back to the platform version-less gem on a linux platform with a version" do + @index = build_index do + gem "foo", "1.0.0" + gem "foo", "1.0.0", "x86_64-linux" + end + dep "foo" + platforms "x86_64-linux-musl" + + should_resolve_as %w[foo-1.0.0-x86_64-linux] + end + + it "falls back to the ruby platform gem on a gnu linux platform when only a version-specifying gem is available" do + @index = build_index do + gem "foo", "1.0.0" + gem "foo", "1.0.0", "x86_64-linux-musl" + end + dep "foo" + platforms "x86_64-linux" + + should_resolve_as %w[foo-1.0.0] + end + + it "falls back to the platform version-less gem on a version-specifying linux platform and no ruby platform gem is available" do + @index = build_index do + gem "foo", "1.0.0", "x86_64-linux" + end + dep "foo" + platforms "x86_64-linux-musl" + + should_resolve_as %w[foo-1.0.0-x86_64-linux] + end + end + it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do @index = build_index do gem "foo", "1.0.0" diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index dd22c86f90..e3cf5020ec 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -355,6 +355,20 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end + it "still installs if the application has `bundle package` no_install config set" do + bundle "config set --local no_install true" + + script <<-RUBY + gemfile do + source "#{file_uri_for(gem_repo1)}" + gem "rack" + end + RUBY + + expect(last_command).to be_success + expect(system_gem_path("gems/rack-1.0.0")).to exist + end + it "preserves previous BUNDLE_GEMFILE value" do ENV["BUNDLE_GEMFILE"] = "" script <<-RUBY diff --git a/spec/bundler/support/artifice/compact_index_api_missing.rb b/spec/bundler/support/artifice/compact_index_api_missing.rb index 6514fde01e..2fd8b6d2e9 100644 --- a/spec/bundler/support/artifice/compact_index_api_missing.rb +++ b/spec/bundler/support/artifice/compact_index_api_missing.rb @@ -6,12 +6,7 @@ Artifice.deactivate class CompactIndexApiMissing < CompactIndexAPI get "/fetch/actual/gem/:id" do - warn params[:id] - if params[:id] == "rack-1.0.gemspec.rz" - halt 404 - else - File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}") - end + halt 404 end end diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb index 55d798a90a..c496679ee6 100644 --- a/spec/bundler/support/indexes.rb +++ b/spec/bundler/support/indexes.rb @@ -33,6 +33,10 @@ module Spec Bundler::Resolver.resolve(deps, source_requirements, *args) end + def should_not_resolve + expect { resolve }.to raise_error(Bundler::GemNotFound) + end + def should_resolve_as(specs) got = resolve got = got.map(&:full_name).sort diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock index da09e717f0..0f1fa7c430 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.29" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a" +checksum = "24b22a374fc2e92eb6f49d7efe4eb7663655c6e9455d9259ed3342cc1599da85" dependencies = [ "bindgen", "linkify", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "rb-sys-build" -version = "0.9.29" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5" +checksum = "3cd23b6dd929b7d50ccb35a6d3aa77dec364328ab9cb304dd32c629332491671" dependencies = [ "regex", "shell-words", diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml index 2a215a55dd..c9ba5c27bd 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = { version = "0.9.29", features = ["gem"] } +rb-sys = { version = "0.9.30", features = ["gem"] } diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock index e351819848..5e602fcf92 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.29" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a" +checksum = "24b22a374fc2e92eb6f49d7efe4eb7663655c6e9455d9259ed3342cc1599da85" dependencies = [ "bindgen", "linkify", @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "rb-sys-build" -version = "0.9.29" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5" +checksum = "3cd23b6dd929b7d50ccb35a6d3aa77dec364328ab9cb304dd32c629332491671" dependencies = [ "regex", "shell-words", diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml index 1867db8e66..8e3f623728 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = { version = "0.9.29", features = ["gem"] } +rb-sys = { version = "0.9.30", features = ["gem"] } diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index 0fb5bf59a5..e0e635e533 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -119,8 +119,8 @@ class TestGemPlatform < Gem::TestCase "i586-linux" => ["x86", "linux", nil], "i486-linux" => ["x86", "linux", nil], "i386-linux" => ["x86", "linux", nil], - "i586-linux-gnu" => ["x86", "linux", nil], - "i386-linux-gnu" => ["x86", "linux", nil], + "i586-linux-gnu" => ["x86", "linux", "gnu"], + "i386-linux-gnu" => ["x86", "linux", "gnu"], "i386-mingw32" => ["x86", "mingw32", nil], "x64-mingw-ucrt" => ["x64", "mingw", "ucrt"], "i386-mswin32" => ["x86", "mswin32", nil], @@ -135,7 +135,9 @@ class TestGemPlatform < Gem::TestCase "i386-solaris2.8" => ["x86", "solaris", "2.8"], "mswin32" => ["x86", "mswin32", nil], "x86_64-linux" => ["x86_64", "linux", nil], + "x86_64-linux-gnu" => ["x86_64", "linux", "gnu"], "x86_64-linux-musl" => ["x86_64", "linux", "musl"], + "x86_64-linux-uclibc" => ["x86_64", "linux", "uclibc"], "x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"], "x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"], "x86_64-openbsd" => ["x86_64", "openbsd", nil], @@ -144,6 +146,7 @@ class TestGemPlatform < Gem::TestCase test_cases.each do |arch, expected| platform = Gem::Platform.new arch assert_equal expected, platform.to_a, arch.inspect + assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect end end @@ -262,6 +265,42 @@ class TestGemPlatform < Gem::TestCase assert((with_x86_arch === with_nil_arch), "x86 =~ nil") end + def test_nil_version_is_treated_as_any_version + x86_darwin_8 = Gem::Platform.new "i686-darwin8.0" + x86_darwin_nil = Gem::Platform.new "i686-darwin" + + assert((x86_darwin_8 === x86_darwin_nil), "8.0 =~ nil") + assert((x86_darwin_nil === x86_darwin_8), "nil =~ 8.0") + end + + def test_nil_version_is_stricter_for_linux_os + x86_linux = Gem::Platform.new "i686-linux" + x86_linux_gnu = Gem::Platform.new "i686-linux-gnu" + x86_linux_musl = Gem::Platform.new "i686-linux-musl" + x86_linux_uclibc = Gem::Platform.new "i686-linux-uclibc" + + # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime + assert(x86_linux === x86_linux_gnu, "linux =~ linux-gnu") + assert(x86_linux_gnu === x86_linux, "linux-gnu =~ linux") + + # musl and explicit gnu should differ + refute(x86_linux_gnu === x86_linux_musl, "linux-gnu =~ linux-musl") + refute(x86_linux_musl === x86_linux_gnu, "linux-musl =~ linux-gnu") + + # explicit libc differ + refute(x86_linux_uclibc === x86_linux_musl, "linux-uclibc =~ linux-musl") + refute(x86_linux_musl === x86_linux_uclibc, "linux-musl =~ linux-uclibc") + + # musl host runtime accepts libc-generic or statically linked gems... + assert(x86_linux === x86_linux_musl, "linux =~ linux-musl") + # ...but implicit gnu runtime generally does not accept musl-specific gems + refute(x86_linux_musl === x86_linux, "linux-musl =~ linux") + + # other libc are not glibc compatible + refute(x86_linux === x86_linux_uclibc, "linux =~ linux-uclibc") + refute(x86_linux_uclibc === x86_linux, "linux-uclibc =~ linux") + end + def test_equals3_cpu_arm arm = Gem::Platform.new "arm-linux" armv5 = Gem::Platform.new "armv5-linux" diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index 2271244729..c816d5484b 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -322,16 +322,15 @@ class TestGemResolver < Gem::TestCase def test_picks_best_platform is = Gem::Resolver::IndexSpecification unknown = Gem::Platform.new "unknown" - a2_p1 = a3_p2 = nil spec_fetcher do |fetcher| fetcher.spec "a", 2 - a2_p1 = fetcher.spec "a", 2 do |s| + fetcher.spec "a", 2 do |s| s.platform = Gem::Platform.local end - a3_p2 = fetcher.spec "a", 3 do |s| + fetcher.spec "a", 3 do |s| s.platform = unknown end end @@ -357,6 +356,41 @@ class TestGemResolver < Gem::TestCase assert_resolves_to [a2_p1.spec], res end + def test_does_not_pick_musl_variants_on_non_musl_linux + util_set_arch "aarch64-linux" do + is = Gem::Resolver::IndexSpecification + + linux_musl = Gem::Platform.new("aarch64-linux-musl") + + spec_fetcher do |fetcher| + fetcher.spec "libv8-node", "15.14.0.1" do |s| + s.platform = Gem::Platform.local + end + + fetcher.spec "libv8-node", "15.14.0.1" do |s| + s.platform = linux_musl + end + end + + v15 = v("15.14.0.1") + source = Gem::Source.new @gem_repo + + s = set + + v15_linux = is.new s, "libv8-node", v15, source, Gem::Platform.local.to_s + v15_linux_musl = is.new s, "libv8-node", v15, source, linux_musl.to_s + + s.add v15_linux + s.add v15_linux_musl + + ad = make_dep "libv8-node", "= 15.14.0.1" + + res = Gem::Resolver.new([ad], s) + + assert_resolves_to [v15_linux.spec], res + end + end + def test_only_returns_spec_once a1 = util_spec "a", "1", "c" => "= 1" b1 = util_spec "b", "1", "c" => "= 1" diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock index 75d8faf683..994c70d333 100644 --- a/tool/bundler/dev_gems.rb.lock +++ b/tool/bundler/dev_gems.rb.lock @@ -53,4 +53,4 @@ DEPENDENCIES webrick (~> 1.6) BUNDLED WITH - 2.3.20 + 2.3.21 diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock index 02fdb0b24d..c321d05fc3 100644 --- a/tool/bundler/rubocop_gems.rb.lock +++ b/tool/bundler/rubocop_gems.rb.lock @@ -62,4 +62,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.20 + 2.3.21 diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock index 570bd99b4c..9f454cf76e 100644 --- a/tool/bundler/standard_gems.rb.lock +++ b/tool/bundler/standard_gems.rb.lock @@ -68,4 +68,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.20 + 2.3.21 diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock index 25602cabb2..8203af4c1a 100644 --- a/tool/bundler/test_gems.rb.lock +++ b/tool/bundler/test_gems.rb.lock @@ -43,4 +43,4 @@ DEPENDENCIES webrick (= 1.7.0) BUNDLED WITH - 2.3.20 + 2.3.21