bundler 1.12.6 → 1.13.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +15 -13
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +40 -3
  5. data/CONTRIBUTING.md +9 -5
  6. data/DEVELOPMENT.md +30 -18
  7. data/ISSUES.md +26 -22
  8. data/Rakefile +15 -4
  9. data/bin/rubocop +1 -1
  10. data/bundler.gemspec +2 -2
  11. data/exe/bundle +7 -0
  12. data/lib/bundler.rb +6 -3
  13. data/lib/bundler/capistrano.rb +1 -1
  14. data/lib/bundler/cli.rb +27 -10
  15. data/lib/bundler/cli/binstubs.rb +2 -0
  16. data/lib/bundler/cli/exec.rb +1 -1
  17. data/lib/bundler/cli/install.rb +87 -56
  18. data/lib/bundler/cli/lock.rb +5 -0
  19. data/lib/bundler/cli/open.rb +3 -1
  20. data/lib/bundler/cli/outdated.rb +8 -8
  21. data/lib/bundler/cli/plugin.rb +23 -0
  22. data/lib/bundler/cli/update.rb +2 -2
  23. data/lib/bundler/cli/viz.rb +3 -0
  24. data/lib/bundler/definition.rb +72 -16
  25. data/lib/bundler/dsl.rb +19 -7
  26. data/lib/bundler/endpoint_specification.rb +2 -2
  27. data/lib/bundler/env.rb +2 -2
  28. data/lib/bundler/errors.rb +15 -1
  29. data/lib/bundler/fetcher.rb +5 -2
  30. data/lib/bundler/fetcher/compact_index.rb +2 -2
  31. data/lib/bundler/fetcher/dependency.rb +8 -4
  32. data/lib/bundler/fetcher/downloader.rb +1 -1
  33. data/lib/bundler/friendly_errors.rb +1 -1
  34. data/lib/bundler/index.rb +29 -36
  35. data/lib/bundler/inline.rb +14 -4
  36. data/lib/bundler/installer.rb +22 -3
  37. data/lib/bundler/installer/gem_installer.rb +1 -1
  38. data/lib/bundler/installer/standalone.rb +1 -1
  39. data/lib/bundler/mirror.rb +4 -4
  40. data/lib/bundler/plugin.rb +156 -0
  41. data/lib/bundler/plugin/api.rb +56 -0
  42. data/lib/bundler/plugin/dsl.rb +29 -0
  43. data/lib/bundler/plugin/index.rb +88 -0
  44. data/lib/bundler/plugin/installer.rb +99 -0
  45. data/lib/bundler/plugin/installer/git.rb +38 -0
  46. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  47. data/lib/bundler/plugin/source_list.rb +24 -0
  48. data/lib/bundler/postit_trampoline.rb +54 -0
  49. data/lib/bundler/psyched_yaml.rb +1 -1
  50. data/lib/bundler/remote_specification.rb +5 -5
  51. data/lib/bundler/resolver.rb +27 -29
  52. data/lib/bundler/ruby_version.rb +29 -3
  53. data/lib/bundler/rubygems_ext.rb +3 -1
  54. data/lib/bundler/rubygems_integration.rb +10 -4
  55. data/lib/bundler/runtime.rb +1 -16
  56. data/lib/bundler/settings.rb +19 -15
  57. data/lib/bundler/setup.rb +1 -0
  58. data/lib/bundler/shared_helpers.rb +3 -0
  59. data/lib/bundler/source.rb +4 -3
  60. data/lib/bundler/source/gemspec.rb +13 -0
  61. data/lib/bundler/source/git.rb +4 -3
  62. data/lib/bundler/source/git/git_proxy.rb +9 -5
  63. data/lib/bundler/source/path.rb +11 -2
  64. data/lib/bundler/source/rubygems.rb +28 -15
  65. data/lib/bundler/source_list.rb +5 -1
  66. data/lib/bundler/spec_set.rb +3 -3
  67. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  68. data/lib/bundler/ssl_certs/rubygems.org/{AddTrustExternalCARoot-2048.pem → AddTrustExternalCARoot.pem} +0 -0
  69. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +54 -29
  70. data/lib/bundler/templates/newgem/newgem.gemspec.tt +5 -2
  71. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +3 -3
  72. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -2
  73. data/lib/bundler/ui/shell.rb +4 -0
  74. data/lib/bundler/ui/silent.rb +3 -0
  75. data/lib/bundler/uri_credentials_filter.rb +36 -0
  76. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +1 -1
  77. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +50 -0
  78. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +80 -0
  79. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +56 -144
  80. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +35 -0
  81. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +58 -0
  82. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +61 -0
  83. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +53 -0
  84. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +114 -0
  85. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +45 -0
  86. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +35 -0
  87. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +123 -0
  88. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  89. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +46 -51
  90. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +4 -2
  91. data/lib/bundler/vendor/postit/lib/postit.rb +15 -0
  92. data/lib/bundler/vendor/postit/lib/postit/environment.rb +44 -0
  93. data/lib/bundler/vendor/postit/lib/postit/installer.rb +28 -0
  94. data/lib/bundler/vendor/postit/lib/postit/parser.rb +21 -0
  95. data/lib/bundler/vendor/postit/lib/postit/setup.rb +12 -0
  96. data/lib/bundler/vendor/postit/lib/postit/version.rb +3 -0
  97. data/lib/bundler/version.rb +1 -1
  98. data/lib/bundler/vlad.rb +1 -1
  99. data/lib/bundler/yaml_serializer.rb +67 -0
  100. data/man/bundle-install.ronn +10 -5
  101. data/man/bundle-package.ronn +7 -6
  102. data/man/bundle-platform.ronn +1 -1
  103. data/man/bundle-update.ronn +5 -2
  104. data/man/bundle.ronn +5 -5
  105. data/man/gemfile.5.ronn +32 -28
  106. metadata +37 -12
  107. data/lib/bundler/ssl_certs/Fastly.pem +0 -82
  108. data/lib/bundler/ssl_certs/GlobalSignOrganizationValidationCA.pem +0 -26
  109. data/lib/bundler/ssl_certs/GlobalSignRoot.pem +0 -18
  110. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRoot.pem +0 -18
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
3
+ module Bundler::Molinillo
4
+ class DependencyGraph
5
+ # @!visibility private
6
+ # (see DependencyGraph#add_vertex)
7
+ class AddVertex < Action # :nodoc:
8
+ # @!group Action
9
+
10
+ # (see Action.name)
11
+ def self.name
12
+ :add_vertex
13
+ end
14
+
15
+ # (see Action#up)
16
+ def up(graph)
17
+ if existing = graph.vertices[name]
18
+ @existing_payload = existing.payload
19
+ @existing_root = existing.root
20
+ end
21
+ vertex = existing || Vertex.new(name, payload)
22
+ graph.vertices[vertex.name] = vertex
23
+ vertex.payload ||= payload
24
+ vertex.root ||= root
25
+ vertex
26
+ end
27
+
28
+ # (see Action#down)
29
+ def down(graph)
30
+ if defined?(@existing_payload)
31
+ vertex = graph.vertices[name]
32
+ vertex.payload = @existing_payload
33
+ vertex.root = @existing_root
34
+ else
35
+ graph.vertices.delete(name)
36
+ end
37
+ end
38
+
39
+ # @!group AddVertex
40
+
41
+ # @return [String] the name of the vertex
42
+ attr_reader :name
43
+
44
+ # @return [Object] the payload for the vertex
45
+ attr_reader :payload
46
+
47
+ # @return [Boolean] whether the vertex is root or not
48
+ attr_reader :root
49
+
50
+ # Initialize an action to add a vertex to a dependency graph
51
+ # @param [String] name the name of the vertex
52
+ # @param [Object] payload the payload for the vertex
53
+ # @param [Boolean] root whether the vertex is root or not
54
+ def initialize(name, payload, root)
55
+ @name = name
56
+ @payload = payload
57
+ @root = root
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
3
+ module Bundler::Molinillo
4
+ class DependencyGraph
5
+ # @!visibility private
6
+ # @see DependencyGraph#detach_vertex_named
7
+ class DetachVertexNamed < Action
8
+ # @!group Action
9
+
10
+ # (see Action#name)
11
+ def self.name
12
+ :add_vertex
13
+ end
14
+
15
+ # (see Action#up)
16
+ def up(graph)
17
+ return unless @vertex = graph.vertices.delete(name)
18
+ @vertex.outgoing_edges.each do |e|
19
+ v = e.destination
20
+ v.incoming_edges.delete(e)
21
+ graph.detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
22
+ end
23
+ @vertex.incoming_edges.each do |e|
24
+ v = e.origin
25
+ v.outgoing_edges.delete(e)
26
+ end
27
+ end
28
+
29
+ # (see Action#down)
30
+ def down(graph)
31
+ return unless @vertex
32
+ graph.vertices[@vertex.name] = @vertex
33
+ @vertex.outgoing_edges.each do |e|
34
+ e.destination.incoming_edges << e
35
+ end
36
+ @vertex.incoming_edges.each do |e|
37
+ e.origin.outgoing_edges << e
38
+ end
39
+ end
40
+
41
+ # @!group DetachVertexNamed
42
+
43
+ # @return [String] the name of the vertex to detach
44
+ attr_reader :name
45
+
46
+ # Initialize an action to detach a vertex from a dependency graph
47
+ # @param [String] name the name of the vertex to detach
48
+ def initialize(name)
49
+ @name = name
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
3
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex'
4
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
5
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload'
6
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag'
7
+
8
+ module Bundler::Molinillo
9
+ class DependencyGraph
10
+ # A log for dependency graph actions
11
+ class Log
12
+ # Initializes an empty log
13
+ def initialize
14
+ @current_action = @first_action = nil
15
+ end
16
+
17
+ # @!macro [new] action
18
+ # {include:DependencyGraph#$0}
19
+ # @param [Graph] graph the graph to perform the action on
20
+ # @param (see DependencyGraph#$0)
21
+ # @return (see DependencyGraph#$0)
22
+
23
+ # @macro action
24
+ def tag(graph, tag)
25
+ push_action(graph, Tag.new(tag))
26
+ end
27
+
28
+ # @macro action
29
+ def add_vertex(graph, name, payload, root)
30
+ push_action(graph, AddVertex.new(name, payload, root))
31
+ end
32
+
33
+ # @macro action
34
+ def detach_vertex_named(graph, name)
35
+ push_action(graph, DetachVertexNamed.new(name))
36
+ end
37
+
38
+ # @macro action
39
+ def add_edge_no_circular(graph, origin, destination, requirement)
40
+ push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement))
41
+ end
42
+
43
+ # @macro action
44
+ def set_payload(graph, name, payload)
45
+ push_action(graph, SetPayload.new(name, payload))
46
+ end
47
+
48
+ # Pops the most recent action from the log and undoes the action
49
+ # @param [DependencyGraph] graph
50
+ # @return [Action] the action that was popped off the log
51
+ def pop!(graph)
52
+ return unless action = @current_action
53
+ unless @current_action = action.previous
54
+ @first_action = nil
55
+ end
56
+ action.down(graph)
57
+ action
58
+ end
59
+
60
+ extend Enumerable
61
+
62
+ # @!visibility private
63
+ # Enumerates each action in the log
64
+ # @yield [Action]
65
+ def each
66
+ return enum_for unless block_given?
67
+ action = @first_action
68
+ loop do
69
+ break unless action
70
+ yield action
71
+ action = action.next
72
+ end
73
+ self
74
+ end
75
+
76
+ # @!visibility private
77
+ # Enumerates each action in the log in reverse order
78
+ # @yield [Action]
79
+ def reverse_each
80
+ return enum_for(:reverse_each) unless block_given?
81
+ action = @current_action
82
+ loop do
83
+ break unless action
84
+ yield action
85
+ action = action.previous
86
+ end
87
+ self
88
+ end
89
+
90
+ # @macro action
91
+ def rewind_to(graph, tag)
92
+ loop do
93
+ action = pop!(graph)
94
+ raise "No tag #{tag.inspect} found" unless action
95
+ break if action.class.name == :tag && action.tag == tag
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ # Adds the given action to the log, running the action
102
+ # @param [DependencyGraph] graph
103
+ # @param [Action] action
104
+ # @return The value returned by `action.up`
105
+ def push_action(graph, action)
106
+ action.previous = @current_action
107
+ @current_action.next = action if @current_action
108
+ @current_action = action
109
+ @first_action ||= action
110
+ action.up(graph)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
3
+ module Bundler::Molinillo
4
+ class DependencyGraph
5
+ # @!visibility private
6
+ # @see DependencyGraph#set_payload
7
+ class SetPayload < Action # :nodoc:
8
+ # @!group Action
9
+
10
+ # (see Action.name)
11
+ def self.name
12
+ :set_payload
13
+ end
14
+
15
+ # (see Action#up)
16
+ def up(graph)
17
+ vertex = graph.vertex_named(name)
18
+ @old_payload = vertex.payload
19
+ vertex.payload = payload
20
+ end
21
+
22
+ # (see Action#down)
23
+ def down(graph)
24
+ graph.vertex_named(name).payload = @old_payload
25
+ end
26
+
27
+ # @!group SetPayload
28
+
29
+ # @return [String] the name of the vertex
30
+ attr_reader :name
31
+
32
+ # @return [Object] the payload for the vertex
33
+ attr_reader :payload
34
+
35
+ # Initialize an action to add set the payload for a vertex in a dependency
36
+ # graph
37
+ # @param [String] name the name of the vertex
38
+ # @param [Object] payload the payload for the vertex
39
+ def initialize(name, payload)
40
+ @name = name
41
+ @payload = payload
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
3
+ module Bundler::Molinillo
4
+ class DependencyGraph
5
+ # @!visibility private
6
+ # @see DependencyGraph#tag
7
+ class Tag < Action
8
+ # @!group Action
9
+
10
+ # (see Action.name)
11
+ def self.name
12
+ :tag
13
+ end
14
+
15
+ # (see Action#up)
16
+ def up(_graph)
17
+ end
18
+
19
+ # (see Action#down)
20
+ def down(_graph)
21
+ end
22
+
23
+ # @!group Tag
24
+
25
+ # @return [Object] An opaque tag
26
+ attr_reader :tag
27
+
28
+ # Initialize an action to tag a state of a dependency graph
29
+ # @param [Object] tag an opaque tag
30
+ def initialize(tag)
31
+ @tag = tag
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+ module Bundler::Molinillo
3
+ class DependencyGraph
4
+ # A vertex in a {DependencyGraph} that encapsulates a {#name} and a
5
+ # {#payload}
6
+ class Vertex
7
+ # @return [String] the name of the vertex
8
+ attr_accessor :name
9
+
10
+ # @return [Object] the payload the vertex holds
11
+ attr_accessor :payload
12
+
13
+ # @return [Arrary<Object>] the explicit requirements that required
14
+ # this vertex
15
+ attr_reader :explicit_requirements
16
+
17
+ # @return [Boolean] whether the vertex is considered a root vertex
18
+ attr_accessor :root
19
+ alias root? root
20
+
21
+ # Initializes a vertex with the given name and payload.
22
+ # @param [String] name see {#name}
23
+ # @param [Object] payload see {#payload}
24
+ def initialize(name, payload)
25
+ @name = name.frozen? ? name : name.dup.freeze
26
+ @payload = payload
27
+ @explicit_requirements = []
28
+ @outgoing_edges = []
29
+ @incoming_edges = []
30
+ end
31
+
32
+ # @return [Array<Object>] all of the requirements that required
33
+ # this vertex
34
+ def requirements
35
+ incoming_edges.map(&:requirement) + explicit_requirements
36
+ end
37
+
38
+ # @return [Array<Edge>] the edges of {#graph} that have `self` as their
39
+ # {Edge#origin}
40
+ attr_accessor :outgoing_edges
41
+
42
+ # @return [Array<Edge>] the edges of {#graph} that have `self` as their
43
+ # {Edge#destination}
44
+ attr_accessor :incoming_edges
45
+
46
+ # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
47
+ # `self` as their {Edge#destination}
48
+ def predecessors
49
+ incoming_edges.map(&:origin)
50
+ end
51
+
52
+ # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
53
+ # {#descendent?}
54
+ def recursive_predecessors
55
+ vertices = predecessors
56
+ vertices += vertices.map(&:recursive_predecessors).flatten(1)
57
+ vertices.uniq!
58
+ vertices
59
+ end
60
+
61
+ # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
62
+ # `self` as their {Edge#origin}
63
+ def successors
64
+ outgoing_edges.map(&:destination)
65
+ end
66
+
67
+ # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
68
+ # {#ancestor?}
69
+ def recursive_successors
70
+ vertices = successors
71
+ vertices += vertices.map(&:recursive_successors).flatten(1)
72
+ vertices.uniq!
73
+ vertices
74
+ end
75
+
76
+ # @return [String] a string suitable for debugging
77
+ def inspect
78
+ "#{self.class}:#{name}(#{payload.inspect})"
79
+ end
80
+
81
+ # @return [Boolean] whether the two vertices are equal, determined
82
+ # by a recursive traversal of each {Vertex#successors}
83
+ def ==(other)
84
+ shallow_eql?(other) &&
85
+ successors.to_set == other.successors.to_set
86
+ end
87
+
88
+ # @param [Vertex] other the other vertex to compare to
89
+ # @return [Boolean] whether the two vertices are equal, determined
90
+ # solely by {#name} and {#payload} equality
91
+ def shallow_eql?(other)
92
+ other &&
93
+ name == other.name &&
94
+ payload == other.payload
95
+ end
96
+
97
+ alias eql? ==
98
+
99
+ # @return [Fixnum] a hash for the vertex based upon its {#name}
100
+ def hash
101
+ name.hash
102
+ end
103
+
104
+ # Is there a path from `self` to `other` following edges in the
105
+ # dependency graph?
106
+ # @return true iff there is a path following edges within this {#graph}
107
+ def path_to?(other)
108
+ equal?(other) || successors.any? { |v| v.path_to?(other) }
109
+ end
110
+
111
+ alias descendent? path_to?
112
+
113
+ # Is there a path from `other` to `self` following edges in the
114
+ # dependency graph?
115
+ # @return true iff there is a path following edges within this {#graph}
116
+ def ancestor?(other)
117
+ other.path_to?(self)
118
+ end
119
+
120
+ alias is_reachable_from? ancestor?
121
+ end
122
+ end
123
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Bundler::Molinillo
3
3
  # The version of Bundler::Molinillo.
4
- VERSION = '0.4.5'.freeze
4
+ VERSION = '0.5.0'.freeze
5
5
  end
@@ -52,6 +52,7 @@ module Bundler::Molinillo
52
52
  @base = base
53
53
  @states = []
54
54
  @iteration_counter = 0
55
+ @parent_of = {}
55
56
  end
56
57
 
57
58
  # Resolves the {#original_requested} dependencies into a full dependency
@@ -67,7 +68,12 @@ module Bundler::Molinillo
67
68
  indicate_progress
68
69
  if state.respond_to?(:pop_possibility_state) # DependencyState
69
70
  debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
70
- state.pop_possibility_state.tap { |s| states.push(s) if s }
71
+ state.pop_possibility_state.tap do |s|
72
+ if s
73
+ states.push(s)
74
+ activated.tag(s)
75
+ end
76
+ end
71
77
  end
72
78
  process_topmost_state
73
79
  end
@@ -118,27 +124,11 @@ module Bundler::Molinillo
118
124
  require 'bundler/vendor/molinillo/lib/molinillo/state'
119
125
  require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
120
126
 
121
- ResolutionState.new.members.each do |member|
122
- define_method member do |*args, &block|
123
- current_state = state || ResolutionState.empty
124
- current_state.send(member, *args, &block)
125
- end
126
- end
127
+ require 'bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state'
128
+ require 'bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider'
127
129
 
128
- SpecificationProvider.instance_methods(false).each do |instance_method|
129
- define_method instance_method do |*args, &block|
130
- begin
131
- specification_provider.send(instance_method, *args, &block)
132
- rescue NoSuchDependencyError => error
133
- if state
134
- vertex = activated.vertex_named(name_for(error.dependency))
135
- error.required_by += vertex.incoming_edges.map { |e| e.origin.name }
136
- error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty?
137
- end
138
- raise
139
- end
140
- end
141
- end
130
+ include Bundler::Molinillo::Delegates::ResolutionState
131
+ include Bundler::Molinillo::Delegates::SpecificationProvider
142
132
 
143
133
  # Processes the topmost available {RequirementState} on the stack
144
134
  # @return [void]
@@ -169,6 +159,7 @@ module Bundler::Molinillo
169
159
  def initial_state
170
160
  graph = DependencyGraph.new.tap do |dg|
171
161
  original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
162
+ dg.tag(:initial_state)
172
163
  end
173
164
 
174
165
  requirements = sort_dependencies(original_requested, graph, {})
@@ -189,8 +180,9 @@ module Bundler::Molinillo
189
180
  def unwind_for_conflict
190
181
  debug(depth) { "Unwinding for conflict: #{requirement}" }
191
182
  conflicts.tap do |c|
192
- states.slice!((state_index_for_unwind + 1)..-1)
183
+ sliced_states = states.slice!((state_index_for_unwind + 1)..-1)
193
184
  raise VersionConflict.new(c) unless state
185
+ activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
194
186
  state.conflicts = c
195
187
  end
196
188
  end
@@ -217,20 +209,14 @@ module Bundler::Molinillo
217
209
  # @return [Object] the requirement that led to `requirement` being added
218
210
  # to the list of requirements.
219
211
  def parent_of(requirement)
220
- return nil unless requirement
221
- seen = false
222
- state = states.reverse_each.find do |s|
223
- seen ||= s.requirement == requirement || s.requirements.include?(requirement)
224
- seen && s.requirement != requirement && !s.requirements.include?(requirement)
225
- end
226
- state && state.requirement
212
+ @parent_of[requirement]
227
213
  end
228
214
 
229
215
  # @return [Object] the requirement that led to a version of a possibility
230
216
  # with the given name being activated.
231
217
  def requirement_for_existing_name(name)
232
218
  return nil unless activated.vertex_named(name).payload
233
- states.reverse_each.find { |s| !s.activated.vertex_named(name).payload }.requirement
219
+ states.find { |s| s.name == name }.requirement
234
220
  end
235
221
 
236
222
  # @return [ResolutionState] the state whose `requirement` is the given
@@ -250,19 +236,25 @@ module Bundler::Molinillo
250
236
  # the {#possibility} in conjunction with the current {#state}
251
237
  def create_conflict
252
238
  vertex = activated.vertex_named(name)
253
- requirements = {
254
- name_for_explicit_dependency_source => vertex.explicit_requirements,
255
- name_for_locking_dependency_source => Array(locked_requirement_named(name)),
256
- }
239
+ locked_requirement = locked_requirement_named(name)
240
+
241
+ requirements = {}
242
+ unless vertex.explicit_requirements.empty?
243
+ requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
244
+ end
245
+ requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
257
246
  vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
247
+
248
+ activated_by_name = {}
249
+ activated.each { |v| activated_by_name[v.name] = v.payload if v.payload }
258
250
  conflicts[name] = Conflict.new(
259
251
  requirement,
260
- Hash[requirements.select { |_, r| !r.empty? }],
252
+ requirements,
261
253
  vertex.payload,
262
254
  possibility,
263
- locked_requirement_named(name),
255
+ locked_requirement,
264
256
  requirement_trees,
265
- Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)]
257
+ activated_by_name
266
258
  )
267
259
  end
268
260
 
@@ -341,15 +333,16 @@ module Bundler::Molinillo
341
333
  # spec with the given name
342
334
  # @return [Boolean] Whether the possibility was swapped into {#activated}
343
335
  def attempt_to_swap_possibility
344
- swapped = activated.dup
345
- vertex = swapped.vertex_named(name)
346
- vertex.payload = possibility
347
- return unless vertex.requirements.
348
- all? { |r| requirement_satisfied_by?(r, swapped, possibility) }
349
- return unless new_spec_satisfied?
350
- actual_vertex = activated.vertex_named(name)
351
- actual_vertex.payload = possibility
352
- fixup_swapped_children(actual_vertex)
336
+ activated.tag(:swap)
337
+ vertex = activated.vertex_named(name)
338
+ activated.set_payload(name, possibility)
339
+ if !vertex.requirements.
340
+ all? { |r| requirement_satisfied_by?(r, activated, possibility) } ||
341
+ !new_spec_satisfied?
342
+ activated.rewind_to(:swap)
343
+ return
344
+ end
345
+ fixup_swapped_children(vertex)
353
346
  activate_spec
354
347
  end
355
348
 
@@ -412,8 +405,7 @@ module Bundler::Molinillo
412
405
  def activate_spec
413
406
  conflicts.delete(name)
414
407
  debug(depth) { 'Activated ' + name + ' at ' + possibility.to_s }
415
- vertex = activated.vertex_named(name)
416
- vertex.payload = possibility
408
+ activated.set_payload(name, possibility)
417
409
  require_nested_dependencies_for(possibility)
418
410
  end
419
411
 
@@ -424,7 +416,10 @@ module Bundler::Molinillo
424
416
  def require_nested_dependencies_for(activated_spec)
425
417
  nested_dependencies = dependencies_for(activated_spec)
426
418
  debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
427
- nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
419
+ nested_dependencies.each do |d|
420
+ activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d)
421
+ @parent_of[d] = requirement
422
+ end
428
423
 
429
424
  push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
430
425
  end
@@ -436,7 +431,7 @@ module Bundler::Molinillo
436
431
  def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
437
432
  new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
438
433
  new_requirement = new_requirements.shift
439
- new_name = new_requirement ? name_for(new_requirement) : ''
434
+ new_name = new_requirement ? name_for(new_requirement) : ''.freeze
440
435
  possibilities = new_requirement ? search_for(new_requirement) : []
441
436
  handle_missing_or_push_dependency_state DependencyState.new(
442
437
  new_name, new_requirements, new_activated,
@@ -457,7 +452,7 @@ module Bundler::Molinillo
457
452
  state.activated.detach_vertex_named(state.name)
458
453
  push_state_for_requirements(state.requirements.dup, false, state.activated)
459
454
  else
460
- states.push state
455
+ states.push(state).tap { activated.tag(state) }
461
456
  end
462
457
  end
463
458
  end