mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parent
4790d0accd
commit
f69244cee8
Notes:
git
2022-08-23 10:46:24 +09:00
16 changed files with 225 additions and 90 deletions
|
@ -53,12 +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 :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__)
|
||||
|
|
|
@ -145,8 +145,6 @@ module Bundler
|
|||
@dependency_changes = converge_dependencies
|
||||
@local_changes = converge_locals
|
||||
|
||||
@reresolve = nil
|
||||
|
||||
@requires = compute_requires
|
||||
end
|
||||
|
||||
|
@ -218,6 +216,7 @@ module Bundler
|
|||
true
|
||||
rescue BundlerError => 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
|
||||
|
@ -879,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)
|
||||
|
@ -894,6 +896,7 @@ module Bundler
|
|||
|
||||
remove_platform(Gem::Platform::RUBY)
|
||||
add_current_platform
|
||||
resolver.platforms = @platforms
|
||||
end
|
||||
|
||||
def source_map
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
module Bundler
|
||||
# used for Creating Specifications from the Gemcutter Endpoint
|
||||
class EndpointSpecification < Gem::Specification
|
||||
include MatchRemoteMetadata
|
||||
|
||||
attr_reader :name, :version, :platform, :checksum
|
||||
attr_accessor :source, :remote, :dependencies
|
||||
|
||||
|
@ -20,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -95,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
|
||||
|
|
13
lib/bundler/match_metadata.rb
Normal file
13
lib/bundler/match_metadata.rb
Normal file
|
@ -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
|
26
lib/bundler/match_remote_metadata.rb
Normal file
26
lib/bundler/match_remote_metadata.rb
Normal file
|
@ -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
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -105,7 +105,7 @@ module Bundler
|
|||
end
|
||||
|
||||
def metadata_dependency(name, requirement, platform)
|
||||
return if requirement.none?
|
||||
return if requirement.nil? || requirement.none?
|
||||
|
||||
DepProxy.get_proxy(Dependency.new("#{name}\0", requirement), platform)
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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|
|
||||
|
|
Loading…
Reference in a new issue