bundler 2.2.26 → 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 +501 -1
- data/README.md +1 -1
- data/bundler.gemspec +6 -8
- 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/check.rb +1 -1
- data/lib/bundler/cli/common.rb +3 -2
- data/lib/bundler/cli/config.rb +10 -1
- data/lib/bundler/cli/doctor.rb +12 -3
- data/lib/bundler/cli/gem.rb +98 -9
- data/lib/bundler/cli/info.rb +27 -6
- data/lib/bundler/cli/init.rb +5 -1
- data/lib/bundler/cli/install.rb +13 -30
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/outdated.rb +12 -3
- 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 +8 -4
- data/lib/bundler/cli.rb +23 -19
- data/lib/bundler/compact_index_client/cache.rb +0 -9
- data/lib/bundler/compact_index_client/updater.rb +16 -8
- data/lib/bundler/compact_index_client.rb +2 -8
- data/lib/bundler/current_ruby.rb +16 -6
- data/lib/bundler/definition.rb +204 -217
- data/lib/bundler/dependency.rb +23 -71
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +28 -45
- 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 +28 -2
- data/lib/bundler/feature_flag.rb +0 -1
- data/lib/bundler/fetcher/base.rb +6 -8
- data/lib/bundler/fetcher/compact_index.rb +9 -14
- data/lib/bundler/fetcher/index.rb +0 -26
- data/lib/bundler/fetcher.rb +20 -22
- data/lib/bundler/friendly_errors.rb +26 -34
- data/lib/bundler/gem_helper.rb +7 -18
- data/lib/bundler/gem_helpers.rb +9 -2
- data/lib/bundler/gem_version_promoter.rb +14 -25
- data/lib/bundler/index.rb +10 -40
- data/lib/bundler/injector.rb +16 -2
- data/lib/bundler/inline.rb +2 -12
- data/lib/bundler/installer/gem_installer.rb +13 -5
- data/lib/bundler/installer/standalone.rb +30 -3
- data/lib/bundler/installer.rb +18 -29
- data/lib/bundler/lazy_specification.rb +52 -35
- data/lib/bundler/lockfile_generator.rb +2 -2
- data/lib/bundler/lockfile_parser.rb +12 -10
- 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 +33 -14
- data/lib/bundler/man/bundle-config.1.ronn +30 -18
- 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 +2 -2
- data/lib/bundler/man/bundle-update.1.ronn +2 -1
- 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 +4 -9
- data/lib/bundler/plugin/installer/git.rb +0 -4
- data/lib/bundler/plugin/installer/rubygems.rb +0 -4
- data/lib/bundler/plugin/installer.rb +3 -1
- data/lib/bundler/plugin.rb +25 -6
- 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 -49
- data/lib/bundler/resolver.rb +183 -192
- data/lib/bundler/ruby_dsl.rb +1 -1
- data/lib/bundler/ruby_version.rb +5 -18
- data/lib/bundler/rubygems_ext.rb +138 -20
- data/lib/bundler/rubygems_gem_installer.rb +42 -16
- data/lib/bundler/rubygems_integration.rb +42 -90
- data/lib/bundler/runtime.rb +2 -3
- data/lib/bundler/self_manager.rb +168 -0
- data/lib/bundler/settings.rb +13 -4
- data/lib/bundler/shared_helpers.rb +15 -24
- data/lib/bundler/source/git/git_proxy.rb +7 -4
- data/lib/bundler/source/git.rb +29 -13
- data/lib/bundler/source/metadata.rb +3 -3
- data/lib/bundler/source/path.rb +1 -1
- data/lib/bundler/source/rubygems.rb +148 -161
- data/lib/bundler/source/rubygems_aggregate.rb +1 -1
- data/lib/bundler/source.rb +6 -5
- data/lib/bundler/source_list.rb +15 -29
- data/lib/bundler/source_map.rb +15 -2
- data/lib/bundler/spec_set.rb +52 -32
- data/lib/bundler/stub_specification.rb +5 -3
- data/lib/bundler/templates/Executable +2 -4
- data/lib/bundler/templates/Executable.bundler +2 -2
- 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 +3 -9
- data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +5 -4
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +5 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +16 -16
- 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/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 +6 -6
- 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/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 +2 -2
- data/lib/bundler.rb +40 -29
- metadata +37 -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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundler
|
|
4
|
+
class Resolver
|
|
5
|
+
class Base
|
|
6
|
+
def initialize(base, additional_base_requirements)
|
|
7
|
+
@base = base
|
|
8
|
+
@additional_base_requirements = additional_base_requirements
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def [](name)
|
|
12
|
+
@base[name]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def delete(spec)
|
|
16
|
+
@base.delete(spec)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def base_requirements
|
|
20
|
+
@base_requirements ||= build_base_requirements
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def unlock_deps(deps)
|
|
24
|
+
exact, lower_bound = deps.partition(&:specific?)
|
|
25
|
+
|
|
26
|
+
exact.each do |exact_dep|
|
|
27
|
+
@base.delete_by_name_and_version(exact_dep.name, exact_dep.requirement.requirements.first.last)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
lower_bound.each do |lower_bound_dep|
|
|
31
|
+
@additional_base_requirements.delete(lower_bound_dep)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@base_requirements = nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def build_base_requirements
|
|
40
|
+
base_requirements = {}
|
|
41
|
+
@base.each do |ls|
|
|
42
|
+
dep = Dependency.new(ls.name, ls.version)
|
|
43
|
+
base_requirements[ls.name] = dep
|
|
44
|
+
end
|
|
45
|
+
@additional_base_requirements.each {|d| base_requirements[d.name] = d }
|
|
46
|
+
base_requirements
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -4,41 +4,25 @@ module Bundler
|
|
|
4
4
|
class Resolver
|
|
5
5
|
class SpecGroup
|
|
6
6
|
attr_accessor :name, :version, :source
|
|
7
|
-
attr_accessor :activated_platforms
|
|
7
|
+
attr_accessor :activated_platforms, :force_ruby_platform
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
new(specific_platform_specs.first, specs, platforms)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def initialize(exemplary_spec, specs, relevant_platforms)
|
|
19
|
-
@exemplary_spec = exemplary_spec
|
|
20
|
-
@name = exemplary_spec.name
|
|
21
|
-
@version = exemplary_spec.version
|
|
22
|
-
@source = exemplary_spec.source
|
|
9
|
+
def initialize(specs, relevant_platforms)
|
|
10
|
+
@exemplary_spec = specs.first
|
|
11
|
+
@name = @exemplary_spec.name
|
|
12
|
+
@version = @exemplary_spec.version
|
|
13
|
+
@source = @exemplary_spec.source
|
|
23
14
|
|
|
24
15
|
@activated_platforms = relevant_platforms
|
|
25
|
-
@dependencies = Hash.new do |dependencies, platforms|
|
|
26
|
-
dependencies[platforms] = dependencies_for(platforms)
|
|
27
|
-
end
|
|
28
16
|
@specs = specs
|
|
29
17
|
end
|
|
30
18
|
|
|
31
19
|
def to_specs
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
lazy_spec.dependencies.replace s.dependencies
|
|
39
|
-
lazy_spec
|
|
40
|
-
end
|
|
41
|
-
end.flatten.compact.uniq
|
|
20
|
+
@specs.map do |s|
|
|
21
|
+
lazy_spec = LazySpecification.new(name, version, s.platform, source)
|
|
22
|
+
lazy_spec.force_ruby_platform = force_ruby_platform
|
|
23
|
+
lazy_spec.dependencies.replace s.dependencies
|
|
24
|
+
lazy_spec
|
|
25
|
+
end
|
|
42
26
|
end
|
|
43
27
|
|
|
44
28
|
def to_s
|
|
@@ -47,7 +31,9 @@ module Bundler
|
|
|
47
31
|
end
|
|
48
32
|
|
|
49
33
|
def dependencies_for_activated_platforms
|
|
50
|
-
@
|
|
34
|
+
@dependencies_for_activated_platforms ||= @specs.map do |spec|
|
|
35
|
+
__dependencies(spec) + metadata_dependencies(spec)
|
|
36
|
+
end.flatten.uniq
|
|
51
37
|
end
|
|
52
38
|
|
|
53
39
|
def ==(other)
|
|
@@ -78,32 +64,28 @@ module Bundler
|
|
|
78
64
|
|
|
79
65
|
private
|
|
80
66
|
|
|
81
|
-
def
|
|
82
|
-
platforms.map do |platform|
|
|
83
|
-
__dependencies(platform) + metadata_dependencies(platform)
|
|
84
|
-
end.flatten
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def __dependencies(platform)
|
|
67
|
+
def __dependencies(spec)
|
|
88
68
|
dependencies = []
|
|
89
|
-
|
|
69
|
+
spec.dependencies.each do |dep|
|
|
90
70
|
next if dep.type == :development
|
|
91
|
-
dependencies <<
|
|
71
|
+
dependencies << Dependency.new(dep.name, dep.requirement)
|
|
92
72
|
end
|
|
93
73
|
dependencies
|
|
94
74
|
end
|
|
95
75
|
|
|
96
|
-
def metadata_dependencies(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
76
|
+
def metadata_dependencies(spec)
|
|
77
|
+
return [] if spec.is_a?(LazySpecification)
|
|
78
|
+
|
|
79
|
+
[
|
|
80
|
+
metadata_dependency("Ruby", spec.required_ruby_version),
|
|
81
|
+
metadata_dependency("RubyGems", spec.required_rubygems_version),
|
|
82
|
+
].compact
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def metadata_dependency(name, requirement)
|
|
86
|
+
return if requirement.nil? || requirement.none?
|
|
87
|
+
|
|
88
|
+
Dependency.new("#{name}\0", requirement)
|
|
107
89
|
end
|
|
108
90
|
end
|
|
109
91
|
end
|
data/lib/bundler/resolver.rb
CHANGED
|
@@ -3,60 +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
|
-
# Figures out the best possible configuration of gems that satisfies
|
|
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, 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(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
23
|
-
result = resolver.start(requirements)
|
|
24
|
-
SpecSet.new(SpecSet.new(result).for(requirements.reject{|dep| dep.name.end_with?("\0") }))
|
|
25
|
-
end
|
|
26
|
-
|
|
27
11
|
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
28
12
|
@source_requirements = source_requirements
|
|
29
|
-
@base = base
|
|
13
|
+
@base = Resolver::Base.new(base, additional_base_requirements)
|
|
30
14
|
@resolver = Molinillo::Resolver.new(self, self)
|
|
15
|
+
@results_for = {}
|
|
31
16
|
@search_for = {}
|
|
32
|
-
@
|
|
33
|
-
aggregate_global_source = @source_requirements[:default].is_a?(Source::RubygemsAggregate)
|
|
34
|
-
@base.each do |ls|
|
|
35
|
-
dep = Dependency.new(ls.name, ls.version)
|
|
36
|
-
ls.source = source_for(ls.name) unless aggregate_global_source
|
|
37
|
-
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
|
|
38
|
-
end
|
|
39
|
-
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
|
40
|
-
@platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
|
|
17
|
+
@platforms = platforms
|
|
41
18
|
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
|
|
42
19
|
@gem_version_promoter = gem_version_promoter
|
|
43
|
-
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
|
|
44
20
|
end
|
|
45
21
|
|
|
46
|
-
def start(requirements)
|
|
47
|
-
@
|
|
48
|
-
|
|
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? }
|
|
49
30
|
|
|
50
31
|
verify_gemfile_dependencies_are_found!(requirements)
|
|
51
|
-
|
|
52
|
-
dg.
|
|
32
|
+
result = @resolver.resolve(requirements).
|
|
53
33
|
map(&:payload).
|
|
54
34
|
reject {|sg| sg.name.end_with?("\0") }.
|
|
55
35
|
map(&:to_specs).
|
|
56
36
|
flatten
|
|
37
|
+
|
|
38
|
+
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
|
|
57
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
|
+
|
|
58
52
|
message = version_conflict_message(e)
|
|
59
|
-
raise VersionConflict.new(
|
|
53
|
+
raise VersionConflict.new(conflicts.keys.uniq, message)
|
|
60
54
|
rescue Molinillo::CircularDependencyError => e
|
|
61
55
|
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
|
62
56
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
|
@@ -106,60 +100,35 @@ module Bundler
|
|
|
106
100
|
specification.dependencies_for_activated_platforms
|
|
107
101
|
end
|
|
108
102
|
|
|
109
|
-
def search_for(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
results = results_for(dependency
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
spec_groups = if results.any?
|
|
128
|
-
nested = []
|
|
129
|
-
results.each do |spec|
|
|
130
|
-
version, specs = nested.last
|
|
131
|
-
if version == spec.version
|
|
132
|
-
specs << spec
|
|
133
|
-
else
|
|
134
|
-
nested << [spec.version, [spec]]
|
|
135
|
-
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
|
|
136
121
|
end
|
|
137
|
-
nested.reduce([]) do |groups, (version, specs)|
|
|
138
|
-
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
|
139
|
-
|
|
140
|
-
specs_by_platform = Hash.new do |current_specs, current_platform|
|
|
141
|
-
current_specs[current_platform] = select_best_platform_match(specs, current_platform)
|
|
142
|
-
end
|
|
143
122
|
|
|
144
|
-
|
|
145
|
-
groups << spec_group_ruby if spec_group_ruby
|
|
123
|
+
next groups if @resolving_only_for_ruby || dependency.force_ruby_platform
|
|
146
124
|
|
|
147
|
-
|
|
125
|
+
platform_specs = relevant_platforms.flat_map {|platform| select_best_platform_match(specs, platform) }
|
|
126
|
+
next groups if platform_specs == ruby_specs
|
|
148
127
|
|
|
149
|
-
|
|
150
|
-
|
|
128
|
+
spec_group = SpecGroup.new(platform_specs, relevant_platforms)
|
|
129
|
+
groups << spec_group
|
|
151
130
|
|
|
152
|
-
|
|
153
|
-
end
|
|
154
|
-
else
|
|
155
|
-
[]
|
|
156
|
-
end
|
|
157
|
-
# GVP handles major itself, but it's still a bit risky to trust it with it
|
|
158
|
-
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
|
159
|
-
if !@use_gvp
|
|
160
|
-
spec_groups
|
|
161
|
-
else
|
|
162
|
-
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
|
131
|
+
groups
|
|
163
132
|
end
|
|
164
133
|
end
|
|
165
134
|
end
|
|
@@ -172,8 +141,8 @@ module Bundler
|
|
|
172
141
|
@source_requirements[name] || @source_requirements[:default]
|
|
173
142
|
end
|
|
174
143
|
|
|
175
|
-
def results_for(dependency
|
|
176
|
-
index_for(dependency).search(dependency
|
|
144
|
+
def results_for(dependency)
|
|
145
|
+
@results_for[dependency] ||= index_for(dependency).search(dependency)
|
|
177
146
|
end
|
|
178
147
|
|
|
179
148
|
def name_for(dependency)
|
|
@@ -186,43 +155,51 @@ module Bundler
|
|
|
186
155
|
"Gemfile"
|
|
187
156
|
end
|
|
188
157
|
|
|
189
|
-
def name_for_locking_dependency_source
|
|
190
|
-
Bundler.default_lockfile.basename.to_s
|
|
191
|
-
rescue StandardError
|
|
192
|
-
"Gemfile.lock"
|
|
193
|
-
end
|
|
194
|
-
|
|
195
158
|
def requirement_satisfied_by?(requirement, activated, spec)
|
|
196
159
|
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
|
197
160
|
end
|
|
198
161
|
|
|
199
|
-
def dependencies_equal?(dependencies, other_dependencies)
|
|
200
|
-
dependencies.map(&:dep) == other_dependencies.map(&:dep)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
162
|
def sort_dependencies(dependencies, activated, conflicts)
|
|
204
163
|
dependencies.sort_by do |dependency|
|
|
205
164
|
name = name_for(dependency)
|
|
206
165
|
vertex = activated.vertex_named(name)
|
|
207
166
|
[
|
|
208
|
-
@
|
|
167
|
+
@base[name].any? ? 0 : 1,
|
|
209
168
|
vertex.payload ? 0 : 1,
|
|
210
169
|
vertex.root? ? 0 : 1,
|
|
211
170
|
amount_constrained(dependency),
|
|
212
171
|
conflicts[name] ? 0 : 1,
|
|
213
172
|
vertex.payload ? 0 : search_for(dependency).count,
|
|
214
|
-
self.class.platform_sort_key(dependency.__platform),
|
|
215
173
|
]
|
|
216
174
|
end
|
|
217
175
|
end
|
|
218
176
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
177
|
+
private
|
|
178
|
+
|
|
179
|
+
def base_requirements
|
|
180
|
+
@base.base_requirements
|
|
223
181
|
end
|
|
224
182
|
|
|
225
|
-
|
|
183
|
+
def prerelease_specified
|
|
184
|
+
@gem_version_promoter.prerelease_specified
|
|
185
|
+
end
|
|
186
|
+
|
|
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
|
|
226
203
|
|
|
227
204
|
# returns an integer \in (-\infty, 0]
|
|
228
205
|
# a number closer to 0 means the dependency is less constraining
|
|
@@ -232,62 +209,60 @@ module Bundler
|
|
|
232
209
|
# before dependencies that are unconstrained
|
|
233
210
|
def amount_constrained(dependency)
|
|
234
211
|
@amount_constrained ||= {}
|
|
235
|
-
@amount_constrained[dependency.name] ||=
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
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
|
|
240
216
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
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
|
|
248
223
|
end
|
|
249
224
|
end
|
|
250
225
|
end
|
|
251
226
|
|
|
252
227
|
def verify_gemfile_dependencies_are_found!(requirements)
|
|
253
|
-
requirements.
|
|
228
|
+
requirements.map! do |requirement|
|
|
254
229
|
name = requirement.name
|
|
255
|
-
next if name == "bundler"
|
|
256
|
-
next
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"The bundle currently has #{name} locked at #{version}.\n" \
|
|
263
|
-
"Try running `bundle update #{name}`\n\n" \
|
|
264
|
-
"If you are updating multiple gems in your Gemfile at once,\n" \
|
|
265
|
-
"try passing them all to `bundle update`"
|
|
266
|
-
else
|
|
267
|
-
source = source_for(name)
|
|
268
|
-
specs = source.specs.search(name)
|
|
269
|
-
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
|
270
|
-
cache_message = begin
|
|
271
|
-
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
272
|
-
rescue GemfileNotFound
|
|
273
|
-
nil
|
|
274
|
-
end
|
|
275
|
-
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source.to_err}#{cache_message}.\n")
|
|
276
|
-
message << "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}" if versions_with_platforms.any?
|
|
277
|
-
end
|
|
278
|
-
raise GemNotFound, message
|
|
279
|
-
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!
|
|
280
237
|
end
|
|
281
238
|
|
|
282
|
-
def
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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")
|
|
289
263
|
end
|
|
290
|
-
|
|
264
|
+
|
|
265
|
+
message
|
|
291
266
|
end
|
|
292
267
|
|
|
293
268
|
def version_conflict_message(e)
|
|
@@ -305,29 +280,62 @@ module Bundler
|
|
|
305
280
|
|
|
306
281
|
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
|
|
307
282
|
|
|
308
|
-
solver_name = "Bundler"
|
|
309
|
-
possibility_type = "gem"
|
|
310
283
|
e.message_with_trees(
|
|
311
|
-
:
|
|
312
|
-
|
|
313
|
-
|
|
284
|
+
:full_message_for_conflict => lambda do |name, conflict|
|
|
285
|
+
trees = conflict.requirement_trees
|
|
286
|
+
|
|
314
287
|
# called first, because we want to reduce the amount of work required to find maximal empty sets
|
|
315
288
|
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
|
316
289
|
|
|
317
290
|
# bail out if tree size is too big for Array#combination to make any sense
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
+
|
|
331
339
|
if name == "bundler"
|
|
332
340
|
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
|
333
341
|
|
|
@@ -348,40 +356,23 @@ module Bundler
|
|
|
348
356
|
o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
349
357
|
end
|
|
350
358
|
end
|
|
351
|
-
elsif
|
|
352
|
-
o <<
|
|
353
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
|
354
|
-
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)
|
|
355
361
|
elsif !conflict.existing
|
|
356
362
|
o << "\n"
|
|
357
363
|
|
|
358
364
|
relevant_source = conflict.requirement.source || source_for(name)
|
|
359
365
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
o << "Could not find gem '" unless metadata_requirement
|
|
363
|
-
o << SharedHelpers.pretty_dependency(conflict.requirement)
|
|
364
|
-
o << "'" unless metadata_requirement
|
|
365
|
-
if conflict.requirement_trees.first.size > 1
|
|
366
|
-
o << ", which is required by "
|
|
367
|
-
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
|
368
|
-
end
|
|
369
|
-
o << " "
|
|
370
|
-
|
|
371
|
-
o << if metadata_requirement
|
|
372
|
-
"is not available in #{relevant_source}"
|
|
366
|
+
extra_message = if trees.first.size > 1
|
|
367
|
+
", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}',"
|
|
373
368
|
else
|
|
374
|
-
"
|
|
369
|
+
""
|
|
375
370
|
end
|
|
371
|
+
|
|
372
|
+
o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
|
|
376
373
|
end
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
:incompatible_version_message_for_conflict => lambda do |name, _conflict|
|
|
380
|
-
if name.end_with?("\0")
|
|
381
|
-
%(#{solver_name} found conflicting requirements for the #{name} version:)
|
|
382
|
-
else
|
|
383
|
-
%(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
|
|
384
|
-
end
|
|
374
|
+
|
|
375
|
+
o
|
|
385
376
|
end
|
|
386
377
|
)
|
|
387
378
|
end
|
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])
|