bundler 2.2.11 → 2.3.26
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 +721 -5
- data/README.md +1 -1
- data/bundler.gemspec +8 -11
- data/exe/bundle +7 -8
- data/exe/bundler +1 -1
- data/lib/bundler/.document +1 -0
- data/lib/bundler/build_metadata.rb +3 -3
- data/lib/bundler/cli/cache.rb +1 -1
- data/lib/bundler/cli/check.rb +4 -2
- data/lib/bundler/cli/common.rb +17 -3
- data/lib/bundler/cli/config.rb +10 -1
- data/lib/bundler/cli/doctor.rb +24 -5
- data/lib/bundler/cli/exec.rb +1 -6
- data/lib/bundler/cli/gem.rb +130 -26
- data/lib/bundler/cli/info.rb +27 -6
- data/lib/bundler/cli/init.rb +5 -1
- data/lib/bundler/cli/install.rb +23 -54
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/list.rb +7 -1
- data/lib/bundler/cli/lock.rb +5 -1
- data/lib/bundler/cli/open.rb +1 -2
- data/lib/bundler/cli/outdated.rb +22 -14
- data/lib/bundler/cli/platform.rb +2 -2
- data/lib/bundler/cli/remove.rb +1 -2
- data/lib/bundler/cli/show.rb +1 -1
- data/lib/bundler/cli/update.rb +17 -8
- data/lib/bundler/cli.rb +51 -63
- data/lib/bundler/compact_index_client/cache.rb +0 -9
- data/lib/bundler/compact_index_client/updater.rb +26 -14
- data/lib/bundler/compact_index_client.rb +2 -8
- data/lib/bundler/current_ruby.rb +17 -6
- data/lib/bundler/definition.rb +260 -362
- data/lib/bundler/dependency.rb +23 -71
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +72 -76
- data/lib/bundler/endpoint_specification.rb +19 -13
- data/lib/bundler/env.rb +1 -1
- data/lib/bundler/environment_preserver.rb +4 -1
- data/lib/bundler/errors.rb +29 -3
- data/lib/bundler/feature_flag.rb +0 -5
- data/lib/bundler/fetcher/base.rb +6 -8
- data/lib/bundler/fetcher/compact_index.rb +10 -15
- data/lib/bundler/fetcher/downloader.rb +9 -6
- data/lib/bundler/fetcher/index.rb +0 -27
- data/lib/bundler/fetcher.rb +22 -23
- data/lib/bundler/friendly_errors.rb +26 -36
- data/lib/bundler/gem_helper.rb +21 -16
- data/lib/bundler/gem_helpers.rb +9 -2
- data/lib/bundler/gem_version_promoter.rb +14 -25
- data/lib/bundler/index.rb +11 -46
- data/lib/bundler/injector.rb +18 -4
- data/lib/bundler/inline.rb +4 -13
- data/lib/bundler/installer/gem_installer.rb +16 -21
- data/lib/bundler/installer/parallel_installer.rb +36 -15
- data/lib/bundler/installer/standalone.rb +42 -10
- data/lib/bundler/installer.rb +25 -41
- data/lib/bundler/lazy_specification.rb +52 -30
- data/lib/bundler/lockfile_generator.rb +2 -2
- data/lib/bundler/lockfile_parser.rb +18 -43
- data/lib/bundler/man/bundle-add.1 +21 -5
- data/lib/bundler/man/bundle-add.1.ronn +16 -4
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +7 -1
- data/lib/bundler/man/bundle-cache.1.ronn +7 -0
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +2 -2
- data/lib/bundler/man/bundle-clean.1.ronn +1 -1
- data/lib/bundler/man/bundle-config.1 +49 -22
- data/lib/bundler/man/bundle-config.1.ronn +49 -30
- data/lib/bundler/man/bundle-console.1 +53 -0
- data/lib/bundler/man/bundle-console.1.ronn +44 -0
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +2 -2
- data/lib/bundler/man/bundle-exec.1.ronn +1 -1
- data/lib/bundler/man/bundle-gem.1 +14 -1
- data/lib/bundler/man/bundle-gem.1.ronn +16 -0
- data/lib/bundler/man/bundle-help.1 +13 -0
- data/lib/bundler/man/bundle-help.1.ronn +12 -0
- 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 +5 -2
- data/lib/bundler/man/bundle-inject.1.ronn +3 -1
- data/lib/bundler/man/bundle-install.1 +6 -2
- data/lib/bundler/man/bundle-install.1.ronn +8 -2
- 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 +3 -10
- data/lib/bundler/man/bundle-outdated.1.ronn +1 -10
- data/lib/bundler/man/bundle-platform.1 +16 -6
- data/lib/bundler/man/bundle-platform.1.ronn +14 -7
- data/lib/bundler/man/bundle-plugin.1 +81 -0
- data/lib/bundler/man/bundle-plugin.1.ronn +59 -0
- 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 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +5 -4
- data/lib/bundler/man/bundle-version.1 +35 -0
- data/lib/bundler/man/bundle-version.1.ronn +24 -0
- data/lib/bundler/man/bundle-viz.1 +4 -1
- data/lib/bundler/man/bundle-viz.1.ronn +2 -0
- data/lib/bundler/man/bundle.1 +15 -10
- data/lib/bundler/man/bundle.1.ronn +12 -7
- data/lib/bundler/man/gemfile.5 +117 -80
- data/lib/bundler/man/gemfile.5.ronn +105 -84
- data/lib/bundler/man/index.txt +4 -0
- data/lib/bundler/match_metadata.rb +13 -0
- data/lib/bundler/match_platform.rb +0 -1
- data/lib/bundler/match_remote_metadata.rb +29 -0
- data/lib/bundler/plugin/api/source.rb +24 -8
- data/lib/bundler/plugin/index.rb +4 -1
- data/lib/bundler/plugin/installer/git.rb +0 -4
- data/lib/bundler/plugin/installer/rubygems.rb +0 -4
- data/lib/bundler/plugin/installer.rb +10 -10
- data/lib/bundler/plugin/source_list.rb +4 -0
- data/lib/bundler/plugin.rb +30 -8
- data/lib/bundler/process_lock.rb +1 -1
- data/lib/bundler/remote_specification.rb +10 -4
- data/lib/bundler/resolver/base.rb +50 -0
- data/lib/bundler/resolver/spec_group.rb +31 -73
- data/lib/bundler/resolver.rb +193 -292
- data/lib/bundler/retry.rb +1 -1
- data/lib/bundler/ruby_dsl.rb +1 -1
- data/lib/bundler/ruby_version.rb +5 -18
- data/lib/bundler/rubygems_ext.rb +160 -26
- data/lib/bundler/rubygems_gem_installer.rb +86 -9
- data/lib/bundler/rubygems_integration.rb +46 -93
- data/lib/bundler/runtime.rb +18 -12
- data/lib/bundler/self_manager.rb +168 -0
- data/lib/bundler/settings.rb +98 -22
- data/lib/bundler/setup.rb +2 -2
- data/lib/bundler/shared_helpers.rb +15 -31
- data/lib/bundler/source/git/git_proxy.rb +8 -6
- data/lib/bundler/source/git.rb +29 -13
- data/lib/bundler/source/metadata.rb +3 -7
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/path.rb +3 -1
- data/lib/bundler/source/rubygems.rb +199 -182
- data/lib/bundler/source/rubygems_aggregate.rb +68 -0
- data/lib/bundler/source.rb +24 -4
- data/lib/bundler/source_list.rb +104 -60
- data/lib/bundler/source_map.rb +71 -0
- data/lib/bundler/spec_set.rb +58 -52
- data/lib/bundler/stub_specification.rb +13 -3
- data/lib/bundler/templates/Executable +2 -4
- data/lib/bundler/templates/Executable.bundler +8 -8
- data/lib/bundler/templates/Executable.standalone +2 -4
- data/lib/bundler/templates/Gemfile +0 -2
- data/lib/bundler/templates/gems.rb +0 -3
- data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
- data/lib/bundler/templates/newgem/README.md.tt +8 -12
- data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -7
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +5 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +19 -17
- data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
- data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
- data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
- data/lib/bundler/ui/shell.rb +1 -1
- data/lib/bundler/vendor/.document +1 -0
- data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
- data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
- data/lib/bundler/vendor/molinillo/LICENSE +9 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +32 -26
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
- data/lib/bundler/vendor/thor/LICENSE.md +20 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
- data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
- data/lib/bundler/vendor/tsort/lib/tsort.rb +452 -0
- data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
- data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
- data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
- data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
- data/lib/bundler/vendored_tsort.rb +4 -0
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +19 -4
- data/lib/bundler.rb +46 -39
- metadata +39 -12
- data/lib/bundler/dep_proxy.rb +0 -55
- data/lib/bundler/gemdeps.rb +0 -29
- data/lib/bundler/psyched_yaml.rb +0 -22
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
data/lib/bundler/resolver.rb
CHANGED
|
@@ -3,64 +3,54 @@
|
|
|
3
3
|
module Bundler
|
|
4
4
|
class Resolver
|
|
5
5
|
require_relative "vendored_molinillo"
|
|
6
|
+
require_relative "resolver/base"
|
|
6
7
|
require_relative "resolver/spec_group"
|
|
7
8
|
|
|
8
9
|
include GemHelpers
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
# the list of passed dependencies and any child dependencies without
|
|
12
|
-
# causing any gem activation errors.
|
|
13
|
-
#
|
|
14
|
-
# ==== Parameters
|
|
15
|
-
# *dependencies<Gem::Dependency>:: The list of dependencies to resolve
|
|
16
|
-
#
|
|
17
|
-
# ==== Returns
|
|
18
|
-
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
|
19
|
-
# collection of gemspecs is returned. Otherwise, nil is returned.
|
|
20
|
-
def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
|
|
21
|
-
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
|
22
|
-
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
23
|
-
result = resolver.start(requirements)
|
|
24
|
-
SpecSet.new(result)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
28
|
-
@index = index
|
|
11
|
+
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
29
12
|
@source_requirements = source_requirements
|
|
30
|
-
@base = base
|
|
13
|
+
@base = Resolver::Base.new(base, additional_base_requirements)
|
|
31
14
|
@resolver = Molinillo::Resolver.new(self, self)
|
|
15
|
+
@results_for = {}
|
|
32
16
|
@search_for = {}
|
|
33
|
-
@
|
|
34
|
-
@base.each do |ls|
|
|
35
|
-
dep = Dependency.new(ls.name, ls.version)
|
|
36
|
-
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
|
|
37
|
-
end
|
|
38
|
-
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
|
39
|
-
@platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
|
|
17
|
+
@platforms = platforms
|
|
40
18
|
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
|
|
41
19
|
@gem_version_promoter = gem_version_promoter
|
|
42
|
-
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
|
|
43
|
-
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
|
|
44
|
-
|
|
45
|
-
@variant_specific_names = []
|
|
46
|
-
@generic_names = ["Ruby\0", "RubyGems\0"]
|
|
47
20
|
end
|
|
48
21
|
|
|
49
|
-
def start(requirements)
|
|
50
|
-
@
|
|
51
|
-
|
|
22
|
+
def start(requirements, exclude_specs: [])
|
|
23
|
+
@metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
|
|
24
|
+
|
|
25
|
+
exclude_specs.each do |spec|
|
|
26
|
+
remove_from_candidates(spec)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
requirements.each {|dep| prerelease_specified[dep.name] ||= dep.prerelease? }
|
|
52
30
|
|
|
53
31
|
verify_gemfile_dependencies_are_found!(requirements)
|
|
54
|
-
|
|
55
|
-
dg.
|
|
56
|
-
tap {|resolved| validate_resolved_specs!(resolved) }.
|
|
32
|
+
result = @resolver.resolve(requirements).
|
|
57
33
|
map(&:payload).
|
|
58
34
|
reject {|sg| sg.name.end_with?("\0") }.
|
|
59
35
|
map(&:to_specs).
|
|
60
36
|
flatten
|
|
37
|
+
|
|
38
|
+
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
|
|
61
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
|
|
45
|
+
|
|
46
|
+
if deps_to_unlock.any?
|
|
47
|
+
@base.unlock_deps(deps_to_unlock)
|
|
48
|
+
reset_spec_cache
|
|
49
|
+
retry
|
|
50
|
+
end
|
|
51
|
+
|
|
62
52
|
message = version_conflict_message(e)
|
|
63
|
-
raise VersionConflict.new(
|
|
53
|
+
raise VersionConflict.new(conflicts.keys.uniq, message)
|
|
64
54
|
rescue Molinillo::CircularDependencyError => e
|
|
65
55
|
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
|
66
56
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
|
@@ -107,109 +97,52 @@ module Bundler
|
|
|
107
97
|
include Molinillo::SpecificationProvider
|
|
108
98
|
|
|
109
99
|
def dependencies_for(specification)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if @variant_specific_names.include?(specification.name)
|
|
113
|
-
@variant_specific_names |= all_dependencies.map(&:name) - @generic_names
|
|
114
|
-
else
|
|
115
|
-
generic_names, variant_specific_names = specification.partitioned_dependency_names_for_activated_platforms
|
|
116
|
-
@variant_specific_names |= variant_specific_names - @generic_names
|
|
117
|
-
@generic_names |= generic_names
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
all_dependencies
|
|
100
|
+
specification.dependencies_for_activated_platforms
|
|
121
101
|
end
|
|
122
102
|
|
|
123
|
-
def search_for(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
results =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
spec_groups = if results.any?
|
|
143
|
-
nested = []
|
|
144
|
-
results.each do |spec|
|
|
145
|
-
version, specs = nested.last
|
|
146
|
-
if version == spec.version
|
|
147
|
-
specs << spec
|
|
148
|
-
else
|
|
149
|
-
nested << [spec.version, [spec]]
|
|
150
|
-
end
|
|
103
|
+
def search_for(dependency)
|
|
104
|
+
@search_for[dependency] ||= begin
|
|
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
|
|
151
121
|
end
|
|
152
|
-
nested.reduce([]) do |groups, (version, specs)|
|
|
153
|
-
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
|
154
|
-
|
|
155
|
-
specs_by_platform = Hash.new do |current_specs, current_platform|
|
|
156
|
-
current_specs[current_platform] = select_best_platform_match(specs, current_platform)
|
|
157
|
-
end
|
|
158
122
|
|
|
159
|
-
|
|
160
|
-
groups << spec_group_ruby if spec_group_ruby
|
|
123
|
+
next groups if @resolving_only_for_ruby || dependency.force_ruby_platform
|
|
161
124
|
|
|
162
|
-
|
|
125
|
+
platform_specs = relevant_platforms.flat_map {|platform| select_best_platform_match(specs, platform) }
|
|
126
|
+
next groups if platform_specs == ruby_specs
|
|
163
127
|
|
|
164
|
-
|
|
165
|
-
|
|
128
|
+
spec_group = SpecGroup.new(platform_specs, relevant_platforms)
|
|
129
|
+
groups << spec_group
|
|
166
130
|
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
else
|
|
170
|
-
[]
|
|
171
|
-
end
|
|
172
|
-
# GVP handles major itself, but it's still a bit risky to trust it with it
|
|
173
|
-
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
|
174
|
-
if !@use_gvp
|
|
175
|
-
spec_groups
|
|
176
|
-
else
|
|
177
|
-
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
|
131
|
+
groups
|
|
178
132
|
end
|
|
179
133
|
end
|
|
134
|
+
end
|
|
180
135
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
search_result.each do |sg|
|
|
186
|
-
if @generic_names.include?(name)
|
|
187
|
-
@variant_specific_names -= [name]
|
|
188
|
-
sg.activate_all_platforms!
|
|
189
|
-
else
|
|
190
|
-
sg.activate_platform!(platform)
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
136
|
+
def index_for(dependency)
|
|
137
|
+
source_for(dependency.name).specs
|
|
138
|
+
end
|
|
194
139
|
|
|
195
|
-
|
|
140
|
+
def source_for(name)
|
|
141
|
+
@source_requirements[name] || @source_requirements[:default]
|
|
196
142
|
end
|
|
197
143
|
|
|
198
|
-
def
|
|
199
|
-
|
|
200
|
-
if source
|
|
201
|
-
source.specs
|
|
202
|
-
elsif @lockfile_uses_separate_rubygems_sources
|
|
203
|
-
Index.build do |idx|
|
|
204
|
-
if dependency.all_sources
|
|
205
|
-
dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
|
|
206
|
-
else
|
|
207
|
-
idx.add_source @source_requirements[:default].specs
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
else
|
|
211
|
-
@index
|
|
212
|
-
end
|
|
144
|
+
def results_for(dependency)
|
|
145
|
+
@results_for[dependency] ||= index_for(dependency).search(dependency)
|
|
213
146
|
end
|
|
214
147
|
|
|
215
148
|
def name_for(dependency)
|
|
@@ -222,54 +155,51 @@ module Bundler
|
|
|
222
155
|
"Gemfile"
|
|
223
156
|
end
|
|
224
157
|
|
|
225
|
-
def name_for_locking_dependency_source
|
|
226
|
-
Bundler.default_lockfile.basename.to_s
|
|
227
|
-
rescue StandardError
|
|
228
|
-
"Gemfile.lock"
|
|
229
|
-
end
|
|
230
|
-
|
|
231
158
|
def requirement_satisfied_by?(requirement, activated, spec)
|
|
232
159
|
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
|
233
160
|
end
|
|
234
161
|
|
|
235
|
-
def dependencies_equal?(dependencies, other_dependencies)
|
|
236
|
-
dependencies.map(&:dep) == other_dependencies.map(&:dep)
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
def relevant_sources_for_vertex(vertex)
|
|
240
|
-
if vertex.root?
|
|
241
|
-
[@source_requirements[vertex.name]]
|
|
242
|
-
elsif @lockfile_uses_separate_rubygems_sources
|
|
243
|
-
vertex.recursive_predecessors.map do |v|
|
|
244
|
-
@source_requirements[v.name]
|
|
245
|
-
end << @source_requirements[:default]
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
|
|
249
162
|
def sort_dependencies(dependencies, activated, conflicts)
|
|
250
163
|
dependencies.sort_by do |dependency|
|
|
251
|
-
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
|
252
164
|
name = name_for(dependency)
|
|
253
165
|
vertex = activated.vertex_named(name)
|
|
254
166
|
[
|
|
255
|
-
@
|
|
167
|
+
@base[name].any? ? 0 : 1,
|
|
256
168
|
vertex.payload ? 0 : 1,
|
|
257
169
|
vertex.root? ? 0 : 1,
|
|
258
170
|
amount_constrained(dependency),
|
|
259
171
|
conflicts[name] ? 0 : 1,
|
|
260
172
|
vertex.payload ? 0 : search_for(dependency).count,
|
|
261
|
-
self.class.platform_sort_key(dependency.__platform),
|
|
262
173
|
]
|
|
263
174
|
end
|
|
264
175
|
end
|
|
265
176
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
177
|
+
private
|
|
178
|
+
|
|
179
|
+
def base_requirements
|
|
180
|
+
@base.base_requirements
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def prerelease_specified
|
|
184
|
+
@gem_version_promoter.prerelease_specified
|
|
270
185
|
end
|
|
271
186
|
|
|
272
|
-
|
|
187
|
+
def remove_from_candidates(spec)
|
|
188
|
+
@base.delete(spec)
|
|
189
|
+
|
|
190
|
+
@results_for.keys.each do |dep|
|
|
191
|
+
next unless dep.name == spec.name
|
|
192
|
+
|
|
193
|
+
@results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
reset_spec_cache
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def reset_spec_cache
|
|
200
|
+
@search_for = {}
|
|
201
|
+
@gem_version_promoter.reset
|
|
202
|
+
end
|
|
273
203
|
|
|
274
204
|
# returns an integer \in (-\infty, 0]
|
|
275
205
|
# a number closer to 0 means the dependency is less constraining
|
|
@@ -279,69 +209,60 @@ module Bundler
|
|
|
279
209
|
# before dependencies that are unconstrained
|
|
280
210
|
def amount_constrained(dependency)
|
|
281
211
|
@amount_constrained ||= {}
|
|
282
|
-
@amount_constrained[dependency.name] ||=
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
all = index_for(dependency).search(dependency.name).size
|
|
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
|
|
287
216
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
end
|
|
217
|
+
if all <= 1
|
|
218
|
+
all - 1_000_000
|
|
219
|
+
else
|
|
220
|
+
search = search_for(dependency)
|
|
221
|
+
search = prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
|
|
222
|
+
search - all
|
|
295
223
|
end
|
|
296
224
|
end
|
|
297
225
|
end
|
|
298
226
|
|
|
299
227
|
def verify_gemfile_dependencies_are_found!(requirements)
|
|
300
|
-
requirements.
|
|
228
|
+
requirements.map! do |requirement|
|
|
301
229
|
name = requirement.name
|
|
302
|
-
next if name == "bundler"
|
|
303
|
-
next
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
if (base = @base[name]) && !base.empty?
|
|
312
|
-
version = base.first.version
|
|
313
|
-
message = "You have requested:\n" \
|
|
314
|
-
" #{name} #{requirement.requirement}\n\n" \
|
|
315
|
-
"The bundle currently has #{name} locked at #{version}.\n" \
|
|
316
|
-
"Try running `bundle update #{name}`\n\n" \
|
|
317
|
-
"If you are updating multiple gems in your Gemfile at once,\n" \
|
|
318
|
-
"try passing them all to `bundle update`"
|
|
319
|
-
elsif source = @source_requirements[name]
|
|
320
|
-
specs = source.specs[name]
|
|
321
|
-
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
|
322
|
-
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
|
323
|
-
message << if versions_with_platforms.any?
|
|
324
|
-
"The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
|
|
325
|
-
else
|
|
326
|
-
"The source does not contain any versions of '#{name}'"
|
|
327
|
-
end
|
|
328
|
-
else
|
|
329
|
-
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
|
330
|
-
"listed in your Gemfile#{cache_message}."
|
|
331
|
-
end
|
|
332
|
-
raise GemNotFound, message
|
|
333
|
-
end
|
|
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?
|
|
234
|
+
|
|
235
|
+
raise GemNotFound, gem_not_found_message(name, requirement, source_for(name))
|
|
236
|
+
end.compact!
|
|
334
237
|
end
|
|
335
238
|
|
|
336
|
-
def
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
239
|
+
def gem_not_found_message(name, requirement, source, extra_message = "")
|
|
240
|
+
specs = source.specs.search(name).sort_by {|s| [s.version, s.platform.to_s] }
|
|
241
|
+
matching_part = name
|
|
242
|
+
requirement_label = SharedHelpers.pretty_dependency(requirement)
|
|
243
|
+
cache_message = begin
|
|
244
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
245
|
+
rescue GemfileNotFound
|
|
246
|
+
nil
|
|
247
|
+
end
|
|
248
|
+
specs_matching_requirement = specs.select {| spec| requirement.matches_spec?(spec) }
|
|
249
|
+
|
|
250
|
+
if specs_matching_requirement.any?
|
|
251
|
+
specs = specs_matching_requirement
|
|
252
|
+
matching_part = requirement_label
|
|
253
|
+
platforms = requirement.gem_platforms(@platforms)
|
|
254
|
+
platform_label = platforms.size == 1 ? "platform '#{platforms.first}" : "platforms '#{platforms.join("', '")}"
|
|
255
|
+
requirement_label = "#{requirement_label}' with #{platform_label}"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")
|
|
259
|
+
|
|
260
|
+
if specs.any?
|
|
261
|
+
message << "\nThe source contains the following gems matching '#{matching_part}':\n"
|
|
262
|
+
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
343
263
|
end
|
|
344
|
-
|
|
264
|
+
|
|
265
|
+
message
|
|
345
266
|
end
|
|
346
267
|
|
|
347
268
|
def version_conflict_message(e)
|
|
@@ -359,29 +280,62 @@ module Bundler
|
|
|
359
280
|
|
|
360
281
|
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
|
|
361
282
|
|
|
362
|
-
solver_name = "Bundler"
|
|
363
|
-
possibility_type = "gem"
|
|
364
283
|
e.message_with_trees(
|
|
365
|
-
:
|
|
366
|
-
|
|
367
|
-
|
|
284
|
+
:full_message_for_conflict => lambda do |name, conflict|
|
|
285
|
+
trees = conflict.requirement_trees
|
|
286
|
+
|
|
368
287
|
# called first, because we want to reduce the amount of work required to find maximal empty sets
|
|
369
288
|
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
|
370
289
|
|
|
371
290
|
# bail out if tree size is too big for Array#combination to make any sense
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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)
|
|
297
|
+
|
|
298
|
+
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
|
299
|
+
|
|
300
|
+
trees.sort_by! {|t| t.reverse.map(&:name) }
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
if trees.size > 1 || name == "bundler"
|
|
304
|
+
o = if name.end_with?("\0")
|
|
305
|
+
String.new("Bundler found conflicting requirements for the #{name} version:")
|
|
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
|
|
338
|
+
|
|
385
339
|
if name == "bundler"
|
|
386
340
|
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
|
387
341
|
|
|
@@ -392,7 +346,7 @@ module Bundler
|
|
|
392
346
|
if other_bundler_required
|
|
393
347
|
o << "\n\n"
|
|
394
348
|
|
|
395
|
-
candidate_specs =
|
|
349
|
+
candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
|
|
396
350
|
if candidate_specs.any?
|
|
397
351
|
target_version = candidate_specs.last.version
|
|
398
352
|
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
|
@@ -402,78 +356,25 @@ module Bundler
|
|
|
402
356
|
o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
403
357
|
end
|
|
404
358
|
end
|
|
405
|
-
elsif
|
|
406
|
-
o <<
|
|
407
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
|
408
|
-
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
|
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)
|
|
409
361
|
elsif !conflict.existing
|
|
410
362
|
o << "\n"
|
|
411
363
|
|
|
412
|
-
|
|
413
|
-
[conflict.requirement.source]
|
|
414
|
-
elsif conflict.requirement.all_sources
|
|
415
|
-
conflict.requirement.all_sources
|
|
416
|
-
elsif @lockfile_uses_separate_rubygems_sources
|
|
417
|
-
# every conflict should have an explicit group of sources when we
|
|
418
|
-
# enforce strict pinning
|
|
419
|
-
raise "no source set for #{conflict}"
|
|
420
|
-
else
|
|
421
|
-
[]
|
|
422
|
-
end.compact.map(&:to_s).uniq.sort
|
|
423
|
-
|
|
424
|
-
metadata_requirement = name.end_with?("\0")
|
|
425
|
-
|
|
426
|
-
o << "Could not find gem '" unless metadata_requirement
|
|
427
|
-
o << SharedHelpers.pretty_dependency(conflict.requirement)
|
|
428
|
-
o << "'" unless metadata_requirement
|
|
429
|
-
if conflict.requirement_trees.first.size > 1
|
|
430
|
-
o << ", which is required by "
|
|
431
|
-
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
|
432
|
-
end
|
|
433
|
-
o << " "
|
|
364
|
+
relevant_source = conflict.requirement.source || source_for(name)
|
|
434
365
|
|
|
435
|
-
|
|
436
|
-
"
|
|
437
|
-
elsif metadata_requirement
|
|
438
|
-
"is not available in #{relevant_sources.join(" or ")}"
|
|
366
|
+
extra_message = if trees.first.size > 1
|
|
367
|
+
", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}',"
|
|
439
368
|
else
|
|
440
|
-
"
|
|
369
|
+
""
|
|
441
370
|
end
|
|
371
|
+
|
|
372
|
+
o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
|
|
442
373
|
end
|
|
443
|
-
end,
|
|
444
|
-
:version_for_spec => lambda {|spec| spec.version },
|
|
445
|
-
:incompatible_version_message_for_conflict => lambda do |name, _conflict|
|
|
446
|
-
if name.end_with?("\0")
|
|
447
|
-
%(#{solver_name} found conflicting requirements for the #{name} version:)
|
|
448
|
-
else
|
|
449
|
-
%(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
|
|
450
|
-
end
|
|
451
|
-
end
|
|
452
|
-
)
|
|
453
|
-
end
|
|
454
374
|
|
|
455
|
-
|
|
456
|
-
resolved_specs.each do |v|
|
|
457
|
-
name = v.name
|
|
458
|
-
next unless sources = relevant_sources_for_vertex(v)
|
|
459
|
-
sources.compact!
|
|
460
|
-
if default_index = sources.index(@source_requirements[:default])
|
|
461
|
-
sources.delete_at(default_index)
|
|
375
|
+
o
|
|
462
376
|
end
|
|
463
|
-
|
|
464
|
-
sources.uniq!
|
|
465
|
-
next if sources.size <= 1
|
|
466
|
-
|
|
467
|
-
multisource_disabled = Bundler.feature_flag.disable_multisource?
|
|
468
|
-
|
|
469
|
-
msg = ["The gem '#{name}' was found in multiple relevant sources."]
|
|
470
|
-
msg.concat sources.map {|s| " * #{s}" }.sort
|
|
471
|
-
msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
|
472
|
-
msg = msg.join("\n")
|
|
473
|
-
|
|
474
|
-
raise SecurityError, msg if multisource_disabled
|
|
475
|
-
Bundler.ui.warn "Warning: #{msg}"
|
|
476
|
-
end
|
|
377
|
+
)
|
|
477
378
|
end
|
|
478
379
|
end
|
|
479
380
|
end
|
data/lib/bundler/retry.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Bundler
|
|
|
49
49
|
raise e
|
|
50
50
|
end
|
|
51
51
|
return true unless name
|
|
52
|
-
Bundler.ui.info "" unless Bundler.ui.debug? # Add new line
|
|
52
|
+
Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
|
|
53
53
|
Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
|
|
54
54
|
end
|
|
55
55
|
|
data/lib/bundler/ruby_dsl.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Bundler
|
|
|
9
9
|
raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil?
|
|
10
10
|
|
|
11
11
|
if options[:engine] == "ruby" && options[:engine_version] &&
|
|
12
|
-
|
|
12
|
+
ruby_version != Array(options[:engine_version])
|
|
13
13
|
raise GemfileEvalError, "ruby_version must match the :engine_version for MRI"
|
|
14
14
|
end
|
|
15
15
|
@ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version])
|