bundler 2.3.27 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -3
- data/README.md +2 -2
- data/bundler.gemspec +2 -2
- data/exe/bundle +1 -4
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/add.rb +1 -1
- data/lib/bundler/cli/check.rb +1 -1
- data/lib/bundler/cli/common.rb +1 -0
- data/lib/bundler/cli/console.rb +2 -2
- data/lib/bundler/cli/doctor.rb +4 -6
- data/lib/bundler/cli/gem.rb +62 -40
- data/lib/bundler/cli/install.rb +2 -3
- data/lib/bundler/cli/lock.rb +8 -5
- data/lib/bundler/cli/outdated.rb +1 -3
- data/lib/bundler/cli/viz.rb +1 -1
- data/lib/bundler/cli.rb +43 -2
- data/lib/bundler/compact_index_client/cache.rb +1 -1
- data/lib/bundler/compact_index_client/updater.rb +40 -39
- data/lib/bundler/constants.rb +1 -1
- data/lib/bundler/definition.rb +61 -31
- data/lib/bundler/dependency.rb +12 -11
- data/lib/bundler/digest.rb +1 -1
- data/lib/bundler/dsl.rb +1 -1
- data/lib/bundler/env.rb +1 -1
- data/lib/bundler/environment_preserver.rb +1 -0
- data/lib/bundler/errors.rb +1 -11
- data/lib/bundler/fetcher/compact_index.rb +9 -11
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +2 -5
- data/lib/bundler/fetcher.rb +2 -6
- data/lib/bundler/force_platform.rb +18 -0
- data/lib/bundler/friendly_errors.rb +0 -3
- data/lib/bundler/gem_version_promoter.rb +52 -86
- data/lib/bundler/graph.rb +3 -3
- data/lib/bundler/index.rb +5 -18
- data/lib/bundler/injector.rb +1 -1
- data/lib/bundler/inline.rb +2 -2
- data/lib/bundler/installer/parallel_installer.rb +0 -31
- data/lib/bundler/installer.rb +6 -16
- data/lib/bundler/lazy_specification.rb +37 -33
- data/lib/bundler/lockfile_parser.rb +5 -5
- data/lib/bundler/man/bundle-add.1 +1 -1
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +1 -1
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +1 -1
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +27 -37
- data/lib/bundler/man/bundle-gem.1.ronn +5 -5
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-inject.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +1 -30
- data/lib/bundler/man/bundle-install.1.ronn +0 -29
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +1 -1
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +2 -2
- data/lib/bundler/man/bundle-platform.1.ronn +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +1 -1
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle-viz.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/mirror.rb +5 -7
- data/lib/bundler/plugin/index.rb +4 -4
- data/lib/bundler/plugin/installer/rubygems.rb +0 -4
- data/lib/bundler/resolver/base.rb +7 -11
- data/lib/bundler/resolver/candidate.rb +92 -0
- data/lib/bundler/resolver/incompatibility.rb +15 -0
- data/lib/bundler/resolver/package.rb +63 -0
- data/lib/bundler/resolver/root.rb +25 -0
- data/lib/bundler/resolver/spec_group.rb +26 -36
- data/lib/bundler/resolver.rb +285 -277
- data/lib/bundler/rubygems_ext.rb +11 -6
- data/lib/bundler/rubygems_gem_installer.rb +4 -2
- data/lib/bundler/rubygems_integration.rb +1 -9
- data/lib/bundler/runtime.rb +1 -5
- data/lib/bundler/settings.rb +0 -6
- data/lib/bundler/shared_helpers.rb +1 -0
- data/lib/bundler/source/git/git_proxy.rb +190 -67
- data/lib/bundler/source/git.rb +15 -17
- data/lib/bundler/source/metadata.rb +0 -1
- data/lib/bundler/source/path/installer.rb +1 -22
- data/lib/bundler/source/path.rb +5 -5
- data/lib/bundler/source/rubygems.rb +13 -67
- data/lib/bundler/source_list.rb +8 -2
- data/lib/bundler/spec_set.rb +7 -9
- data/lib/bundler/templates/Executable +1 -1
- data/lib/bundler/templates/Executable.bundler +4 -9
- data/lib/bundler/templates/Executable.standalone +2 -0
- data/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +3 -0
- data/lib/bundler/templates/newgem/README.md.tt +6 -4
- data/lib/bundler/templates/newgem/Rakefile.tt +2 -1
- data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
- data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
- data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
- data/lib/bundler/templates/newgem/gitignore.tt +3 -0
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
- data/lib/bundler/ui/shell.rb +35 -12
- data/lib/bundler/ui/silent.rb +21 -5
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -408
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
- data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +151 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +124 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +409 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +240 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
- data/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
- data/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
- data/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +13 -7
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +10 -5
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
- data/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
- data/lib/bundler/vendor/uri/lib/uri.rb +3 -2
- data/lib/bundler/vendored_persistent.rb +1 -33
- data/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
- data/lib/bundler/version.rb +5 -1
- data/lib/bundler/worker.rb +5 -7
- data/lib/bundler.rb +20 -64
- metadata +33 -32
- data/lib/bundler/templates/newgem/travis.yml.tt +0 -6
- data/lib/bundler/vendor/molinillo/LICENSE +0 -9
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
- data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
- data/lib/bundler/vendored_molinillo.rb +0 -4
- data/lib/bundler/version_ranges.rb +0 -122
- /data/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +0 -0
data/lib/bundler/resolver.rb
CHANGED
|
@@ -1,380 +1,388 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Bundler
|
|
4
|
+
#
|
|
5
|
+
# This class implements the interface needed by PubGrub for resolution. It is
|
|
6
|
+
# equivalent to the `PubGrub::BasicPackageSource` class provided by PubGrub by
|
|
7
|
+
# default and used by the most simple PubGrub consumers.
|
|
8
|
+
#
|
|
4
9
|
class Resolver
|
|
5
|
-
require_relative "
|
|
10
|
+
require_relative "vendored_pub_grub"
|
|
6
11
|
require_relative "resolver/base"
|
|
7
|
-
require_relative "resolver/
|
|
12
|
+
require_relative "resolver/package"
|
|
13
|
+
require_relative "resolver/candidate"
|
|
14
|
+
require_relative "resolver/incompatibility"
|
|
15
|
+
require_relative "resolver/root"
|
|
8
16
|
|
|
9
17
|
include GemHelpers
|
|
10
18
|
|
|
11
|
-
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements
|
|
19
|
+
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements)
|
|
12
20
|
@source_requirements = source_requirements
|
|
13
21
|
@base = Resolver::Base.new(base, additional_base_requirements)
|
|
14
|
-
@resolver = Molinillo::Resolver.new(self, self)
|
|
15
|
-
@results_for = {}
|
|
16
|
-
@search_for = {}
|
|
17
|
-
@platforms = platforms
|
|
18
|
-
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
|
|
19
22
|
@gem_version_promoter = gem_version_promoter
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
def start(requirements, exclude_specs: [])
|
|
23
|
-
@metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
|
|
24
|
-
|
|
25
|
+
def start(requirements, packages, exclude_specs: [])
|
|
25
26
|
exclude_specs.each do |spec|
|
|
26
27
|
remove_from_candidates(spec)
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
requirements
|
|
30
|
-
|
|
31
|
-
verify_gemfile_dependencies_are_found!(requirements)
|
|
32
|
-
result = @resolver.resolve(requirements).
|
|
33
|
-
map(&:payload).
|
|
34
|
-
reject {|sg| sg.name.end_with?("\0") }.
|
|
35
|
-
map(&:to_specs).
|
|
36
|
-
flatten
|
|
30
|
+
@requirements = requirements
|
|
31
|
+
@packages = packages
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
rescue Molinillo::VersionConflict => e
|
|
40
|
-
conflicts = e.conflicts
|
|
41
|
-
|
|
42
|
-
deps_to_unlock = conflicts.values.inject([]) do |deps, conflict|
|
|
43
|
-
deps |= conflict.requirement_trees.flatten.map {|req| base_requirements[req.name] }.compact
|
|
44
|
-
end
|
|
33
|
+
root, logger = setup_solver
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
@base.unlock_deps(deps_to_unlock)
|
|
48
|
-
reset_spec_cache
|
|
49
|
-
retry
|
|
50
|
-
end
|
|
35
|
+
Bundler.ui.info "Resolving dependencies...", true
|
|
51
36
|
|
|
52
|
-
|
|
53
|
-
raise VersionConflict.new(conflicts.keys.uniq, message)
|
|
54
|
-
rescue Molinillo::CircularDependencyError => e
|
|
55
|
-
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
|
56
|
-
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
|
57
|
-
" on each other, creating an infinite loop. Please remove" \
|
|
58
|
-
" #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
|
|
59
|
-
" and try again."
|
|
37
|
+
solve_versions(:root => root, :logger => logger)
|
|
60
38
|
end
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
# @param [Integer] depth the current depth of the resolution process.
|
|
67
|
-
# @return [void]
|
|
68
|
-
def debug(depth = 0)
|
|
69
|
-
return unless debug?
|
|
70
|
-
debug_info = yield
|
|
71
|
-
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
|
72
|
-
puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
|
|
73
|
-
end
|
|
40
|
+
def setup_solver
|
|
41
|
+
root = Resolver::Root.new(name_for_explicit_dependency_source)
|
|
42
|
+
root_version = Resolver::Candidate.new(0)
|
|
74
43
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
ENV["BUNDLER_DEBUG_RESOLVER"] ||
|
|
79
|
-
ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
|
|
80
|
-
ENV["DEBUG_RESOLVER"] ||
|
|
81
|
-
ENV["DEBUG_RESOLVER_TREE"] ||
|
|
82
|
-
false
|
|
83
|
-
end
|
|
44
|
+
@all_specs = Hash.new do |specs, name|
|
|
45
|
+
specs[name] = source_for(name).specs.search(name).sort_by {|s| [s.version, s.platform.to_s] }
|
|
46
|
+
end
|
|
84
47
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
48
|
+
@sorted_versions = Hash.new do |candidates, package|
|
|
49
|
+
candidates[package] = if package.root?
|
|
50
|
+
[root_version]
|
|
51
|
+
else
|
|
52
|
+
all_versions_for(package).sort
|
|
53
|
+
end
|
|
54
|
+
end
|
|
88
55
|
|
|
89
|
-
|
|
90
|
-
Bundler.ui.info ""
|
|
91
|
-
end
|
|
56
|
+
root_dependencies = prepare_dependencies(@requirements, @packages)
|
|
92
57
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
58
|
+
@cached_dependencies = Hash.new do |dependencies, package|
|
|
59
|
+
dependencies[package] = if package.root?
|
|
60
|
+
{ root_version => root_dependencies }
|
|
61
|
+
else
|
|
62
|
+
Hash.new do |versions, version|
|
|
63
|
+
versions[version] = to_dependency_hash(version.dependencies, @packages)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
96
67
|
|
|
97
|
-
|
|
68
|
+
logger = Bundler::UI::Shell.new
|
|
69
|
+
logger.level = debug? ? "debug" : "warn"
|
|
98
70
|
|
|
99
|
-
|
|
100
|
-
specification.dependencies_for_activated_platforms
|
|
71
|
+
[root, logger]
|
|
101
72
|
end
|
|
102
73
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
@gem_version_promoter.sort_versions(dependency, results).group_by(&:version).reduce([]) do |groups, (_, specs)|
|
|
113
|
-
relevant_platforms = dep_platforms.select {|platform| specs.any? {|spec| spec.match_platform(platform) } }
|
|
114
|
-
next groups unless relevant_platforms.any?
|
|
115
|
-
|
|
116
|
-
ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
|
|
117
|
-
if ruby_specs.any?
|
|
118
|
-
spec_group_ruby = SpecGroup.new(ruby_specs, [Gem::Platform::RUBY])
|
|
119
|
-
spec_group_ruby.force_ruby_platform = dependency.force_ruby_platform
|
|
120
|
-
groups << spec_group_ruby
|
|
121
|
-
end
|
|
74
|
+
def solve_versions(root:, logger:)
|
|
75
|
+
solver = PubGrub::VersionSolver.new(:source => self, :root => root, :logger => logger)
|
|
76
|
+
result = solver.solve
|
|
77
|
+
result.map {|package, version| version.to_specs(package) }.flatten.uniq
|
|
78
|
+
rescue PubGrub::SolveFailure => e
|
|
79
|
+
incompatibility = e.incompatibility
|
|
80
|
+
|
|
81
|
+
names_to_unlock = []
|
|
82
|
+
extended_explanation = nil
|
|
122
83
|
|
|
123
|
-
|
|
84
|
+
while incompatibility.conflict?
|
|
85
|
+
cause = incompatibility.cause
|
|
86
|
+
incompatibility = cause.incompatibility
|
|
124
87
|
|
|
125
|
-
|
|
126
|
-
|
|
88
|
+
incompatibility.terms.each do |term|
|
|
89
|
+
name = term.package.name
|
|
90
|
+
names_to_unlock << name if base_requirements[name]
|
|
127
91
|
|
|
128
|
-
|
|
129
|
-
|
|
92
|
+
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(PubGrub::Incompatibility::NoVersions) }
|
|
93
|
+
next unless no_versions_incompat
|
|
130
94
|
|
|
131
|
-
|
|
95
|
+
extended_explanation = no_versions_incompat.extended_explanation
|
|
132
96
|
end
|
|
133
97
|
end
|
|
134
|
-
end
|
|
135
98
|
|
|
136
|
-
|
|
137
|
-
source_for(dependency.name).specs
|
|
138
|
-
end
|
|
99
|
+
names_to_unlock.uniq!
|
|
139
100
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
end
|
|
101
|
+
if names_to_unlock.any?
|
|
102
|
+
Bundler.ui.debug "Found conflicts with locked dependencies. Retrying with #{names_to_unlock.join(", ")} unlocked...", true
|
|
143
103
|
|
|
144
|
-
|
|
145
|
-
@results_for[dependency] ||= index_for(dependency).search(dependency)
|
|
146
|
-
end
|
|
104
|
+
@base.unlock_names(names_to_unlock)
|
|
147
105
|
|
|
148
|
-
|
|
149
|
-
dependency.name
|
|
150
|
-
end
|
|
106
|
+
root, logger = setup_solver
|
|
151
107
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
rescue StandardError
|
|
155
|
-
"Gemfile"
|
|
156
|
-
end
|
|
108
|
+
retry
|
|
109
|
+
end
|
|
157
110
|
|
|
158
|
-
|
|
159
|
-
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
|
160
|
-
end
|
|
111
|
+
explanation = e.message
|
|
161
112
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
vertex = activated.vertex_named(name)
|
|
166
|
-
[
|
|
167
|
-
@base[name].any? ? 0 : 1,
|
|
168
|
-
vertex.payload ? 0 : 1,
|
|
169
|
-
vertex.root? ? 0 : 1,
|
|
170
|
-
amount_constrained(dependency),
|
|
171
|
-
conflicts[name] ? 0 : 1,
|
|
172
|
-
vertex.payload ? 0 : search_for(dependency).count,
|
|
173
|
-
]
|
|
113
|
+
if extended_explanation
|
|
114
|
+
explanation << "\n\n"
|
|
115
|
+
explanation << extended_explanation
|
|
174
116
|
end
|
|
117
|
+
|
|
118
|
+
raise SolveFailure.new(explanation)
|
|
175
119
|
end
|
|
176
120
|
|
|
177
|
-
|
|
121
|
+
def parse_dependency(package, dependency)
|
|
122
|
+
range = if repository_for(package).is_a?(Source::Gemspec)
|
|
123
|
+
PubGrub::VersionRange.any
|
|
124
|
+
else
|
|
125
|
+
requirement_to_range(dependency)
|
|
126
|
+
end
|
|
178
127
|
|
|
179
|
-
|
|
180
|
-
@base.base_requirements
|
|
128
|
+
PubGrub::VersionConstraint.new(package, :range => range)
|
|
181
129
|
end
|
|
182
130
|
|
|
183
|
-
def
|
|
184
|
-
@
|
|
131
|
+
def versions_for(package, range=VersionRange.any)
|
|
132
|
+
versions = range.select_versions(@sorted_versions[package])
|
|
133
|
+
|
|
134
|
+
sort_versions(package, versions)
|
|
185
135
|
end
|
|
186
136
|
|
|
187
|
-
def
|
|
188
|
-
|
|
137
|
+
def no_versions_incompatibility_for(package, unsatisfied_term)
|
|
138
|
+
cause = PubGrub::Incompatibility::NoVersions.new(unsatisfied_term)
|
|
139
|
+
name = package.name
|
|
140
|
+
constraint = unsatisfied_term.constraint
|
|
141
|
+
constraint_string = constraint.constraint_string
|
|
142
|
+
requirements = constraint_string.split(" OR ").map {|req| Gem::Requirement.new(req.split(",")) }
|
|
143
|
+
|
|
144
|
+
if name == "bundler"
|
|
145
|
+
custom_explanation = "the current Bundler version (#{Bundler::VERSION}) does not satisfy #{constraint}"
|
|
146
|
+
extended_explanation = bundler_not_found_message(requirements)
|
|
147
|
+
else
|
|
148
|
+
specs_matching_other_platforms = filter_matching_specs(@all_specs[name], requirements)
|
|
189
149
|
|
|
190
|
-
|
|
191
|
-
|
|
150
|
+
platforms_explanation = specs_matching_other_platforms.any? ? " for any resolution platforms (#{package.platforms.join(", ")})" : ""
|
|
151
|
+
custom_explanation = "#{constraint} could not be found in #{repository_for(package)}#{platforms_explanation}"
|
|
192
152
|
|
|
193
|
-
|
|
153
|
+
label = "#{name} (#{constraint_string})"
|
|
154
|
+
extended_explanation = other_specs_matching_message(specs_matching_other_platforms, label) if specs_matching_other_platforms.any?
|
|
194
155
|
end
|
|
195
156
|
|
|
196
|
-
|
|
157
|
+
Incompatibility.new([unsatisfied_term], :cause => cause, :custom_explanation => custom_explanation, :extended_explanation => extended_explanation)
|
|
197
158
|
end
|
|
198
159
|
|
|
199
|
-
def
|
|
200
|
-
|
|
201
|
-
|
|
160
|
+
def debug?
|
|
161
|
+
ENV["BUNDLER_DEBUG_RESOLVER"] ||
|
|
162
|
+
ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
|
|
163
|
+
ENV["DEBUG_RESOLVER"] ||
|
|
164
|
+
ENV["DEBUG_RESOLVER_TREE"] ||
|
|
165
|
+
false
|
|
202
166
|
end
|
|
203
167
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
@amount_constrained[dependency.name] ||= if (base = @base[dependency.name]) && !base.empty?
|
|
213
|
-
dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
|
|
214
|
-
else
|
|
215
|
-
all = index_for(dependency).search(dependency.name).size
|
|
168
|
+
def incompatibilities_for(package, version)
|
|
169
|
+
package_deps = @cached_dependencies[package]
|
|
170
|
+
sorted_versions = @sorted_versions[package]
|
|
171
|
+
package_deps[version].map do |dep_package, dep_constraint|
|
|
172
|
+
if package == dep_package
|
|
173
|
+
cause = PubGrub::Incompatibility::CircularDependency.new(dep_package, dep_constraint.constraint_string)
|
|
174
|
+
return [PubGrub::Incompatibility.new([PubGrub::Term.new(dep_constraint, true)], :cause => cause)]
|
|
175
|
+
end
|
|
216
176
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
177
|
+
low = high = sorted_versions.index(version)
|
|
178
|
+
|
|
179
|
+
# find version low such that all >= low share the same dep
|
|
180
|
+
while low > 0 && package_deps[sorted_versions[low - 1]][dep_package] == dep_constraint
|
|
181
|
+
low -= 1
|
|
182
|
+
end
|
|
183
|
+
low =
|
|
184
|
+
if low == 0
|
|
185
|
+
nil
|
|
186
|
+
else
|
|
187
|
+
sorted_versions[low]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# find version high such that all < high share the same dep
|
|
191
|
+
while high < sorted_versions.length && package_deps[sorted_versions[high]][dep_package] == dep_constraint
|
|
192
|
+
high += 1
|
|
193
|
+
end
|
|
194
|
+
high =
|
|
195
|
+
if high == sorted_versions.length
|
|
196
|
+
nil
|
|
197
|
+
else
|
|
198
|
+
sorted_versions[high]
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
range = PubGrub::VersionRange.new(:min => low, :max => high, :include_min => true)
|
|
202
|
+
|
|
203
|
+
self_constraint = PubGrub::VersionConstraint.new(package, :range => range)
|
|
204
|
+
|
|
205
|
+
dep_term = PubGrub::Term.new(dep_constraint, false)
|
|
206
|
+
self_term = PubGrub::Term.new(self_constraint, true)
|
|
207
|
+
|
|
208
|
+
custom_explanation = if dep_package.meta? && package.root?
|
|
209
|
+
"current #{dep_package} version is #{dep_constraint.constraint_string}"
|
|
223
210
|
end
|
|
211
|
+
|
|
212
|
+
PubGrub::Incompatibility.new([self_term, dep_term], :cause => :dependency, :custom_explanation => custom_explanation)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def all_versions_for(package)
|
|
217
|
+
name = package.name
|
|
218
|
+
results = (@base[name] + @all_specs[name]).uniq(&:full_name)
|
|
219
|
+
locked_requirement = base_requirements[name]
|
|
220
|
+
results = filter_matching_specs(results, locked_requirement) if locked_requirement
|
|
221
|
+
|
|
222
|
+
versions = results.group_by(&:version).reduce([]) do |groups, (version, specs)|
|
|
223
|
+
platform_specs = package.platforms.flat_map {|platform| select_best_platform_match(specs, platform) }
|
|
224
|
+
next groups if platform_specs.empty?
|
|
225
|
+
|
|
226
|
+
ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
|
|
227
|
+
groups << Resolver::Candidate.new(version, :specs => ruby_specs) if ruby_specs.any?
|
|
228
|
+
|
|
229
|
+
next groups if platform_specs == ruby_specs
|
|
230
|
+
|
|
231
|
+
groups << Resolver::Candidate.new(version, :specs => platform_specs)
|
|
232
|
+
|
|
233
|
+
groups
|
|
224
234
|
end
|
|
235
|
+
|
|
236
|
+
sort_versions(package, versions)
|
|
225
237
|
end
|
|
226
238
|
|
|
227
|
-
def
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
next requirement if name == "bundler"
|
|
231
|
-
next if requirement.gem_platforms(@platforms).empty?
|
|
232
|
-
next requirement unless search_for(requirement).empty?
|
|
233
|
-
next unless requirement.current_platform?
|
|
239
|
+
def source_for(name)
|
|
240
|
+
@source_requirements[name] || @source_requirements[:default]
|
|
241
|
+
end
|
|
234
242
|
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
def name_for_explicit_dependency_source
|
|
244
|
+
Bundler.default_gemfile.basename.to_s
|
|
245
|
+
rescue StandardError
|
|
246
|
+
"Gemfile"
|
|
237
247
|
end
|
|
238
248
|
|
|
239
|
-
def
|
|
240
|
-
|
|
249
|
+
def raise_not_found!(package)
|
|
250
|
+
name = package.name
|
|
251
|
+
source = source_for(name)
|
|
252
|
+
specs = @all_specs[name]
|
|
241
253
|
matching_part = name
|
|
242
|
-
requirement_label = SharedHelpers.pretty_dependency(
|
|
254
|
+
requirement_label = SharedHelpers.pretty_dependency(package.dependency)
|
|
243
255
|
cache_message = begin
|
|
244
256
|
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
245
257
|
rescue GemfileNotFound
|
|
246
258
|
nil
|
|
247
259
|
end
|
|
248
|
-
specs_matching_requirement = specs.
|
|
260
|
+
specs_matching_requirement = filter_matching_specs(specs, package.dependency.requirement)
|
|
249
261
|
|
|
250
262
|
if specs_matching_requirement.any?
|
|
251
263
|
specs = specs_matching_requirement
|
|
252
264
|
matching_part = requirement_label
|
|
253
|
-
platforms =
|
|
265
|
+
platforms = package.platforms
|
|
254
266
|
platform_label = platforms.size == 1 ? "platform '#{platforms.first}" : "platforms '#{platforms.join("', '")}"
|
|
255
267
|
requirement_label = "#{requirement_label}' with #{platform_label}"
|
|
256
268
|
end
|
|
257
269
|
|
|
258
|
-
message = String.new("Could not find gem '#{requirement_label}'
|
|
270
|
+
message = String.new("Could not find gem '#{requirement_label}' in #{source}#{cache_message}.\n")
|
|
259
271
|
|
|
260
272
|
if specs.any?
|
|
261
|
-
message << "\
|
|
262
|
-
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
273
|
+
message << "\n#{other_specs_matching_message(specs, matching_part)}"
|
|
263
274
|
end
|
|
264
275
|
|
|
265
|
-
message
|
|
276
|
+
raise GemNotFound, message
|
|
266
277
|
end
|
|
267
278
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
279
|
+
private
|
|
280
|
+
|
|
281
|
+
def filter_matching_specs(specs, requirements)
|
|
282
|
+
Array(requirements).flat_map do |requirement|
|
|
283
|
+
specs.select {| spec| requirement_satisfied_by?(requirement, spec) }
|
|
284
|
+
end
|
|
285
|
+
end
|
|
271
286
|
|
|
272
|
-
|
|
273
|
-
|
|
287
|
+
def requirement_satisfied_by?(requirement, spec)
|
|
288
|
+
requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def sort_versions(package, versions)
|
|
292
|
+
if versions.size > 1
|
|
293
|
+
@gem_version_promoter.sort_versions(package, versions).reverse
|
|
274
294
|
else
|
|
275
|
-
|
|
276
|
-
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
|
277
|
-
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
|
278
|
-
end
|
|
295
|
+
versions
|
|
279
296
|
end
|
|
297
|
+
end
|
|
280
298
|
|
|
281
|
-
|
|
299
|
+
def repository_for(package)
|
|
300
|
+
source_for(package.name)
|
|
301
|
+
end
|
|
282
302
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
303
|
+
def base_requirements
|
|
304
|
+
@base.base_requirements
|
|
305
|
+
end
|
|
286
306
|
|
|
287
|
-
|
|
288
|
-
|
|
307
|
+
def remove_from_candidates(spec)
|
|
308
|
+
@base.delete(spec)
|
|
309
|
+
end
|
|
289
310
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
311
|
+
def prepare_dependencies(requirements, packages)
|
|
312
|
+
to_dependency_hash(requirements, packages).map do |dep_package, dep_constraint|
|
|
313
|
+
name = dep_package.name
|
|
314
|
+
next if dep_package.platforms.empty?
|
|
315
|
+
next [dep_package, dep_constraint] if name == "bundler"
|
|
316
|
+
next [dep_package, dep_constraint] unless versions_for(dep_package, dep_constraint.range).empty?
|
|
317
|
+
next unless dep_package.current_platform?
|
|
297
318
|
|
|
298
|
-
|
|
319
|
+
raise_not_found!(dep_package)
|
|
320
|
+
end.compact.to_h
|
|
321
|
+
end
|
|
299
322
|
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
def other_specs_matching_message(specs, requirement)
|
|
324
|
+
message = String.new("The source contains the following gems matching '#{requirement}':\n")
|
|
325
|
+
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
326
|
+
message
|
|
327
|
+
end
|
|
302
328
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
end
|
|
329
|
-
t << %(\n)
|
|
330
|
-
depth += 1
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
t
|
|
334
|
-
end.compact.join("\n")
|
|
335
|
-
else
|
|
336
|
-
o = String.new
|
|
337
|
-
end
|
|
329
|
+
def requirement_to_range(requirement)
|
|
330
|
+
ranges = requirement.requirements.map do |(op, version)|
|
|
331
|
+
ver = Resolver::Candidate.new(version)
|
|
332
|
+
|
|
333
|
+
case op
|
|
334
|
+
when "~>"
|
|
335
|
+
name = "~> #{ver}"
|
|
336
|
+
bump = Resolver::Candidate.new(version.bump.to_s + ".A")
|
|
337
|
+
PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true)
|
|
338
|
+
when ">"
|
|
339
|
+
PubGrub::VersionRange.new(:min => ver)
|
|
340
|
+
when ">="
|
|
341
|
+
PubGrub::VersionRange.new(:min => ver, :include_min => true)
|
|
342
|
+
when "<"
|
|
343
|
+
PubGrub::VersionRange.new(:max => ver)
|
|
344
|
+
when "<="
|
|
345
|
+
PubGrub::VersionRange.new(:max => ver, :include_max => true)
|
|
346
|
+
when "="
|
|
347
|
+
PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true)
|
|
348
|
+
when "!="
|
|
349
|
+
PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true).invert
|
|
350
|
+
else
|
|
351
|
+
raise "bad version specifier: #{op}"
|
|
352
|
+
end
|
|
353
|
+
end
|
|
338
354
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if other_bundler_required
|
|
347
|
-
o << "\n\n"
|
|
348
|
-
|
|
349
|
-
candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
|
|
350
|
-
if candidate_specs.any?
|
|
351
|
-
target_version = candidate_specs.last.version
|
|
352
|
-
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
|
353
|
-
o << "Your bundle requires a different version of Bundler than the one you're running.\n"
|
|
354
|
-
o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
|
|
355
|
-
else
|
|
356
|
-
o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
357
|
-
end
|
|
358
|
-
end
|
|
359
|
-
elsif name.end_with?("\0")
|
|
360
|
-
o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n)
|
|
361
|
-
elsif !conflict.existing
|
|
362
|
-
o << "\n"
|
|
363
|
-
|
|
364
|
-
relevant_source = conflict.requirement.source || source_for(name)
|
|
365
|
-
|
|
366
|
-
extra_message = if trees.first.size > 1
|
|
367
|
-
", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}',"
|
|
368
|
-
else
|
|
369
|
-
""
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
|
|
373
|
-
end
|
|
355
|
+
ranges.inject(&:intersect)
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def to_dependency_hash(dependencies, packages)
|
|
359
|
+
dependencies.inject({}) do |deps, dep|
|
|
360
|
+
package = packages[dep.name]
|
|
374
361
|
|
|
375
|
-
|
|
362
|
+
current_req = deps[package]
|
|
363
|
+
new_req = parse_dependency(package, dep.requirement)
|
|
364
|
+
|
|
365
|
+
deps[package] = if current_req
|
|
366
|
+
current_req.intersect(new_req)
|
|
367
|
+
else
|
|
368
|
+
new_req
|
|
376
369
|
end
|
|
377
|
-
|
|
370
|
+
|
|
371
|
+
deps
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def bundler_not_found_message(conflict_dependencies)
|
|
376
|
+
candidate_specs = filter_matching_specs(source_for(:default_bundler).specs.search("bundler"), conflict_dependencies)
|
|
377
|
+
|
|
378
|
+
if candidate_specs.any?
|
|
379
|
+
target_version = candidate_specs.last.version
|
|
380
|
+
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
|
381
|
+
"Your bundle requires a different version of Bundler than the one you're running.\n" \
|
|
382
|
+
"Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
|
|
383
|
+
else
|
|
384
|
+
"Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
385
|
+
end
|
|
378
386
|
end
|
|
379
387
|
end
|
|
380
388
|
end
|