bundler 1.11.2 → 1.12.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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +24 -0
- data/.gitignore +2 -2
- data/.rubocop.yml +17 -2
- data/.rubocop_todo.yml +145 -18
- data/.travis.yml +9 -2
- data/CHANGELOG.md +42 -0
- data/Rakefile +20 -13
- data/bin/rake +5 -0
- data/bin/rspec +5 -0
- data/bin/rubocop +7 -1
- data/bundler.gemspec +2 -1
- data/exe/bundle +10 -2
- data/exe/bundle_ruby +2 -1
- data/exe/bundler +3 -1
- data/lib/bundler.rb +54 -51
- data/lib/bundler/capistrano.rb +1 -0
- data/lib/bundler/cli.rb +26 -4
- data/lib/bundler/cli/binstubs.rb +1 -0
- data/lib/bundler/cli/cache.rb +1 -0
- data/lib/bundler/cli/check.rb +4 -1
- data/lib/bundler/cli/clean.rb +1 -0
- data/lib/bundler/cli/common.rb +1 -0
- data/lib/bundler/cli/config.rb +5 -5
- data/lib/bundler/cli/console.rb +1 -0
- data/lib/bundler/cli/exec.rb +4 -9
- data/lib/bundler/cli/gem.rb +12 -9
- data/lib/bundler/cli/init.rb +1 -0
- data/lib/bundler/cli/inject.rb +1 -0
- data/lib/bundler/cli/install.rb +8 -5
- data/lib/bundler/cli/lock.rb +2 -0
- data/lib/bundler/cli/open.rb +1 -0
- data/lib/bundler/cli/outdated.rb +36 -9
- data/lib/bundler/cli/package.rb +1 -0
- data/lib/bundler/cli/platform.rb +4 -1
- data/lib/bundler/cli/show.rb +1 -0
- data/lib/bundler/cli/update.rb +6 -6
- data/lib/bundler/cli/viz.rb +4 -6
- data/lib/bundler/constants.rb +1 -0
- data/lib/bundler/current_ruby.rb +34 -168
- data/lib/bundler/definition.rb +41 -15
- data/lib/bundler/dep_proxy.rb +1 -0
- data/lib/bundler/dependency.rb +10 -0
- data/lib/bundler/deployment.rb +1 -0
- data/lib/bundler/deprecate.rb +1 -0
- data/lib/bundler/dsl.rb +19 -9
- data/lib/bundler/endpoint_specification.rb +37 -8
- data/lib/bundler/env.rb +4 -3
- data/lib/bundler/environment.rb +1 -0
- data/lib/bundler/errors.rb +51 -32
- data/lib/bundler/fetcher.rb +44 -30
- data/lib/bundler/fetcher/base.rb +3 -2
- data/lib/bundler/fetcher/compact_index.rb +98 -0
- data/lib/bundler/fetcher/dependency.rb +36 -36
- data/lib/bundler/fetcher/downloader.rb +14 -8
- data/lib/bundler/fetcher/index.rb +28 -5
- data/lib/bundler/friendly_errors.rb +93 -85
- data/lib/bundler/gem_helper.rb +20 -21
- data/lib/bundler/gem_helpers.rb +9 -2
- data/lib/bundler/gem_remote_fetcher.rb +1 -0
- data/lib/bundler/gem_tasks.rb +1 -0
- data/lib/bundler/graph.rb +16 -17
- data/lib/bundler/index.rb +4 -6
- data/lib/bundler/injector.rb +1 -0
- data/lib/bundler/inline.rb +8 -2
- data/lib/bundler/installer.rb +4 -4
- data/lib/bundler/installer/gem_installer.rb +1 -0
- data/lib/bundler/installer/parallel_installer.rb +3 -2
- data/lib/bundler/installer/standalone.rb +5 -1
- data/lib/bundler/lazy_specification.rb +5 -2
- data/lib/bundler/lockfile_parser.rb +22 -15
- data/lib/bundler/match_platform.rb +1 -0
- data/lib/bundler/mirror.rb +218 -0
- data/lib/bundler/path_preserver.rb +12 -0
- data/lib/bundler/psyched_yaml.rb +1 -0
- data/lib/bundler/remote_specification.rb +4 -1
- data/lib/bundler/resolver.rb +17 -16
- data/lib/bundler/retry.rb +1 -0
- data/lib/bundler/ruby_dsl.rb +8 -2
- data/lib/bundler/ruby_version.rb +58 -61
- data/lib/bundler/rubygems_ext.rb +4 -3
- data/lib/bundler/rubygems_gem_installer.rb +1 -0
- data/lib/bundler/rubygems_integration.rb +9 -14
- data/lib/bundler/runtime.rb +17 -22
- data/lib/bundler/settings.rb +17 -21
- data/lib/bundler/setup.rb +1 -0
- data/lib/bundler/shared_helpers.rb +47 -17
- data/lib/bundler/similarity_detector.rb +1 -0
- data/lib/bundler/source.rb +2 -1
- data/lib/bundler/source/git.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +33 -7
- data/lib/bundler/source/path.rb +17 -10
- data/lib/bundler/source/path/installer.rb +1 -0
- data/lib/bundler/source/rubygems.rb +4 -3
- data/lib/bundler/source/rubygems/remote.rb +16 -0
- data/lib/bundler/source_list.rb +1 -0
- data/lib/bundler/spec_set.rb +1 -0
- data/lib/bundler/ssl_certs/certificate_manager.rb +1 -0
- data/lib/bundler/stub_specification.rb +1 -0
- data/lib/bundler/templates/Executable +1 -0
- data/lib/bundler/templates/Gemfile +1 -0
- data/lib/bundler/templates/newgem/.travis.yml.tt +1 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
- data/lib/bundler/ui.rb +1 -0
- data/lib/bundler/ui/rg_proxy.rb +1 -0
- data/lib/bundler/ui/shell.rb +2 -1
- data/lib/bundler/ui/silent.rb +1 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +78 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +97 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +55 -0
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +3 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +4 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +13 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +5 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +37 -14
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +7 -7
- data/lib/bundler/vendored_molinillo.rb +1 -0
- data/lib/bundler/vendored_persistent.rb +1 -0
- data/lib/bundler/vendored_thor.rb +1 -0
- data/lib/bundler/version.rb +6 -1
- data/lib/bundler/vlad.rb +1 -0
- data/lib/bundler/worker.rb +12 -2
- data/man/bundle-config.ronn +6 -0
- data/man/bundle-gem.ronn +5 -5
- metadata +14 -6
- data/lib/bundler/gem_path_manipulation.rb +0 -8
data/lib/bundler/ui/silent.rb
CHANGED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "set"
|
3
|
+
|
4
|
+
class Bundler::CompactIndexClient
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
require "bundler/vendor/compact_index_client/lib/compact_index_client/cache"
|
8
|
+
require "bundler/vendor/compact_index_client/lib/compact_index_client/updater"
|
9
|
+
require "bundler/vendor/compact_index_client/lib/compact_index_client/version"
|
10
|
+
|
11
|
+
attr_reader :directory
|
12
|
+
|
13
|
+
# @return [Lambda] A lambda that takes an array of inputs and a block, and
|
14
|
+
# maps the inputs with the block in parallel.
|
15
|
+
#
|
16
|
+
attr_accessor :in_parallel
|
17
|
+
|
18
|
+
def initialize(directory, fetcher)
|
19
|
+
@directory = Pathname.new(directory)
|
20
|
+
@updater = Updater.new(fetcher)
|
21
|
+
@cache = Cache.new(@directory)
|
22
|
+
@endpoints = Set.new
|
23
|
+
@info_checksums_by_name = {}
|
24
|
+
@in_parallel = lambda do |inputs, &blk|
|
25
|
+
inputs.map(&blk)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def names
|
30
|
+
update(@cache.names_path, "names")
|
31
|
+
@cache.names
|
32
|
+
end
|
33
|
+
|
34
|
+
def versions
|
35
|
+
update(@cache.versions_path, "versions")
|
36
|
+
versions, @info_checksums_by_name = @cache.versions
|
37
|
+
versions
|
38
|
+
end
|
39
|
+
|
40
|
+
def dependencies(names)
|
41
|
+
in_parallel.call(names) do |name|
|
42
|
+
update_info(name)
|
43
|
+
@cache.dependencies(name).map {|d| d.unshift(name) }
|
44
|
+
end.flatten(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def spec(name, version, platform = nil)
|
48
|
+
update_info(name)
|
49
|
+
@cache.specific_dependency(name, version, platform)
|
50
|
+
end
|
51
|
+
|
52
|
+
def update_and_parse_checksums!
|
53
|
+
return @info_checksums_by_name if @parsed_checksums
|
54
|
+
update(@cache.versions_path, "versions")
|
55
|
+
@info_checksums_by_name = @cache.checksums
|
56
|
+
@parsed_checksums = true
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def update(local_path, remote_path)
|
62
|
+
return if @endpoints.include?(remote_path)
|
63
|
+
@updater.update(local_path, url(remote_path))
|
64
|
+
@endpoints << remote_path
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_info(name)
|
68
|
+
path = @cache.info_path(name)
|
69
|
+
checksum = @updater.checksum_for_file(path)
|
70
|
+
return unless existing = @info_checksums_by_name[name]
|
71
|
+
return if checksum == existing
|
72
|
+
update(path, "info/#{name}")
|
73
|
+
end
|
74
|
+
|
75
|
+
def url(path)
|
76
|
+
path
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
class Bundler::CompactIndexClient
|
2
|
+
class Cache
|
3
|
+
attr_reader :directory
|
4
|
+
|
5
|
+
def initialize(directory)
|
6
|
+
@directory = Pathname.new(directory).expand_path
|
7
|
+
FileUtils.mkdir_p info_path(nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
def names
|
11
|
+
lines(names_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def names_path
|
15
|
+
directory.join("names")
|
16
|
+
end
|
17
|
+
|
18
|
+
def versions
|
19
|
+
versions_by_name = Hash.new {|hash, key| hash[key] = [] }
|
20
|
+
info_checksums_by_name = {}
|
21
|
+
|
22
|
+
lines(versions_path).each do |line|
|
23
|
+
name, versions_string, info_checksum = line.split(" ", 3)
|
24
|
+
info_checksums_by_name[name] = info_checksum || ""
|
25
|
+
versions_string.split(",").each do |version|
|
26
|
+
if version.start_with?("-")
|
27
|
+
version = version[1..-1].split("-", 2).unshift(name)
|
28
|
+
versions_by_name[name].delete(version)
|
29
|
+
else
|
30
|
+
version = version.split("-", 2).unshift(name)
|
31
|
+
versions_by_name[name] << version
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
[versions_by_name, info_checksums_by_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def versions_path
|
40
|
+
directory.join("versions")
|
41
|
+
end
|
42
|
+
|
43
|
+
def checksums
|
44
|
+
checksums = {}
|
45
|
+
|
46
|
+
lines(versions_path).each do |line|
|
47
|
+
name, _, checksum = line.split(" ", 3)
|
48
|
+
checksums[name] = checksum
|
49
|
+
end
|
50
|
+
|
51
|
+
checksums
|
52
|
+
end
|
53
|
+
|
54
|
+
def dependencies(name)
|
55
|
+
lines(info_path(name)).map do |line|
|
56
|
+
parse_gem(line)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def info_path(name)
|
61
|
+
directory.join("info", name.to_s)
|
62
|
+
end
|
63
|
+
|
64
|
+
def specific_dependency(name, version, platform)
|
65
|
+
pattern = [version, platform].compact.join("-")
|
66
|
+
return nil if pattern.empty?
|
67
|
+
|
68
|
+
gem_lines = info_path(name).read
|
69
|
+
gem_line = gem_lines[/^#{Regexp.escape(pattern)}\b.*/, 0]
|
70
|
+
gem_line ? parse_gem(gem_line) : nil
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def lines(path)
|
76
|
+
return [] unless path.file?
|
77
|
+
lines = path.read.split("\n")
|
78
|
+
header = lines.index("---")
|
79
|
+
lines = header ? lines[header + 1..-1] : lines
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_gem(string)
|
83
|
+
version_and_platform, rest = string.split(" ", 2)
|
84
|
+
version, platform = version_and_platform.split("-", 2)
|
85
|
+
dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
|
86
|
+
dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
|
87
|
+
requirements = requirements ? requirements.map {|r| parse_dependency(r) } : []
|
88
|
+
[version, platform, dependencies, requirements]
|
89
|
+
end
|
90
|
+
|
91
|
+
def parse_dependency(string)
|
92
|
+
dependency = string.split(":")
|
93
|
+
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
|
94
|
+
dependency
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "stringio"
|
2
|
+
require "zlib"
|
3
|
+
|
4
|
+
class Bundler::CompactIndexClient
|
5
|
+
class Updater
|
6
|
+
class MisMatchedChecksumError < Error; end
|
7
|
+
|
8
|
+
def initialize(fetcher)
|
9
|
+
@fetcher = fetcher
|
10
|
+
end
|
11
|
+
|
12
|
+
def update(local_path, remote_path, retrying = nil)
|
13
|
+
headers = {}
|
14
|
+
|
15
|
+
if local_path.file?
|
16
|
+
headers["If-None-Match"] = etag_for(local_path)
|
17
|
+
headers["Range"] = "bytes=#{local_path.size}-"
|
18
|
+
else
|
19
|
+
# Fastly ignores Range when Accept-Encoding: gzip is set
|
20
|
+
headers["Accept-Encoding"] = "gzip"
|
21
|
+
end
|
22
|
+
|
23
|
+
response = @fetcher.call(remote_path, headers)
|
24
|
+
return if response.is_a?(Net::HTTPNotModified)
|
25
|
+
|
26
|
+
content = response.body
|
27
|
+
if response["Content-Encoding"] == "gzip"
|
28
|
+
content = Zlib::GzipReader.new(StringIO.new(content)).read
|
29
|
+
end
|
30
|
+
|
31
|
+
mode = response.is_a?(Net::HTTPPartialContent) ? "a" : "w"
|
32
|
+
local_path.open(mode) {|f| f << content }
|
33
|
+
|
34
|
+
return if etag_for(local_path) == response["ETag"]
|
35
|
+
|
36
|
+
if retrying.nil?
|
37
|
+
local_path.delete
|
38
|
+
update(local_path, remote_path, :retrying)
|
39
|
+
else
|
40
|
+
raise MisMatchedChecksumError, "Checksum of /#{remote_path} " \
|
41
|
+
"does not match the checksum provided by server! Something is wrong."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def etag_for(path)
|
46
|
+
sum = checksum_for_file(path)
|
47
|
+
sum ? '"' << sum << '"' : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def checksum_for_file(path)
|
51
|
+
return nil unless path.file?
|
52
|
+
Digest::MD5.file(path).hexdigest
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -3,3 +3,7 @@ require 'bundler/vendor/molinillo/lib/molinillo/errors'
|
|
3
3
|
require 'bundler/vendor/molinillo/lib/molinillo/resolver'
|
4
4
|
require 'bundler/vendor/molinillo/lib/molinillo/modules/ui'
|
5
5
|
require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
|
6
|
+
|
7
|
+
# Bundler::Molinillo is a generic dependency resolution algorithm.
|
8
|
+
module Bundler::Molinillo
|
9
|
+
end
|
@@ -14,8 +14,10 @@ module Bundler::Molinillo
|
|
14
14
|
|
15
15
|
include TSort
|
16
16
|
|
17
|
+
# @visibility private
|
17
18
|
alias_method :tsort_each_node, :each
|
18
19
|
|
20
|
+
# @visibility private
|
19
21
|
def tsort_each_child(vertex, &block)
|
20
22
|
vertex.successors.each(&block)
|
21
23
|
end
|
@@ -41,12 +43,14 @@ module Bundler::Molinillo
|
|
41
43
|
# by {Vertex#name}
|
42
44
|
attr_reader :vertices
|
43
45
|
|
46
|
+
# Initializes an empty dependency graph
|
44
47
|
def initialize
|
45
48
|
@vertices = {}
|
46
49
|
end
|
47
50
|
|
48
51
|
# Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
|
49
52
|
# are properly copied.
|
53
|
+
# @param [DependencyGraph] other the graph to copy.
|
50
54
|
def initialize_copy(other)
|
51
55
|
super
|
52
56
|
@vertices = {}
|
@@ -100,6 +104,7 @@ module Bundler::Molinillo
|
|
100
104
|
vertex
|
101
105
|
end
|
102
106
|
|
107
|
+
# Adds a vertex with the given name, or updates the existing one.
|
103
108
|
# @param [String] name
|
104
109
|
# @param [Object] payload
|
105
110
|
# @return [Vertex] the vertex that was added to `self`
|
@@ -121,6 +126,10 @@ module Bundler::Molinillo
|
|
121
126
|
v.incoming_edges.delete(e)
|
122
127
|
detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
|
123
128
|
end
|
129
|
+
vertex.incoming_edges.each do |e|
|
130
|
+
v = e.origin
|
131
|
+
v.outgoing_edges.delete(e)
|
132
|
+
end
|
124
133
|
end
|
125
134
|
|
126
135
|
# @param [String] name
|
@@ -150,6 +159,8 @@ module Bundler::Molinillo
|
|
150
159
|
|
151
160
|
private
|
152
161
|
|
162
|
+
# Adds a new {Edge} to the dependency graph without checking for
|
163
|
+
# circularity.
|
153
164
|
def add_edge_no_circular(origin, destination, requirement)
|
154
165
|
edge = Edge.new(origin, destination, requirement)
|
155
166
|
origin.outgoing_edges << edge
|
@@ -174,6 +185,7 @@ module Bundler::Molinillo
|
|
174
185
|
attr_accessor :root
|
175
186
|
alias_method :root?, :root
|
176
187
|
|
188
|
+
# Initializes a vertex with the given name and payload.
|
177
189
|
# @param [String] name see {#name}
|
178
190
|
# @param [Object] payload see {#payload}
|
179
191
|
def initialize(name, payload)
|
@@ -240,6 +252,7 @@ module Bundler::Molinillo
|
|
240
252
|
successors.to_set == other.successors.to_set
|
241
253
|
end
|
242
254
|
|
255
|
+
# @param [Vertex] other the other vertex to compare to
|
243
256
|
# @return [Boolean] whether the two vertices are equal, determined
|
244
257
|
# solely by {#name} and {#payload} equality
|
245
258
|
def shallow_eql?(other)
|
@@ -11,6 +11,7 @@ module Bundler::Molinillo
|
|
11
11
|
# @return [Array<Object>] the specifications that depended upon {#dependency}
|
12
12
|
attr_accessor :required_by
|
13
13
|
|
14
|
+
# Initializes a new error with the given missing dependency.
|
14
15
|
# @param [Object] dependency @see {#dependency}
|
15
16
|
# @param [Array<Object>] required_by @see {#required_by}
|
16
17
|
def initialize(dependency, required_by = [])
|
@@ -19,6 +20,8 @@ module Bundler::Molinillo
|
|
19
20
|
super()
|
20
21
|
end
|
21
22
|
|
23
|
+
# The error message for the missing dependency, including the specifications
|
24
|
+
# that had this dependency.
|
22
25
|
def message
|
23
26
|
sources = required_by.map { |r| "`#{r}`" }.join(' and ')
|
24
27
|
message = "Unable to find a specification for `#{dependency}`"
|
@@ -36,6 +39,7 @@ module Bundler::Molinillo
|
|
36
39
|
# [Set<Object>] the dependencies responsible for causing the error
|
37
40
|
attr_reader :dependencies
|
38
41
|
|
42
|
+
# Initializes a new error with the given circular vertices.
|
39
43
|
# @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
|
40
44
|
# that caused the error
|
41
45
|
def initialize(nodes)
|
@@ -50,6 +54,7 @@ module Bundler::Molinillo
|
|
50
54
|
# resolution to fail
|
51
55
|
attr_reader :conflicts
|
52
56
|
|
57
|
+
# Initializes a new error with the given version conflicts.
|
53
58
|
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
|
54
59
|
def initialize(conflicts)
|
55
60
|
pairs = []
|
@@ -38,6 +38,7 @@ module Bundler::Molinillo
|
|
38
38
|
# @return [Array] the dependencies that were explicitly required
|
39
39
|
attr_reader :original_requested
|
40
40
|
|
41
|
+
# Initializes a new resolution.
|
41
42
|
# @param [SpecificationProvider] specification_provider
|
42
43
|
# see {#specification_provider}
|
43
44
|
# @param [UI] resolver_ui see {#resolver_ui}
|
@@ -340,26 +341,36 @@ module Bundler::Molinillo
|
|
340
341
|
# @return [Boolean] Whether the possibility was swapped into {#activated}
|
341
342
|
def attempt_to_swap_possibility
|
342
343
|
swapped = activated.dup
|
343
|
-
swapped.vertex_named(name)
|
344
|
-
|
344
|
+
vertex = swapped.vertex_named(name)
|
345
|
+
vertex.payload = possibility
|
346
|
+
return unless vertex.requirements.
|
345
347
|
all? { |r| requirement_satisfied_by?(r, swapped, possibility) }
|
346
|
-
|
348
|
+
return unless new_spec_satisfied?
|
349
|
+
actual_vertex = activated.vertex_named(name)
|
350
|
+
actual_vertex.payload = possibility
|
351
|
+
fixup_swapped_children(actual_vertex)
|
352
|
+
activate_spec
|
353
|
+
end
|
354
|
+
|
355
|
+
# Ensures there are no orphaned successors to the given {vertex}.
|
356
|
+
# @param [DependencyGraph::Vertex] vertex the vertex to fix up.
|
357
|
+
# @return [void]
|
358
|
+
def fixup_swapped_children(vertex)
|
359
|
+
payload = vertex.payload
|
360
|
+
dep_names = dependencies_for(payload).map(&method(:name_for))
|
361
|
+
vertex.successors.each do |succ|
|
362
|
+
if !dep_names.include?(succ.name) && !succ.root? && succ.predecessors.to_a == [vertex]
|
363
|
+
debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
|
364
|
+
activated.detach_vertex_named(succ.name)
|
365
|
+
end
|
366
|
+
end
|
347
367
|
end
|
348
368
|
|
349
369
|
# Attempts to activate the current {#possibility} (given that it hasn't
|
350
370
|
# already been activated)
|
351
371
|
# @return [void]
|
352
372
|
def attempt_to_activate_new_spec
|
353
|
-
|
354
|
-
locked_requirement = locked_requirement_named(name)
|
355
|
-
requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
|
356
|
-
locked_spec_satisfied = !locked_requirement ||
|
357
|
-
requirement_satisfied_by?(locked_requirement, activated, possibility)
|
358
|
-
debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
|
359
|
-
debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
|
360
|
-
requested_spec_satisfied && locked_spec_satisfied
|
361
|
-
end
|
362
|
-
if satisfied
|
373
|
+
if new_spec_satisfied?
|
363
374
|
activate_spec
|
364
375
|
else
|
365
376
|
create_conflict
|
@@ -367,6 +378,18 @@ module Bundler::Molinillo
|
|
367
378
|
end
|
368
379
|
end
|
369
380
|
|
381
|
+
# @return [Boolean] whether the current spec is satisfied as a new
|
382
|
+
# possibility.
|
383
|
+
def new_spec_satisfied?
|
384
|
+
locked_requirement = locked_requirement_named(name)
|
385
|
+
requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
|
386
|
+
locked_spec_satisfied = !locked_requirement ||
|
387
|
+
requirement_satisfied_by?(locked_requirement, activated, possibility)
|
388
|
+
debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
|
389
|
+
debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
|
390
|
+
requested_spec_satisfied && locked_spec_satisfied
|
391
|
+
end
|
392
|
+
|
370
393
|
# @param [String] requirement_name the spec name to search for
|
371
394
|
# @return [Object] the locked spec named `requirement_name`, if one
|
372
395
|
# is found on {#base}
|
@@ -392,7 +415,7 @@ module Bundler::Molinillo
|
|
392
415
|
# @return [void]
|
393
416
|
def require_nested_dependencies_for(activated_spec)
|
394
417
|
nested_dependencies = dependencies_for(activated_spec)
|
395
|
-
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.
|
418
|
+
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
|
396
419
|
nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
|
397
420
|
|
398
421
|
push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)
|