diff --git a/lib/bundler/dep_proxy.rb b/lib/bundler/dep_proxy.rb index 47de2968108..f007546777a 100644 --- a/lib/bundler/dep_proxy.rb +++ b/lib/bundler/dep_proxy.rb @@ -29,13 +29,16 @@ def requirement end def to_s - "#{name} (#{requirement}) #{__platform}" + s = name.dup + s << " (#{requirement})" unless requirement == Gem::Requirement.default + s << " #{__platform}" unless __platform == Gem::Platform::RUBY + s end private - def method_missing(*args) - @dep.send(*args) + def method_missing(*args, &blk) + @dep.send(*args, &blk) end end end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 14a33f5e463..ff05e78c9d2 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -1,51 +1,40 @@ -require "set" - -# This is the latest iteration of the gem dependency resolving algorithm. As of now, -# it can resolve (as a success or failure) any set of gem dependencies we throw at it -# in a reasonable amount of time. The most iterations I've seen it take is about 150. -# The actual implementation of the algorithm is not as good as it could be yet, but that -# can come later. - module Bundler class Resolver require "bundler/vendored_molinillo" class Molinillo::VersionConflict - def clean_req(req) - if req.to_s.include?(">= 0") - req.to_s.gsub(/ \(.*?\)$/, "") - else - req.to_s.gsub(/\, (runtime|development)\)$/, ")") - end - end - def message - conflicts.values.flatten.reduce("") do |o, conflict| - o << %(Bundler could not find compatible versions for gem "#{conflict.requirement.name}":\n) + conflicts.sort.reduce("") do |o, (name, conflict)| + o << %(Bundler could not find compatible versions for gem "#{name}":\n) if conflict.locked_requirement o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n) - o << %( #{clean_req conflict.locked_requirement}\n) + o << %( #{DepProxy.new(conflict.locked_requirement, Gem::Platform::RUBY)}\n) o << %(\n) end o << %( In Gemfile:\n) - o << conflict.requirement_trees.map do |tree| + o << conflict.requirement_trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree| t = "" depth = 2 tree.each do |req| - t << " " * depth << %(#{clean_req req}) - t << %( depends on) unless tree[-1] == req + t << " " * depth << req.to_s + unless tree.last == req + if spec = conflict.activated_by_name[req.name] + t << %( was resolved to #{spec.version}, which) + end + t << %( depends on) + end t << %(\n) depth += 1 end t end.join("\n") - if conflict.requirement.name == "bundler" + if name == "bundler" o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION})) other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION) end - if conflict.requirement.name == "bundler" && other_bundler_required + if name == "bundler" && other_bundler_required o << "\n" o << "This Gemfile requires a different version of Bundler.\n" o << "Perhaps you need to update Bundler by running `gem install bundler`?\n" @@ -55,11 +44,12 @@ def message o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n) o << %(the gems in your Gemfile, which may resolve the conflict.\n) elsif !conflict.existing + o << "\n" if conflict.requirement_trees.first.size > 1 - o << "Could not find gem '#{clean_req(conflict.requirement)}', which is required by " - o << "gem '#{clean_req(conflict.requirement_trees.first[-2])}', in any of the sources." + o << "Could not find gem '#{conflict.requirement}', which is required by " + o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources." else - o << "Could not find gem '#{clean_req(conflict.requirement)} in any of the sources\n" + o << "Could not find gem '#{conflict.requirement}' in any of the sources\n" end end o @@ -189,7 +179,7 @@ def initialize(index, source_requirements, base) @resolver = Molinillo::Resolver.new(self, self) @search_for = {} @base_dg = Molinillo::DependencyGraph.new - @base.each {|ls| @base_dg.add_root_vertex ls.name, Dependency.new(ls.name, ls.version) } + @base.each {|ls| @base_dg.add_vertex(ls.name, Dependency.new(ls.name, ls.version), true) } end def start(requirements) diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb index 7cde9fa5ebb..655b0ebb970 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb @@ -34,40 +34,34 @@ def self.tsort(vertices) # A directed edge of a {DependencyGraph} # @attr [Vertex] origin The origin of the directed edge # @attr [Vertex] destination The destination of the directed edge - # @attr [Array] requirements The requirements the directed edge represents - Edge = Struct.new(:origin, :destination, :requirements) + # @attr [Object] requirement The requirement the directed edge represents + Edge = Struct.new(:origin, :destination, :requirement) - # @return [{String => Vertex}] vertices that have no {Vertex#predecessors}, - # keyed by by {Vertex#name} - attr_reader :root_vertices # @return [{String => Vertex}] the vertices of the dependency graph, keyed # by {Vertex#name} attr_reader :vertices - # @return [Set] the edges of the dependency graph - attr_reader :edges def initialize @vertices = {} - @edges = Set.new - @root_vertices = {} end # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices} - # have the correct {Vertex#graph} set + # are properly copied. def initialize_copy(other) super - @vertices = other.vertices.reduce({}) do |vertices, (name, vertex)| - vertices.tap do |hash| - hash[name] = vertex.dup.tap { |v| v.graph = self } + @vertices = {} + traverse = lambda do |new_v, old_v| + return if new_v.outgoing_edges.size == old_v.outgoing_edges.size + old_v.outgoing_edges.each do |edge| + destination = add_vertex(edge.destination.name, edge.destination.payload) + add_edge_no_circular(new_v, destination, edge.requirement) + traverse.call(destination, edge.destination) end end - @root_vertices = Hash[@vertices.select { |n, _v| other.root_vertices[n] }] - @edges = other.edges.map do |edge| - Edge.new( - vertex_named(edge.origin.name), - vertex_named(edge.destination.name), - edge.requirements.dup - ) + other.vertices.each do |name, vertex| + new_vertex = add_vertex(name, vertex.payload, vertex.root?) + new_vertex.explicit_requirements.replace(vertex.explicit_requirements) + traverse.call(new_vertex, vertex) end end @@ -80,7 +74,12 @@ def inspect # by a recursive traversal of each {#root_vertices} and its # {Vertex#successors} def ==(other) - root_vertices == other.root_vertices + return false unless other + vertices.each do |name, vertex| + other_vertex = other.vertex_named(name) + return false unless other_vertex + return false unless other_vertex.successors.map(&:name).to_set == vertex.successors.map(&:name).to_set + end end # @param [String] name @@ -89,15 +88,13 @@ def ==(other) # @param [Object] requirement the requirement that is requiring the child # @return [void] def add_child_vertex(name, payload, parent_names, requirement) - is_root = parent_names.include?(nil) - parent_nodes = parent_names.compact.map { |n| vertex_named(n) } - vertex = vertex_named(name) || if is_root - add_root_vertex(name, payload) - else - add_vertex(name, payload) - end - vertex.payload ||= payload - parent_nodes.each do |parent_node| + vertex = add_vertex(name, payload) + parent_names.each do |parent_name| + unless parent_name + vertex.root = true + next + end + parent_node = vertex_named(parent_name) add_edge(parent_node, vertex, requirement) end vertex @@ -106,16 +103,11 @@ def add_child_vertex(name, payload, parent_names, requirement) # @param [String] name # @param [Object] payload # @return [Vertex] the vertex that was added to `self` - def add_vertex(name, payload) - vertex = vertices[name] ||= Vertex.new(self, name, payload) - vertex.tap { |v| v.payload = payload } - end - - # @param [String] name - # @param [Object] payload - # @return [Vertex] the vertex that was added to `self` - def add_root_vertex(name, payload) - add_vertex(name, payload).tap { |v| root_vertices[name] = v } + def add_vertex(name, payload, root = false) + vertex = vertices[name] ||= Vertex.new(name, payload) + vertex.payload ||= payload + vertex.root ||= root + vertex end # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively @@ -123,12 +115,12 @@ def add_root_vertex(name, payload) # @param [String] name # @return [void] def detach_vertex_named(name) - vertex = vertex_named(name) - return unless vertex - successors = vertex.successors - vertices.delete(name) - edges.reject! { |e| e.origin == vertex || e.destination == vertex } - successors.each { |v| detach_vertex_named(v.name) unless root_vertices[v.name] || v.predecessors.any? } + return unless vertex = vertices.delete(name) + vertex.outgoing_edges.each do |e| + v = e.destination + v.incoming_edges.delete(e) + detach_vertex_named(v.name) unless v.root? || v.predecessors.any? + end end # @param [String] name @@ -140,7 +132,8 @@ def vertex_named(name) # @param [String] name # @return [Vertex,nil] the root vertex with the given name def root_vertex_named(name) - root_vertices[name] + vertex = vertex_named(name) + vertex if vertex && vertex.root? end # Adds a new {Edge} to the dependency graph @@ -149,18 +142,24 @@ def root_vertex_named(name) # @param [Object] requirement the requirement that this edge represents # @return [Edge] the added edge def add_edge(origin, destination, requirement) - if origin == destination || destination.path_to?(origin) + if destination.path_to?(origin) raise CircularDependencyError.new([origin, destination]) end - Edge.new(origin, destination, [requirement]).tap { |e| edges << e } + add_edge_no_circular(origin, destination, requirement) + end + + private + + def add_edge_no_circular(origin, destination, requirement) + edge = Edge.new(origin, destination, requirement) + origin.outgoing_edges << edge + destination.incoming_edges << edge + edge end # A vertex in a {DependencyGraph} that encapsulates a {#name} and a # {#payload} class Vertex - # @return [DependencyGraph] the graph this vertex is a node of - attr_accessor :graph - # @return [String] the name of the vertex attr_accessor :name @@ -171,50 +170,62 @@ class Vertex # this vertex attr_reader :explicit_requirements - # @param [DependencyGraph] graph see {#graph} + # @return [Boolean] whether the vertex is considered a root vertex + attr_accessor :root + alias_method :root?, :root + # @param [String] name see {#name} # @param [Object] payload see {#payload} - def initialize(graph, name, payload) - @graph = graph + def initialize(name, payload) @name = name @payload = payload @explicit_requirements = [] + @outgoing_edges = [] + @incoming_edges = [] end # @return [Array] all of the requirements that required # this vertex def requirements - incoming_edges.map(&:requirements).flatten + explicit_requirements + incoming_edges.map(&:requirement) + explicit_requirements end # @return [Array] the edges of {#graph} that have `self` as their # {Edge#origin} - def outgoing_edges - graph.edges.select { |e| e.origin.shallow_eql?(self) } - end + attr_accessor :outgoing_edges # @return [Array] the edges of {#graph} that have `self` as their # {Edge#destination} - def incoming_edges - graph.edges.select { |e| e.destination.shallow_eql?(self) } - end + attr_accessor :incoming_edges - # @return [Set] the vertices of {#graph} that have an edge with + # @return [Array] the vertices of {#graph} that have an edge with # `self` as their {Edge#destination} def predecessors - incoming_edges.map(&:origin).to_set + incoming_edges.map(&:origin) + end + + # @return [Array] the vertices of {#graph} where `self` is a + # {#descendent?} + def recursive_predecessors + vertices = predecessors + vertices += vertices.map(&:recursive_predecessors).flatten(1) + vertices.uniq! + vertices end - # @return [Set] the vertices of {#graph} that have an edge with + # @return [Array] the vertices of {#graph} that have an edge with # `self` as their {Edge#origin} def successors - outgoing_edges.map(&:destination).to_set + outgoing_edges.map(&:destination) end - # @return [Set] the vertices of {#graph} where `self` is an + # @return [Array] the vertices of {#graph} where `self` is an # {#ancestor?} def recursive_successors - successors + successors.map(&:recursive_successors).reduce(Set.new, &:+) + vertices = successors + vertices += vertices.map(&:recursive_successors).flatten(1) + vertices.uniq! + vertices end # @return [String] a string suitable for debugging @@ -226,7 +237,7 @@ def inspect # by a recursive traversal of each {Vertex#successors} def ==(other) shallow_eql?(other) && - successors == other.successors + successors.to_set == other.successors.to_set end # @return [Boolean] whether the two vertices are equal, determined @@ -248,7 +259,7 @@ def hash # dependency graph? # @return true iff there is a path following edges within this {#graph} def path_to?(other) - successors.include?(other) || successors.any? { |v| v.path_to?(other) } + equal?(other) || successors.any? { |v| v.path_to?(other) } end alias_method :descendent?, :path_to? @@ -257,7 +268,7 @@ def path_to?(other) # dependency graph? # @return true iff there is a path following edges within this {#graph} def ancestor?(other) - predecessors.include?(other) || predecessors.any? { |v| v.ancestor?(other) } + other.path_to?(self) end alias_method :is_reachable_from?, :ancestor? diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb index 0e8e4372405..a58ee533148 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb @@ -1,3 +1,3 @@ module Bundler::Molinillo - VERSION = '0.3.0' + VERSION = '0.4.0' end diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb index fc7fe86c7d3..51cfa101b1e 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb @@ -12,13 +12,15 @@ class Resolution # @attr [Object] locked_requirement the relevant locking requirement. # @attr [Array>] requirement_trees the different requirement # trees that led to every requirement for the conflicting name. + # @attr [{String=>Object}] activated_by_name the already-activated specs. Conflict = Struct.new( :requirement, :requirements, :existing, :possibility, :locked_requirement, - :requirement_trees + :requirement_trees, + :activated_by_name ) # @return [SpecificationProvider] the provider that knows about @@ -164,7 +166,7 @@ def state # @return [DependencyState] the initial state for the resolution def initial_state graph = DependencyGraph.new.tap do |dg| - original_requested.each { |r| dg.add_root_vertex(name_for(r), nil).tap { |v| v.explicit_requirements << r } } + original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } } end requirements = sort_dependencies(original_requested, graph, {}) @@ -216,7 +218,7 @@ def parent_of(requirement) return nil unless requirement seen = false state = states.reverse_each.find do |s| - seen ||= s.requirement == requirement + seen ||= s.requirement == requirement || s.requirements.include?(requirement) seen && s.requirement != requirement && !s.requirements.include?(requirement) end state && state.requirement @@ -250,21 +252,23 @@ def create_conflict name_for_explicit_dependency_source => vertex.explicit_requirements, name_for_locking_dependency_source => Array(locked_requirement_named(name)), } - vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(*edge.requirements) } + vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) } conflicts[name] = Conflict.new( requirement, Hash[requirements.select { |_, r| !r.empty? }], vertex.payload, possibility, locked_requirement_named(name), - requirement_trees + requirement_trees, + Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)] ) end # @return [Array>] The different requirement # trees that led to every requirement for the current spec. def requirement_trees - activated.vertex_named(name).requirements.map { |r| requirement_tree_for(r) } + vertex = activated.vertex_named(name) + vertex.requirements.map { |r| requirement_tree_for(r) } end # @return [Array] the list of requirements that led to @@ -322,7 +326,7 @@ def attempt_to_activate_existing_spec(existing_node) existing_spec = existing_node.payload if requirement_satisfied_by?(requirement, activated, existing_spec) new_requirements = requirements.dup - push_state_for_requirements(new_requirements) + push_state_for_requirements(new_requirements, false) else return if attempt_to_swap_possibility create_conflict @@ -389,17 +393,17 @@ def activate_spec def require_nested_dependencies_for(activated_spec) nested_dependencies = dependencies_for(activated_spec) debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" } - nested_dependencies.each { |d| activated.add_child_vertex name_for(d), nil, [name_for(activated_spec)], d } + nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) } - push_state_for_requirements(requirements + nested_dependencies) + push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0) end # Pushes a new {DependencyState} that encapsulates both existing and new # requirements # @param [Array] new_requirements # @return [void] - def push_state_for_requirements(new_requirements, new_activated = activated.dup) - new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) + def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated.dup) + new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort new_requirement = new_requirements.shift new_name = new_requirement ? name_for(new_requirement) : '' possibilities = new_requirement ? search_for(new_requirement) : [] @@ -420,7 +424,7 @@ def push_state_for_requirements(new_requirements, new_activated = activated.dup) def handle_missing_or_push_dependency_state(state) if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement) state.activated.detach_vertex_named(state.name) - push_state_for_requirements(state.requirements, state.activated) + push_state_for_requirements(state.requirements.dup, false, state.activated) else states.push state end diff --git a/spec/commands/install_spec.rb b/spec/commands/install_spec.rb index 2e1a206f21d..f6648ac6b00 100644 --- a/spec/commands/install_spec.rb +++ b/spec/commands/install_spec.rb @@ -370,7 +370,7 @@ G bundle :install, :quiet => true - expect(out).to include("Could not find gem 'rack (>= 0) ruby'") + expect(out).to include("Could not find gem 'rack'") expect(out).to_not include("Your Gemfile has no gem server sources") end end diff --git a/spec/install/bundler_spec.rb b/spec/install/bundler_spec.rb index 930d7095fc9..4bbfb135c12 100644 --- a/spec/install/bundler_spec.rb +++ b/spec/install/bundler_spec.rb @@ -41,7 +41,7 @@ Resolving dependencies... Bundler could not find compatible versions for gem "bundler": In Gemfile: - bundler (= 0.9.2) ruby + bundler (= 0.9.2) Current Bundler version: bundler (#{Bundler::VERSION}) @@ -98,11 +98,11 @@ Resolving dependencies... Bundler could not find compatible versions for gem "activesupport": In Gemfile: - activemerchant (>= 0) ruby depends on - activesupport (>= 2.0.0) ruby + activemerchant was resolved to 1.0, which depends on + activesupport (>= 2.0.0) - rails_fail (>= 0) ruby depends on - activesupport (= 1.2.3) ruby + rails_fail was resolved to 1.0, which depends on + activesupport (= 1.2.3) E expect(out).to eq(nice_error) end @@ -119,10 +119,10 @@ Resolving dependencies... Bundler could not find compatible versions for gem "activesupport": In Gemfile: - rails_fail (>= 0) ruby depends on - activesupport (= 1.2.3) ruby + activesupport (= 2.3.5) - activesupport (= 2.3.5) ruby + rails_fail was resolved to 1.0, which depends on + activesupport (= 1.2.3) E expect(out).to eq(nice_error) end diff --git a/spec/install/gems/flex_spec.rb b/spec/install/gems/flex_spec.rb index d6ff15bf086..8b344cd8ad8 100644 --- a/spec/install/gems/flex_spec.rb +++ b/spec/install/gems/flex_spec.rb @@ -200,11 +200,11 @@ rack (= 0.9.1) In Gemfile: - rack_middleware (>= 0) ruby depends on - rack (= 0.9.1) ruby + rack-obama (= 2.0) was resolved to 2.0, which depends on + rack (= 1.2) - rack-obama (= 2.0) ruby depends on - rack (= 1.2) ruby + rack_middleware was resolved to 1.0, which depends on + rack (= 0.9.1) Running `bundle update` will rebuild your snapshot from scratch, using only the gems in your Gemfile, which may resolve the conflict. @@ -277,43 +277,42 @@ end end - # This was written to test github issue #636, but it passed. - # It's insanoly slow (3.36s) so I'm not going to run it - # describe "when a locked child dependency conflicts" do - # before(:each) do - # build_repo2 do - # build_gem "capybara", "0.3.9" do |s| - # s.add_dependency "rack", ">= 1.0.0" - # end - # - # build_gem "rack", "1.1.0" - # build_gem "rails", "3.0.0.rc4" do |s| - # s.add_dependency "rack", "~> 1.1.0" - # end - # - # build_gem "rack", "1.2.1" - # build_gem "rails", "3.0.0" do |s| - # s.add_dependency "rack", "~> 1.2.1" - # end - # end - # end - # - # it "prints the correct error message" do - # # install Rails 3.0.0.rc - # install_gemfile <<-G - # source "file://#{gem_repo2}" - # gem "rails", "3.0.0.rc4" - # gem "capybara", "0.3.9" - # G - # - # # upgrade Rails to 3.0.0 and then install again - # install_gemfile <<-G - # source "file://#{gem_repo2}" - # gem "rails", "3.0.0" - # gem "capybara", "0.3.9" - # G - # - # out.should match(/Gemfile.lock/) - # end - # end + # This was written to test github issue #636 + describe "when a locked child dependency conflicts" do + before(:each) do + build_repo2 do + build_gem "capybara", "0.3.9" do |s| + s.add_dependency "rack", ">= 1.0.0" + end + + build_gem "rack", "1.1.0" + build_gem "rails", "3.0.0.rc4" do |s| + s.add_dependency "rack", "~> 1.1.0" + end + + build_gem "rack", "1.2.1" + build_gem "rails", "3.0.0" do |s| + s.add_dependency "rack", "~> 1.2.1" + end + end + end + + it "prints the correct error message" do + # install Rails 3.0.0.rc + install_gemfile <<-G + source "file://#{gem_repo2}" + gem "rails", "3.0.0.rc4" + gem "capybara", "0.3.9" + G + + # upgrade Rails to 3.0.0 and then install again + install_gemfile <<-G + source "file://#{gem_repo2}" + gem "rails", "3.0.0" + gem "capybara", "0.3.9" + G + + expect(out).to include("Gemfile.lock") + end + end end diff --git a/spec/install/gems/resolving_spec.rb b/spec/install/gems/resolving_spec.rb index 7ef2535e571..5377db233ed 100644 --- a/spec/install/gems/resolving_spec.rb +++ b/spec/install/gems/resolving_spec.rb @@ -96,7 +96,8 @@ bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1" } end - expect(resolve_output).to include(" net_b (>= 0) ruby") + expect(resolve_output).to include(" net_b") + expect(resolve_output).to include(" net_build_extensions (1.0)") end end end diff --git a/spec/install/gems/sources_spec.rb b/spec/install/gems/sources_spec.rb index bf302d8d9ec..0206dc1dbf4 100644 --- a/spec/install/gems/sources_spec.rb +++ b/spec/install/gems/sources_spec.rb @@ -280,7 +280,7 @@ it "does not install the gem" do bundle :install - expect(out).to include("Could not find gem 'not_in_repo1 (>= 0) ruby'") + expect(out).to include("Could not find gem 'not_in_repo1'") end end diff --git a/spec/install/post_bundle_message_spec.rb b/spec/install/post_bundle_message_spec.rb index 1c7847ce50c..39076461dbd 100644 --- a/spec/install/post_bundle_message_spec.rb +++ b/spec/install/post_bundle_message_spec.rb @@ -89,7 +89,7 @@ gem "rack" gem "not-a-gem", :group => :development G - expect(out).to include("Could not find gem 'not-a-gem (>= 0) ruby' in any of the gem sources listed in your Gemfile or available on this machine.") + expect(out).to include("Could not find gem 'not-a-gem' in any of the gem sources listed in your Gemfile or available on this machine.") end end end diff --git a/spec/runtime/inline_spec.rb b/spec/runtime/inline_spec.rb index 2e33cf9c9f5..a5142d34ed4 100644 --- a/spec/runtime/inline_spec.rb +++ b/spec/runtime/inline_spec.rb @@ -69,7 +69,7 @@ def script(code, options = {}) puts "success" RUBY - expect(err).to include "Could not find gem 'eleven (>= 0) ruby'" + expect(err).to include "Could not find gem 'eleven'" expect(out).not_to include "success" script <<-RUBY