bundler 2.3.26 → 2.4.5
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 +110 -1
- 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/open.rb +6 -4
- data/lib/bundler/cli/outdated.rb +1 -3
- data/lib/bundler/cli/viz.rb +1 -1
- data/lib/bundler/cli.rb +44 -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 +87 -51
- data/lib/bundler/dependency.rb +12 -11
- data/lib/bundler/digest.rb +1 -1
- data/lib/bundler/dsl.rb +3 -3
- 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 -13
- 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 +9 -23
- 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 +2 -2
- data/lib/bundler/man/bundle-config.1.ronn +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 +5 -5
- data/lib/bundler/man/bundle-exec.1.ronn +5 -5
- 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 +22 -2
- data/lib/bundler/man/bundle-open.1.ronn +9 -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 +42 -15
- data/lib/bundler/resolver/candidate.rb +94 -0
- data/lib/bundler/resolver/incompatibility.rb +15 -0
- data/lib/bundler/resolver/package.rb +72 -0
- data/lib/bundler/resolver/root.rb +25 -0
- data/lib/bundler/resolver/spec_group.rb +26 -36
- data/lib/bundler/resolver.rb +314 -278
- 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 +193 -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 +14 -68
- 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.rb.tt → extconf-c.rb.tt} +0 -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 +128 -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/resolver.rb
CHANGED
|
@@ -1,380 +1,416 @@
|
|
|
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/candidate"
|
|
13
|
+
require_relative "resolver/incompatibility"
|
|
14
|
+
require_relative "resolver/root"
|
|
8
15
|
|
|
9
16
|
include GemHelpers
|
|
10
17
|
|
|
11
|
-
def initialize(
|
|
12
|
-
@source_requirements = source_requirements
|
|
13
|
-
@base =
|
|
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]
|
|
18
|
+
def initialize(base, gem_version_promoter)
|
|
19
|
+
@source_requirements = base.source_requirements
|
|
20
|
+
@base = base
|
|
19
21
|
@gem_version_promoter = gem_version_promoter
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
def start
|
|
23
|
-
@
|
|
24
|
+
def start
|
|
25
|
+
@requirements = @base.requirements
|
|
26
|
+
@packages = @base.packages
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
remove_from_candidates(spec)
|
|
27
|
-
end
|
|
28
|
+
root, logger = setup_solver
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
Bundler.ui.info "Resolving dependencies...", true
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
map(&:payload).
|
|
34
|
-
reject {|sg| sg.name.end_with?("\0") }.
|
|
35
|
-
map(&:to_specs).
|
|
36
|
-
flatten
|
|
32
|
+
solve_versions(:root => root, :logger => logger)
|
|
33
|
+
end
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
def setup_solver
|
|
36
|
+
root = Resolver::Root.new(name_for_explicit_dependency_source)
|
|
37
|
+
root_version = Resolver::Candidate.new(0)
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
@all_specs = Hash.new do |specs, name|
|
|
40
|
+
specs[name] = source_for(name).specs.search(name).sort_by {|s| [s.version, s.platform.to_s] }
|
|
44
41
|
end
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
@sorted_versions = Hash.new do |candidates, package|
|
|
44
|
+
candidates[package] = if package.root?
|
|
45
|
+
[root_version]
|
|
46
|
+
else
|
|
47
|
+
all_versions_for(package).sort
|
|
48
|
+
end
|
|
50
49
|
end
|
|
51
50
|
|
|
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."
|
|
60
|
-
end
|
|
51
|
+
root_dependencies = prepare_dependencies(@requirements, @packages)
|
|
61
52
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
53
|
+
@cached_dependencies = Hash.new do |dependencies, package|
|
|
54
|
+
dependencies[package] = if package.root?
|
|
55
|
+
{ root_version => root_dependencies }
|
|
56
|
+
else
|
|
57
|
+
Hash.new do |versions, version|
|
|
58
|
+
versions[version] = to_dependency_hash(version.dependencies, @packages)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
74
62
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@debug_mode =
|
|
78
|
-
ENV["BUNDLER_DEBUG_RESOLVER"] ||
|
|
79
|
-
ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
|
|
80
|
-
ENV["DEBUG_RESOLVER"] ||
|
|
81
|
-
ENV["DEBUG_RESOLVER_TREE"] ||
|
|
82
|
-
false
|
|
83
|
-
end
|
|
63
|
+
logger = Bundler::UI::Shell.new
|
|
64
|
+
logger.level = debug? ? "debug" : "warn"
|
|
84
65
|
|
|
85
|
-
|
|
86
|
-
Bundler.ui.info "Resolving dependencies...", debug?
|
|
66
|
+
[root, logger]
|
|
87
67
|
end
|
|
88
68
|
|
|
89
|
-
def
|
|
90
|
-
|
|
91
|
-
|
|
69
|
+
def solve_versions(root:, logger:)
|
|
70
|
+
solver = PubGrub::VersionSolver.new(:source => self, :root => root, :logger => logger)
|
|
71
|
+
result = solver.solve
|
|
72
|
+
result.map {|package, version| version.to_specs(package) }.flatten.uniq
|
|
73
|
+
rescue PubGrub::SolveFailure => e
|
|
74
|
+
incompatibility = e.incompatibility
|
|
92
75
|
|
|
93
|
-
|
|
94
|
-
Bundler.ui.info ".", false unless debug?
|
|
95
|
-
end
|
|
76
|
+
names_to_unlock, names_to_allow_prereleases_for, extended_explanation = find_names_to_relax(incompatibility)
|
|
96
77
|
|
|
97
|
-
|
|
78
|
+
names_to_relax = names_to_unlock + names_to_allow_prereleases_for
|
|
98
79
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
80
|
+
if names_to_relax.any?
|
|
81
|
+
if names_to_unlock.any?
|
|
82
|
+
Bundler.ui.debug "Found conflicts with locked dependencies. Will retry with #{names_to_unlock.join(", ")} unlocked...", true
|
|
102
83
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
name = dependency.name
|
|
106
|
-
locked_results = @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) }
|
|
107
|
-
locked_requirement = base_requirements[name]
|
|
108
|
-
results = results_for(dependency) + locked_results
|
|
109
|
-
results = results.select {|spec| requirement_satisfied_by?(locked_requirement, nil, spec) } if locked_requirement
|
|
110
|
-
dep_platforms = dependency.gem_platforms(@platforms)
|
|
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
|
|
84
|
+
@base.unlock_names(names_to_unlock)
|
|
85
|
+
end
|
|
122
86
|
|
|
123
|
-
|
|
87
|
+
if names_to_allow_prereleases_for.any?
|
|
88
|
+
Bundler.ui.debug "Found conflicts with dependencies with prereleases. Will retrying considering prereleases for #{names_to_allow_prereleases_for.join(", ")}...", true
|
|
124
89
|
|
|
125
|
-
|
|
126
|
-
|
|
90
|
+
@base.include_prereleases(names_to_allow_prereleases_for)
|
|
91
|
+
end
|
|
127
92
|
|
|
128
|
-
|
|
129
|
-
groups << spec_group
|
|
93
|
+
root, logger = setup_solver
|
|
130
94
|
|
|
131
|
-
|
|
132
|
-
|
|
95
|
+
Bundler.ui.debug "Retrying resolution...", true
|
|
96
|
+
retry
|
|
133
97
|
end
|
|
134
|
-
end
|
|
135
98
|
|
|
136
|
-
|
|
137
|
-
source_for(dependency.name).specs
|
|
138
|
-
end
|
|
99
|
+
explanation = e.message
|
|
139
100
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
101
|
+
if extended_explanation
|
|
102
|
+
explanation << "\n\n"
|
|
103
|
+
explanation << extended_explanation
|
|
104
|
+
end
|
|
143
105
|
|
|
144
|
-
|
|
145
|
-
@results_for[dependency] ||= index_for(dependency).search(dependency)
|
|
106
|
+
raise SolveFailure.new(explanation)
|
|
146
107
|
end
|
|
147
108
|
|
|
148
|
-
def
|
|
149
|
-
|
|
150
|
-
|
|
109
|
+
def find_names_to_relax(incompatibility)
|
|
110
|
+
names_to_unlock = []
|
|
111
|
+
names_to_allow_prereleases_for = []
|
|
112
|
+
extended_explanation = nil
|
|
151
113
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"Gemfile"
|
|
156
|
-
end
|
|
114
|
+
while incompatibility.conflict?
|
|
115
|
+
cause = incompatibility.cause
|
|
116
|
+
incompatibility = cause.incompatibility
|
|
157
117
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
118
|
+
incompatibility.terms.each do |term|
|
|
119
|
+
package = term.package
|
|
120
|
+
name = package.name
|
|
121
|
+
|
|
122
|
+
if base_requirements[name]
|
|
123
|
+
names_to_unlock << name
|
|
124
|
+
elsif package.ignores_prereleases?
|
|
125
|
+
names_to_allow_prereleases_for << name
|
|
126
|
+
end
|
|
161
127
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
]
|
|
128
|
+
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(PubGrub::Incompatibility::NoVersions) }
|
|
129
|
+
next unless no_versions_incompat
|
|
130
|
+
|
|
131
|
+
extended_explanation = no_versions_incompat.extended_explanation
|
|
132
|
+
end
|
|
174
133
|
end
|
|
134
|
+
|
|
135
|
+
[names_to_unlock.uniq, names_to_allow_prereleases_for.uniq, extended_explanation]
|
|
175
136
|
end
|
|
176
137
|
|
|
177
|
-
|
|
138
|
+
def parse_dependency(package, dependency)
|
|
139
|
+
range = if repository_for(package).is_a?(Source::Gemspec)
|
|
140
|
+
PubGrub::VersionRange.any
|
|
141
|
+
else
|
|
142
|
+
requirement_to_range(dependency)
|
|
143
|
+
end
|
|
178
144
|
|
|
179
|
-
|
|
180
|
-
@base.base_requirements
|
|
145
|
+
PubGrub::VersionConstraint.new(package, :range => range)
|
|
181
146
|
end
|
|
182
147
|
|
|
183
|
-
def
|
|
184
|
-
@
|
|
148
|
+
def versions_for(package, range=VersionRange.any)
|
|
149
|
+
versions = range.select_versions(@sorted_versions[package])
|
|
150
|
+
|
|
151
|
+
sort_versions(package, versions)
|
|
185
152
|
end
|
|
186
153
|
|
|
187
|
-
def
|
|
188
|
-
|
|
154
|
+
def no_versions_incompatibility_for(package, unsatisfied_term)
|
|
155
|
+
cause = PubGrub::Incompatibility::NoVersions.new(unsatisfied_term)
|
|
156
|
+
name = package.name
|
|
157
|
+
constraint = unsatisfied_term.constraint
|
|
158
|
+
constraint_string = constraint.constraint_string
|
|
159
|
+
requirements = constraint_string.split(" OR ").map {|req| Gem::Requirement.new(req.split(",")) }
|
|
160
|
+
|
|
161
|
+
if name == "bundler"
|
|
162
|
+
custom_explanation = "the current Bundler version (#{Bundler::VERSION}) does not satisfy #{constraint}"
|
|
163
|
+
extended_explanation = bundler_not_found_message(requirements)
|
|
164
|
+
else
|
|
165
|
+
specs_matching_other_platforms = filter_matching_specs(@all_specs[name], requirements)
|
|
189
166
|
|
|
190
|
-
|
|
191
|
-
|
|
167
|
+
platforms_explanation = specs_matching_other_platforms.any? ? " for any resolution platforms (#{package.platforms.join(", ")})" : ""
|
|
168
|
+
custom_explanation = "#{constraint} could not be found in #{repository_for(package)}#{platforms_explanation}"
|
|
192
169
|
|
|
193
|
-
|
|
170
|
+
label = "#{name} (#{constraint_string})"
|
|
171
|
+
extended_explanation = other_specs_matching_message(specs_matching_other_platforms, label) if specs_matching_other_platforms.any?
|
|
194
172
|
end
|
|
195
173
|
|
|
196
|
-
|
|
174
|
+
Incompatibility.new([unsatisfied_term], :cause => cause, :custom_explanation => custom_explanation, :extended_explanation => extended_explanation)
|
|
197
175
|
end
|
|
198
176
|
|
|
199
|
-
def
|
|
200
|
-
|
|
201
|
-
|
|
177
|
+
def debug?
|
|
178
|
+
ENV["BUNDLER_DEBUG_RESOLVER"] ||
|
|
179
|
+
ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
|
|
180
|
+
ENV["DEBUG_RESOLVER"] ||
|
|
181
|
+
ENV["DEBUG_RESOLVER_TREE"] ||
|
|
182
|
+
false
|
|
202
183
|
end
|
|
203
184
|
|
|
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
|
|
185
|
+
def incompatibilities_for(package, version)
|
|
186
|
+
package_deps = @cached_dependencies[package]
|
|
187
|
+
sorted_versions = @sorted_versions[package]
|
|
188
|
+
package_deps[version].map do |dep_package, dep_constraint|
|
|
189
|
+
if package == dep_package
|
|
190
|
+
cause = PubGrub::Incompatibility::CircularDependency.new(dep_package, dep_constraint.constraint_string)
|
|
191
|
+
return [PubGrub::Incompatibility.new([PubGrub::Term.new(dep_constraint, true)], :cause => cause)]
|
|
192
|
+
end
|
|
216
193
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
194
|
+
low = high = sorted_versions.index(version)
|
|
195
|
+
|
|
196
|
+
# find version low such that all >= low share the same dep
|
|
197
|
+
while low > 0 && package_deps[sorted_versions[low - 1]][dep_package] == dep_constraint
|
|
198
|
+
low -= 1
|
|
199
|
+
end
|
|
200
|
+
low =
|
|
201
|
+
if low == 0
|
|
202
|
+
nil
|
|
203
|
+
else
|
|
204
|
+
sorted_versions[low]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# find version high such that all < high share the same dep
|
|
208
|
+
while high < sorted_versions.length && package_deps[sorted_versions[high]][dep_package] == dep_constraint
|
|
209
|
+
high += 1
|
|
223
210
|
end
|
|
211
|
+
high =
|
|
212
|
+
if high == sorted_versions.length
|
|
213
|
+
nil
|
|
214
|
+
else
|
|
215
|
+
sorted_versions[high]
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
range = PubGrub::VersionRange.new(:min => low, :max => high, :include_min => true)
|
|
219
|
+
|
|
220
|
+
self_constraint = PubGrub::VersionConstraint.new(package, :range => range)
|
|
221
|
+
|
|
222
|
+
dep_term = PubGrub::Term.new(dep_constraint, false)
|
|
223
|
+
self_term = PubGrub::Term.new(self_constraint, true)
|
|
224
|
+
|
|
225
|
+
custom_explanation = if dep_package.meta? && package.root?
|
|
226
|
+
"current #{dep_package} version is #{dep_constraint.constraint_string}"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
PubGrub::Incompatibility.new([self_term, dep_term], :cause => :dependency, :custom_explanation => custom_explanation)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def all_versions_for(package)
|
|
234
|
+
name = package.name
|
|
235
|
+
results = (@base[name] + filter_prereleases(@all_specs[name], package)).uniq {|spec| [spec.version.hash, spec.platform] }
|
|
236
|
+
locked_requirement = base_requirements[name]
|
|
237
|
+
results = filter_matching_specs(results, locked_requirement) if locked_requirement
|
|
238
|
+
|
|
239
|
+
versions = results.group_by(&:version).reduce([]) do |groups, (version, specs)|
|
|
240
|
+
platform_specs = package.platforms.flat_map {|platform| select_best_platform_match(specs, platform) }
|
|
241
|
+
next groups if platform_specs.empty?
|
|
242
|
+
|
|
243
|
+
ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
|
|
244
|
+
groups << Resolver::Candidate.new(version, :specs => ruby_specs) if ruby_specs.any?
|
|
245
|
+
|
|
246
|
+
next groups if platform_specs == ruby_specs
|
|
247
|
+
|
|
248
|
+
groups << Resolver::Candidate.new(version, :specs => platform_specs)
|
|
249
|
+
|
|
250
|
+
groups
|
|
224
251
|
end
|
|
252
|
+
|
|
253
|
+
sort_versions(package, versions)
|
|
225
254
|
end
|
|
226
255
|
|
|
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?
|
|
256
|
+
def source_for(name)
|
|
257
|
+
@source_requirements[name] || @source_requirements[:default]
|
|
258
|
+
end
|
|
234
259
|
|
|
235
|
-
|
|
236
|
-
|
|
260
|
+
def name_for_explicit_dependency_source
|
|
261
|
+
Bundler.default_gemfile.basename.to_s
|
|
262
|
+
rescue StandardError
|
|
263
|
+
"Gemfile"
|
|
237
264
|
end
|
|
238
265
|
|
|
239
|
-
def
|
|
240
|
-
|
|
266
|
+
def raise_not_found!(package)
|
|
267
|
+
name = package.name
|
|
268
|
+
source = source_for(name)
|
|
269
|
+
specs = @all_specs[name]
|
|
241
270
|
matching_part = name
|
|
242
|
-
requirement_label = SharedHelpers.pretty_dependency(
|
|
271
|
+
requirement_label = SharedHelpers.pretty_dependency(package.dependency)
|
|
243
272
|
cache_message = begin
|
|
244
273
|
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
245
274
|
rescue GemfileNotFound
|
|
246
275
|
nil
|
|
247
276
|
end
|
|
248
|
-
specs_matching_requirement = specs.
|
|
277
|
+
specs_matching_requirement = filter_matching_specs(specs, package.dependency.requirement)
|
|
249
278
|
|
|
250
279
|
if specs_matching_requirement.any?
|
|
251
280
|
specs = specs_matching_requirement
|
|
252
281
|
matching_part = requirement_label
|
|
253
|
-
platforms =
|
|
282
|
+
platforms = package.platforms
|
|
254
283
|
platform_label = platforms.size == 1 ? "platform '#{platforms.first}" : "platforms '#{platforms.join("', '")}"
|
|
255
284
|
requirement_label = "#{requirement_label}' with #{platform_label}"
|
|
256
285
|
end
|
|
257
286
|
|
|
258
|
-
message = String.new("Could not find gem '#{requirement_label}'
|
|
287
|
+
message = String.new("Could not find gem '#{requirement_label}' in #{source}#{cache_message}.\n")
|
|
259
288
|
|
|
260
289
|
if specs.any?
|
|
261
|
-
message << "\
|
|
262
|
-
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
290
|
+
message << "\n#{other_specs_matching_message(specs, matching_part)}"
|
|
263
291
|
end
|
|
264
292
|
|
|
265
|
-
message
|
|
293
|
+
raise GemNotFound, message
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
private
|
|
297
|
+
|
|
298
|
+
def filter_matching_specs(specs, requirements)
|
|
299
|
+
Array(requirements).flat_map do |requirement|
|
|
300
|
+
specs.select {| spec| requirement_satisfied_by?(requirement, spec) }
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def filter_prereleases(specs, package)
|
|
305
|
+
return specs unless package.ignores_prereleases?
|
|
306
|
+
|
|
307
|
+
specs.reject {|s| s.version.prerelease? }
|
|
266
308
|
end
|
|
267
309
|
|
|
268
|
-
def
|
|
269
|
-
|
|
270
|
-
|
|
310
|
+
def requirement_satisfied_by?(requirement, spec)
|
|
311
|
+
requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec)
|
|
312
|
+
end
|
|
271
313
|
|
|
272
|
-
|
|
273
|
-
|
|
314
|
+
def sort_versions(package, versions)
|
|
315
|
+
if versions.size > 1
|
|
316
|
+
@gem_version_promoter.sort_versions(package, versions).reverse
|
|
274
317
|
else
|
|
275
|
-
|
|
276
|
-
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
|
277
|
-
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
|
278
|
-
end
|
|
318
|
+
versions
|
|
279
319
|
end
|
|
320
|
+
end
|
|
280
321
|
|
|
281
|
-
|
|
322
|
+
def repository_for(package)
|
|
323
|
+
source_for(package.name)
|
|
324
|
+
end
|
|
282
325
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
326
|
+
def base_requirements
|
|
327
|
+
@base.base_requirements
|
|
328
|
+
end
|
|
286
329
|
|
|
287
|
-
|
|
288
|
-
|
|
330
|
+
def prepare_dependencies(requirements, packages)
|
|
331
|
+
to_dependency_hash(requirements, packages).map do |dep_package, dep_constraint|
|
|
332
|
+
name = dep_package.name
|
|
289
333
|
|
|
290
|
-
|
|
291
|
-
if trees.size <= 15
|
|
292
|
-
maximal = 1.upto(trees.size).map do |size|
|
|
293
|
-
trees.map(&:last).flatten(1).combination(size).to_a
|
|
294
|
-
end.flatten(1).select do |deps|
|
|
295
|
-
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
|
296
|
-
end.min_by(&:size)
|
|
334
|
+
next [dep_package, dep_constraint] if name == "bundler"
|
|
297
335
|
|
|
298
|
-
|
|
336
|
+
versions = versions_for(dep_package, dep_constraint.range)
|
|
337
|
+
if versions.empty? && dep_package.ignores_prereleases?
|
|
338
|
+
@sorted_versions.delete(dep_package)
|
|
339
|
+
dep_package.consider_prereleases!
|
|
340
|
+
versions = versions_for(dep_package, dep_constraint.range)
|
|
341
|
+
end
|
|
342
|
+
next [dep_package, dep_constraint] unless versions.empty?
|
|
299
343
|
|
|
300
|
-
|
|
301
|
-
end
|
|
344
|
+
next unless dep_package.current_platform?
|
|
302
345
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
else
|
|
307
|
-
String.new("Bundler could not find compatible versions for gem \"#{name}\":")
|
|
308
|
-
end
|
|
309
|
-
o << %(\n)
|
|
310
|
-
o << %( In #{name_for_explicit_dependency_source}:\n)
|
|
311
|
-
o << trees.map do |tree|
|
|
312
|
-
t = "".dup
|
|
313
|
-
depth = 2
|
|
314
|
-
|
|
315
|
-
base_tree = tree.first
|
|
316
|
-
base_tree_name = base_tree.name
|
|
317
|
-
|
|
318
|
-
if base_tree_name.end_with?("\0")
|
|
319
|
-
t = nil
|
|
320
|
-
else
|
|
321
|
-
tree.each do |req|
|
|
322
|
-
t << " " * depth << SharedHelpers.pretty_dependency(req)
|
|
323
|
-
unless tree.last == req
|
|
324
|
-
if spec = conflict.activated_by_name[req.name]
|
|
325
|
-
t << %( was resolved to #{spec.version}, which)
|
|
326
|
-
end
|
|
327
|
-
t << %( depends on)
|
|
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
|
|
346
|
+
raise_not_found!(dep_package)
|
|
347
|
+
end.compact.to_h
|
|
348
|
+
end
|
|
338
349
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
|
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
|
|
350
|
+
def other_specs_matching_message(specs, requirement)
|
|
351
|
+
message = String.new("The source contains the following gems matching '#{requirement}':\n")
|
|
352
|
+
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
353
|
+
message
|
|
354
|
+
end
|
|
374
355
|
|
|
375
|
-
|
|
356
|
+
def requirement_to_range(requirement)
|
|
357
|
+
ranges = requirement.requirements.map do |(op, version)|
|
|
358
|
+
ver = Resolver::Candidate.new(version).generic!
|
|
359
|
+
platform_ver = Resolver::Candidate.new(version).platform_specific!
|
|
360
|
+
|
|
361
|
+
case op
|
|
362
|
+
when "~>"
|
|
363
|
+
name = "~> #{ver}"
|
|
364
|
+
bump = Resolver::Candidate.new(version.bump.to_s + ".A")
|
|
365
|
+
PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true)
|
|
366
|
+
when ">"
|
|
367
|
+
PubGrub::VersionRange.new(:min => platform_ver)
|
|
368
|
+
when ">="
|
|
369
|
+
PubGrub::VersionRange.new(:min => ver, :include_min => true)
|
|
370
|
+
when "<"
|
|
371
|
+
PubGrub::VersionRange.new(:max => ver)
|
|
372
|
+
when "<="
|
|
373
|
+
PubGrub::VersionRange.new(:max => platform_ver, :include_max => true)
|
|
374
|
+
when "="
|
|
375
|
+
PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true)
|
|
376
|
+
when "!="
|
|
377
|
+
PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true).invert
|
|
378
|
+
else
|
|
379
|
+
raise "bad version specifier: #{op}"
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
ranges.inject(&:intersect)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def to_dependency_hash(dependencies, packages)
|
|
387
|
+
dependencies.inject({}) do |deps, dep|
|
|
388
|
+
package = packages[dep.name]
|
|
389
|
+
|
|
390
|
+
current_req = deps[package]
|
|
391
|
+
new_req = parse_dependency(package, dep.requirement)
|
|
392
|
+
|
|
393
|
+
deps[package] = if current_req
|
|
394
|
+
current_req.intersect(new_req)
|
|
395
|
+
else
|
|
396
|
+
new_req
|
|
376
397
|
end
|
|
377
|
-
|
|
398
|
+
|
|
399
|
+
deps
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def bundler_not_found_message(conflict_dependencies)
|
|
404
|
+
candidate_specs = filter_matching_specs(source_for(:default_bundler).specs.search("bundler"), conflict_dependencies)
|
|
405
|
+
|
|
406
|
+
if candidate_specs.any?
|
|
407
|
+
target_version = candidate_specs.last.version
|
|
408
|
+
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
|
409
|
+
"Your bundle requires a different version of Bundler than the one you're running.\n" \
|
|
410
|
+
"Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
|
|
411
|
+
else
|
|
412
|
+
"Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
413
|
+
end
|
|
378
414
|
end
|
|
379
415
|
end
|
|
380
416
|
end
|