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/definition.rb
CHANGED
|
@@ -6,6 +6,11 @@ module Bundler
|
|
|
6
6
|
class Definition
|
|
7
7
|
include GemHelpers
|
|
8
8
|
|
|
9
|
+
class << self
|
|
10
|
+
# Do not create or modify a lockfile (Makes #lock a noop)
|
|
11
|
+
attr_accessor :no_lock
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
attr_reader(
|
|
10
15
|
:dependencies,
|
|
11
16
|
:locked_deps,
|
|
@@ -56,10 +61,8 @@ module Bundler
|
|
|
56
61
|
@unlocking_bundler = false
|
|
57
62
|
@unlocking = unlock
|
|
58
63
|
else
|
|
59
|
-
unlock = unlock.dup
|
|
60
64
|
@unlocking_bundler = unlock.delete(:bundler)
|
|
61
|
-
unlock.
|
|
62
|
-
@unlocking = !unlock.empty?
|
|
65
|
+
@unlocking = unlock.any? {|_k, v| !Array(v).empty? }
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
@dependencies = dependencies
|
|
@@ -67,6 +70,7 @@ module Bundler
|
|
|
67
70
|
@unlock = unlock
|
|
68
71
|
@optional_groups = optional_groups
|
|
69
72
|
@remote = false
|
|
73
|
+
@prefer_local = false
|
|
70
74
|
@specs = nil
|
|
71
75
|
@ruby_version = ruby_version
|
|
72
76
|
@gemfiles = gemfiles
|
|
@@ -75,7 +79,6 @@ module Bundler
|
|
|
75
79
|
@lockfile_contents = String.new
|
|
76
80
|
@locked_bundler_version = nil
|
|
77
81
|
@locked_ruby_version = nil
|
|
78
|
-
@locked_specs_incomplete_for_platform = false
|
|
79
82
|
@new_platform = nil
|
|
80
83
|
|
|
81
84
|
if lockfile && File.exist?(lockfile)
|
|
@@ -85,10 +88,11 @@ module Bundler
|
|
|
85
88
|
@platforms = @locked_platforms.dup
|
|
86
89
|
@locked_bundler_version = @locked_gems.bundler_version
|
|
87
90
|
@locked_ruby_version = @locked_gems.ruby_version
|
|
91
|
+
@originally_locked_specs = SpecSet.new(@locked_gems.specs)
|
|
88
92
|
|
|
89
93
|
if unlock != true
|
|
90
94
|
@locked_deps = @locked_gems.dependencies
|
|
91
|
-
@locked_specs =
|
|
95
|
+
@locked_specs = @originally_locked_specs
|
|
92
96
|
@locked_sources = @locked_gems.sources
|
|
93
97
|
else
|
|
94
98
|
@unlock = {}
|
|
@@ -102,11 +106,24 @@ module Bundler
|
|
|
102
106
|
@locked_gems = nil
|
|
103
107
|
@locked_deps = {}
|
|
104
108
|
@locked_specs = SpecSet.new([])
|
|
109
|
+
@originally_locked_specs = @locked_specs
|
|
105
110
|
@locked_sources = []
|
|
106
111
|
@locked_platforms = []
|
|
107
112
|
end
|
|
108
113
|
|
|
109
|
-
@
|
|
114
|
+
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
115
|
+
@multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
|
|
116
|
+
|
|
117
|
+
if @multisource_allowed
|
|
118
|
+
unless sources.aggregate_global_source?
|
|
119
|
+
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
|
|
120
|
+
|
|
121
|
+
Bundler::SharedHelpers.major_deprecation 2, msg
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
|
|
125
|
+
end
|
|
126
|
+
|
|
110
127
|
@unlock[:sources] ||= []
|
|
111
128
|
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
|
|
112
129
|
@ruby_version.diff(locked_ruby_version_object)
|
|
@@ -119,9 +136,11 @@ module Bundler
|
|
|
119
136
|
@path_changes = converge_paths
|
|
120
137
|
@source_changes = converge_sources
|
|
121
138
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
if @unlock[:conservative]
|
|
140
|
+
@unlock[:gems] ||= @dependencies.map(&:name)
|
|
141
|
+
else
|
|
142
|
+
eager_unlock = (@unlock[:gems] || []).map {|name| Dependency.new(name, ">= 0") }
|
|
143
|
+
@unlock[:gems] = @locked_specs.for(eager_unlock, false, platforms).map(&:name).uniq
|
|
125
144
|
end
|
|
126
145
|
|
|
127
146
|
@dependency_changes = converge_dependencies
|
|
@@ -131,31 +150,31 @@ module Bundler
|
|
|
131
150
|
end
|
|
132
151
|
|
|
133
152
|
def gem_version_promoter
|
|
134
|
-
@gem_version_promoter ||=
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
@gem_version_promoter ||= GemVersionPromoter.new(@originally_locked_specs, @unlock[:gems])
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def resolve_only_locally!
|
|
157
|
+
@remote = false
|
|
158
|
+
sources.local_only!
|
|
159
|
+
resolve
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def resolve_prefering_local!
|
|
163
|
+
@prefer_local = true
|
|
164
|
+
@remote = true
|
|
165
|
+
sources.remote!
|
|
166
|
+
resolve
|
|
146
167
|
end
|
|
147
168
|
|
|
148
169
|
def resolve_with_cache!
|
|
149
|
-
raise "Specs already loaded" if @specs
|
|
150
170
|
sources.cached!
|
|
151
|
-
|
|
171
|
+
resolve
|
|
152
172
|
end
|
|
153
173
|
|
|
154
174
|
def resolve_remotely!
|
|
155
|
-
return if @specs
|
|
156
175
|
@remote = true
|
|
157
176
|
sources.remote!
|
|
158
|
-
|
|
177
|
+
resolve
|
|
159
178
|
end
|
|
160
179
|
|
|
161
180
|
# For given dependency list returns a SpecSet with Gemspec of all the required
|
|
@@ -165,25 +184,7 @@ module Bundler
|
|
|
165
184
|
#
|
|
166
185
|
# @return [Bundler::SpecSet]
|
|
167
186
|
def specs
|
|
168
|
-
@specs ||=
|
|
169
|
-
begin
|
|
170
|
-
specs = resolve.materialize(requested_dependencies)
|
|
171
|
-
rescue GemNotFound => e # Handle yanked gem
|
|
172
|
-
gem_name, gem_version = extract_gem_info(e)
|
|
173
|
-
locked_gem = @locked_specs[gem_name].last
|
|
174
|
-
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
|
|
175
|
-
raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
|
|
176
|
-
"be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
|
|
177
|
-
"that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
|
|
178
|
-
"to a version other than #{locked_gem} that hasn't been removed in order to install."
|
|
179
|
-
end
|
|
180
|
-
unless specs["bundler"].any?
|
|
181
|
-
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
|
182
|
-
specs["bundler"] = bundler
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
specs
|
|
186
|
-
end
|
|
187
|
+
@specs ||= materialize(requested_dependencies)
|
|
187
188
|
end
|
|
188
189
|
|
|
189
190
|
def new_specs
|
|
@@ -195,9 +196,7 @@ module Bundler
|
|
|
195
196
|
end
|
|
196
197
|
|
|
197
198
|
def missing_specs
|
|
198
|
-
|
|
199
|
-
resolve.materialize(requested_dependencies, missing)
|
|
200
|
-
missing
|
|
199
|
+
resolve.materialize(requested_dependencies).missing_specs
|
|
201
200
|
end
|
|
202
201
|
|
|
203
202
|
def missing_specs?
|
|
@@ -206,8 +205,8 @@ module Bundler
|
|
|
206
205
|
Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
|
|
207
206
|
true
|
|
208
207
|
rescue BundlerError => e
|
|
209
|
-
@index = nil
|
|
210
208
|
@resolve = nil
|
|
209
|
+
@resolver = nil
|
|
211
210
|
@specs = nil
|
|
212
211
|
@gem_version_promoter = nil
|
|
213
212
|
|
|
@@ -216,31 +215,39 @@ module Bundler
|
|
|
216
215
|
end
|
|
217
216
|
|
|
218
217
|
def requested_specs
|
|
219
|
-
|
|
220
|
-
groups = requested_groups
|
|
221
|
-
groups.map!(&:to_sym)
|
|
222
|
-
specs_for(groups)
|
|
223
|
-
end
|
|
218
|
+
specs_for(requested_groups)
|
|
224
219
|
end
|
|
225
220
|
|
|
226
221
|
def requested_dependencies
|
|
227
|
-
|
|
228
|
-
groups.map!(&:to_sym)
|
|
229
|
-
dependencies_for(groups)
|
|
222
|
+
dependencies_for(requested_groups)
|
|
230
223
|
end
|
|
231
224
|
|
|
232
225
|
def current_dependencies
|
|
233
226
|
dependencies.select do |d|
|
|
234
|
-
d.should_include? && !d.gem_platforms(
|
|
227
|
+
d.should_include? && !d.gem_platforms([generic_local_platform]).empty?
|
|
235
228
|
end
|
|
236
229
|
end
|
|
237
230
|
|
|
231
|
+
def locked_dependencies
|
|
232
|
+
@locked_deps.values
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def new_deps
|
|
236
|
+
@new_deps ||= @dependencies - locked_dependencies
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def deleted_deps
|
|
240
|
+
@deleted_deps ||= locked_dependencies - @dependencies
|
|
241
|
+
end
|
|
242
|
+
|
|
238
243
|
def specs_for(groups)
|
|
244
|
+
return specs if groups.empty?
|
|
239
245
|
deps = dependencies_for(groups)
|
|
240
|
-
|
|
246
|
+
materialize(deps)
|
|
241
247
|
end
|
|
242
248
|
|
|
243
249
|
def dependencies_for(groups)
|
|
250
|
+
groups.map!(&:to_sym)
|
|
244
251
|
current_dependencies.reject do |d|
|
|
245
252
|
(d.groups & groups).empty?
|
|
246
253
|
end
|
|
@@ -252,70 +259,26 @@ module Bundler
|
|
|
252
259
|
#
|
|
253
260
|
# @return [SpecSet] resolved dependencies
|
|
254
261
|
def resolve
|
|
255
|
-
@resolve ||=
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
last_resolve
|
|
262
|
+
@resolve ||= if Bundler.frozen_bundle?
|
|
263
|
+
Bundler.ui.debug "Frozen, using resolution from the lockfile"
|
|
264
|
+
@locked_specs
|
|
265
|
+
elsif !unlocking? && nothing_changed?
|
|
266
|
+
if deleted_deps.any?
|
|
267
|
+
Bundler.ui.debug("Some dependencies were deleted, using a subset of the resolution from the lockfile")
|
|
268
|
+
SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
|
|
263
269
|
else
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def index
|
|
273
|
-
@index ||= Index.build do |idx|
|
|
274
|
-
dependency_names = @dependencies.map(&:name)
|
|
275
|
-
|
|
276
|
-
sources.all_sources.each do |source|
|
|
277
|
-
source.dependency_names = dependency_names - pinned_spec_names(source)
|
|
278
|
-
idx.add_source source.specs
|
|
279
|
-
dependency_names.concat(source.unmet_deps).uniq!
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
double_check_for_index(idx, dependency_names)
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
|
287
|
-
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
|
288
|
-
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
|
289
|
-
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
|
290
|
-
# each spec we found, we add all possible versions from all sources to the index.
|
|
291
|
-
def double_check_for_index(idx, dependency_names)
|
|
292
|
-
pinned_names = pinned_spec_names
|
|
293
|
-
loop do
|
|
294
|
-
idxcount = idx.size
|
|
295
|
-
|
|
296
|
-
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
|
297
|
-
unmet_dependency_names = lambda do
|
|
298
|
-
return names unless names == :names
|
|
299
|
-
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
|
300
|
-
return names = nil if new_names.compact!
|
|
301
|
-
names = new_names.flatten(1).concat(dependency_names)
|
|
302
|
-
names.uniq!
|
|
303
|
-
names -= pinned_names
|
|
304
|
-
names
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
sources.all_sources.each do |source|
|
|
308
|
-
source.double_check_for(unmet_dependency_names)
|
|
270
|
+
Bundler.ui.debug("Found no changes, using resolution from the lockfile")
|
|
271
|
+
if @locked_gems.may_include_redundant_platform_specific_gems?
|
|
272
|
+
SpecSet.new(filter_specs(@locked_specs, @dependencies))
|
|
273
|
+
else
|
|
274
|
+
@locked_specs
|
|
275
|
+
end
|
|
309
276
|
end
|
|
310
|
-
|
|
311
|
-
|
|
277
|
+
else
|
|
278
|
+
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
|
279
|
+
resolver.start(expanded_dependencies)
|
|
312
280
|
end
|
|
313
281
|
end
|
|
314
|
-
private :double_check_for_index
|
|
315
|
-
|
|
316
|
-
def has_rubygems_remotes?
|
|
317
|
-
sources.rubygems_sources.any? {|s| s.remotes.any? }
|
|
318
|
-
end
|
|
319
282
|
|
|
320
283
|
def spec_git_paths
|
|
321
284
|
sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
|
|
@@ -326,6 +289,8 @@ module Bundler
|
|
|
326
289
|
end
|
|
327
290
|
|
|
328
291
|
def lock(file, preserve_unknown_sections = false)
|
|
292
|
+
return if Definition.no_lock
|
|
293
|
+
|
|
329
294
|
contents = to_lock
|
|
330
295
|
|
|
331
296
|
# Convert to \r\n if the existing lock has them
|
|
@@ -336,10 +301,7 @@ module Bundler
|
|
|
336
301
|
locked_major = @locked_bundler_version.segments.first
|
|
337
302
|
current_major = Gem::Version.create(Bundler::VERSION).segments.first
|
|
338
303
|
|
|
339
|
-
|
|
340
|
-
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
|
|
341
|
-
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
|
|
342
|
-
end
|
|
304
|
+
updating_major = locked_major < current_major
|
|
343
305
|
end
|
|
344
306
|
|
|
345
307
|
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
@@ -356,14 +318,6 @@ module Bundler
|
|
|
356
318
|
end
|
|
357
319
|
end
|
|
358
320
|
|
|
359
|
-
def locked_bundler_version
|
|
360
|
-
if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
|
|
361
|
-
new_version = Bundler::VERSION
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
new_version || @locked_bundler_version || Bundler::VERSION
|
|
365
|
-
end
|
|
366
|
-
|
|
367
321
|
def locked_ruby_version
|
|
368
322
|
return unless ruby_version
|
|
369
323
|
if @unlock[:ruby] || !@locked_ruby_version
|
|
@@ -403,7 +357,7 @@ module Bundler
|
|
|
403
357
|
"bundle config unset deployment"
|
|
404
358
|
end
|
|
405
359
|
msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
|
|
406
|
-
"freeze \nby running `#{suggested_command}`."
|
|
360
|
+
"freeze \nby running `#{suggested_command}`." if suggested_command
|
|
407
361
|
end
|
|
408
362
|
|
|
409
363
|
added = []
|
|
@@ -415,44 +369,28 @@ module Bundler
|
|
|
415
369
|
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
|
416
370
|
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
|
417
371
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
new_sources = gemfile_sources - @locked_sources
|
|
421
|
-
deleted_sources = @locked_sources - gemfile_sources
|
|
422
|
-
|
|
423
|
-
new_deps = @dependencies - @locked_deps.values
|
|
424
|
-
deleted_deps = @locked_deps.values - @dependencies
|
|
372
|
+
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
|
373
|
+
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
|
425
374
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
429
|
-
deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
430
|
-
end
|
|
375
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
|
376
|
+
@dependencies.each {|d| both_sources[d.name][0] = d }
|
|
431
377
|
|
|
432
|
-
|
|
433
|
-
if
|
|
434
|
-
added.concat new_sources.map {|source| "* source: #{source}" }
|
|
435
|
-
end
|
|
378
|
+
locked_dependencies.each do |d|
|
|
379
|
+
next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty?
|
|
436
380
|
|
|
437
|
-
|
|
438
|
-
deleted.concat deleted_sources.map {|source| "* source: #{source}" }
|
|
439
|
-
end
|
|
381
|
+
both_sources[d.name][1] = d
|
|
440
382
|
end
|
|
441
383
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
|
|
445
|
-
end
|
|
384
|
+
both_sources.each do |name, (dep, lock_dep)|
|
|
385
|
+
next if dep.nil? || lock_dep.nil?
|
|
446
386
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
387
|
+
gemfile_source = dep.source || sources.default_source
|
|
388
|
+
lock_source = lock_dep.source || sources.default_source
|
|
389
|
+
next if lock_source.include?(gemfile_source)
|
|
450
390
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
lockfile_source_name = lock_source
|
|
455
|
-
changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
|
|
391
|
+
gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source"
|
|
392
|
+
lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
|
|
393
|
+
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
|
|
456
394
|
end
|
|
457
395
|
|
|
458
396
|
reason = change_reason
|
|
@@ -500,7 +438,7 @@ module Bundler
|
|
|
500
438
|
|
|
501
439
|
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
|
|
502
440
|
"but your local platform is #{Bundler.local_platform}. " \
|
|
503
|
-
"Add the current platform to the lockfile with
|
|
441
|
+
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again."
|
|
504
442
|
end
|
|
505
443
|
|
|
506
444
|
def add_platform(platform)
|
|
@@ -519,19 +457,11 @@ module Bundler
|
|
|
519
457
|
end
|
|
520
458
|
end
|
|
521
459
|
|
|
522
|
-
def find_resolved_spec(current_spec)
|
|
523
|
-
specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
def find_indexed_specs(current_spec)
|
|
527
|
-
index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
|
|
528
|
-
end
|
|
529
|
-
|
|
530
460
|
attr_reader :sources
|
|
531
461
|
private :sources
|
|
532
462
|
|
|
533
463
|
def nothing_changed?
|
|
534
|
-
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
|
|
464
|
+
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
|
|
535
465
|
end
|
|
536
466
|
|
|
537
467
|
def unlocking?
|
|
@@ -540,8 +470,78 @@ module Bundler
|
|
|
540
470
|
|
|
541
471
|
private
|
|
542
472
|
|
|
473
|
+
def resolver
|
|
474
|
+
@resolver ||= begin
|
|
475
|
+
last_resolve = converge_locked_specs
|
|
476
|
+
remove_ruby_from_platforms_if_necessary!(current_dependencies)
|
|
477
|
+
Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve(last_resolve), platforms)
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def expanded_dependencies
|
|
482
|
+
@expanded_dependencies ||= dependencies + metadata_dependencies
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def filter_specs(specs, deps)
|
|
486
|
+
SpecSet.new(specs).for(deps, false, platforms)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def materialize(dependencies)
|
|
490
|
+
specs = resolve.materialize(dependencies)
|
|
491
|
+
missing_specs = specs.missing_specs
|
|
492
|
+
|
|
493
|
+
if missing_specs.any?
|
|
494
|
+
missing_specs.each do |s|
|
|
495
|
+
locked_gem = @locked_specs[s.name].last
|
|
496
|
+
next if locked_gem.nil? || locked_gem.version != s.version || !@remote
|
|
497
|
+
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
|
|
498
|
+
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
|
|
499
|
+
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
|
|
500
|
+
"removed in order to install."
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|
|
|
504
|
+
"#{missing_specs_for_source.map(&:full_name).join(", ")} in #{source}"
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
loop do
|
|
511
|
+
incomplete_specs = specs.incomplete_specs
|
|
512
|
+
break if incomplete_specs.empty?
|
|
513
|
+
|
|
514
|
+
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
|
|
515
|
+
@resolve = resolver.start(expanded_dependencies, :exclude_specs => incomplete_specs)
|
|
516
|
+
specs = resolve.materialize(dependencies)
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
|
520
|
+
specs["bundler"] = bundler
|
|
521
|
+
|
|
522
|
+
specs
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def precompute_source_requirements_for_indirect_dependencies?
|
|
526
|
+
@remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def pin_locally_available_names(source_requirements)
|
|
530
|
+
source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements|
|
|
531
|
+
local_source = original_source.dup
|
|
532
|
+
local_source.local_only!
|
|
533
|
+
|
|
534
|
+
new_source_requirements[name] = if local_source.specs.search(name).any?
|
|
535
|
+
local_source
|
|
536
|
+
else
|
|
537
|
+
original_source
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
543
542
|
def current_ruby_platform_locked?
|
|
544
543
|
return false unless generic_local_platform == Gem::Platform::RUBY
|
|
544
|
+
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
|
|
545
545
|
|
|
546
546
|
current_platform_locked?
|
|
547
547
|
end
|
|
@@ -574,12 +574,11 @@ module Bundler
|
|
|
574
574
|
[@new_platform, "you added a new platform to your gemfile"],
|
|
575
575
|
[@path_changes, "the gemspecs for path gems changed"],
|
|
576
576
|
[@local_changes, "the gemspecs for git local gems changed"],
|
|
577
|
-
[@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"],
|
|
578
577
|
].select(&:first).map(&:last).join(", ")
|
|
579
578
|
end
|
|
580
579
|
|
|
581
|
-
def pretty_dep(dep
|
|
582
|
-
SharedHelpers.pretty_dependency(dep
|
|
580
|
+
def pretty_dep(dep)
|
|
581
|
+
SharedHelpers.pretty_dependency(dep)
|
|
583
582
|
end
|
|
584
583
|
|
|
585
584
|
# Check if the specs of the given source changed
|
|
@@ -592,9 +591,9 @@ module Bundler
|
|
|
592
591
|
|
|
593
592
|
def dependencies_for_source_changed?(source, locked_source = source)
|
|
594
593
|
deps_for_source = @dependencies.select {|s| s.source == source }
|
|
595
|
-
locked_deps_for_source =
|
|
594
|
+
locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
|
|
596
595
|
|
|
597
|
-
deps_for_source.sort != locked_deps_for_source.sort
|
|
596
|
+
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
|
598
597
|
end
|
|
599
598
|
|
|
600
599
|
def specs_for_source_changed?(source)
|
|
@@ -653,36 +652,11 @@ module Bundler
|
|
|
653
652
|
end
|
|
654
653
|
end
|
|
655
654
|
|
|
656
|
-
def converge_rubygems_sources
|
|
657
|
-
return false if Bundler.feature_flag.disable_multisource?
|
|
658
|
-
|
|
659
|
-
changes = false
|
|
660
|
-
|
|
661
|
-
# Get the RubyGems sources from the Gemfile.lock
|
|
662
|
-
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
663
|
-
# Get the RubyGems remotes from the Gemfile
|
|
664
|
-
actual_remotes = sources.rubygems_remotes
|
|
665
|
-
|
|
666
|
-
# If there is a RubyGems source in both
|
|
667
|
-
if !locked_gem_sources.empty? && !actual_remotes.empty?
|
|
668
|
-
locked_gem_sources.each do |locked_gem|
|
|
669
|
-
# Merge the remotes from the Gemfile into the Gemfile.lock
|
|
670
|
-
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
|
671
|
-
end
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
changes
|
|
675
|
-
end
|
|
676
|
-
|
|
677
655
|
def converge_sources
|
|
678
|
-
changes = false
|
|
679
|
-
|
|
680
|
-
changes |= converge_rubygems_sources
|
|
681
|
-
|
|
682
656
|
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
|
683
657
|
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
|
|
684
658
|
# source in the Gemfile.lock, use the one from the Gemfile.
|
|
685
|
-
changes
|
|
659
|
+
changes = sources.replace_sources!(@locked_sources)
|
|
686
660
|
|
|
687
661
|
sources.all_sources.each do |source|
|
|
688
662
|
# If the source is unlockable and the current command allows an unlock of
|
|
@@ -700,25 +674,14 @@ module Bundler
|
|
|
700
674
|
end
|
|
701
675
|
|
|
702
676
|
def converge_dependencies
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
# after locked_source and sources don't match, we still use locked_source.
|
|
708
|
-
if frozen && !locked_source.nil? &&
|
|
709
|
-
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
|
710
|
-
dep.source = locked_source.source
|
|
711
|
-
elsif dep.source
|
|
677
|
+
changes = false
|
|
678
|
+
|
|
679
|
+
@dependencies.each do |dep|
|
|
680
|
+
if dep.source
|
|
712
681
|
dep.source = sources.get(dep.source)
|
|
713
682
|
end
|
|
714
|
-
end
|
|
715
683
|
|
|
716
|
-
|
|
717
|
-
# We want to know if all match, but don't want to check all entries
|
|
718
|
-
# This means we need to return false if any dependency doesn't match
|
|
719
|
-
# the lock or doesn't exist in the lock.
|
|
720
|
-
@dependencies.each do |dependency|
|
|
721
|
-
unless locked_dep = @locked_deps[dependency.name]
|
|
684
|
+
unless locked_dep = @locked_deps[dep.name]
|
|
722
685
|
changes = true
|
|
723
686
|
next
|
|
724
687
|
end
|
|
@@ -729,11 +692,11 @@ module Bundler
|
|
|
729
692
|
# directive, the lockfile dependencies and resolved dependencies end up
|
|
730
693
|
# with a mismatch on #type. Work around that by setting the type on the
|
|
731
694
|
# dep from the lockfile.
|
|
732
|
-
locked_dep.instance_variable_set(:@type,
|
|
695
|
+
locked_dep.instance_variable_set(:@type, dep.type)
|
|
733
696
|
|
|
734
697
|
# We already know the name matches from the hash lookup
|
|
735
698
|
# so we only need to check the requirement now
|
|
736
|
-
changes ||=
|
|
699
|
+
changes ||= dep.requirement != locked_dep.requirement
|
|
737
700
|
end
|
|
738
701
|
|
|
739
702
|
changes
|
|
@@ -743,50 +706,50 @@ module Bundler
|
|
|
743
706
|
# commonly happen if the Gemfile has changed since the lockfile was last
|
|
744
707
|
# generated
|
|
745
708
|
def converge_locked_specs
|
|
746
|
-
|
|
709
|
+
converged = converge_specs(@locked_specs)
|
|
747
710
|
|
|
748
|
-
|
|
749
|
-
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
|
750
|
-
# the gem in the Gemfile.lock still satisfies it, this is fine
|
|
751
|
-
# too.
|
|
752
|
-
@dependencies.each do |dep|
|
|
753
|
-
locked_dep = @locked_deps[dep.name]
|
|
711
|
+
resolve = SpecSet.new(converged.reject {|s| @unlock[:gems].include?(s.name) })
|
|
754
712
|
|
|
755
|
-
|
|
756
|
-
locked_dep = nil unless locked_dep == dep
|
|
713
|
+
diff = nil
|
|
757
714
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
@locked_specs.each do |s|
|
|
762
|
-
@unlock[:gems] << s.name if s.source == dep.source
|
|
763
|
-
end
|
|
715
|
+
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
716
|
+
sources.all_sources.each do |source|
|
|
717
|
+
next unless source.respond_to?(:unlock!)
|
|
764
718
|
|
|
765
|
-
|
|
766
|
-
|
|
719
|
+
unless resolve.any? {|s| s.source == source }
|
|
720
|
+
diff ||= @locked_specs.to_a - resolve.to_a
|
|
721
|
+
source.unlock! if diff.any? {|s| s.source == source }
|
|
767
722
|
end
|
|
768
723
|
end
|
|
769
724
|
|
|
770
|
-
|
|
725
|
+
resolve
|
|
726
|
+
end
|
|
771
727
|
|
|
728
|
+
def converge_specs(specs)
|
|
772
729
|
converged = []
|
|
773
|
-
|
|
774
|
-
|
|
730
|
+
|
|
731
|
+
deps = @dependencies.select do |dep|
|
|
732
|
+
specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
@specs_that_changed_sources = []
|
|
736
|
+
|
|
737
|
+
specs.each do |s|
|
|
775
738
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
|
776
|
-
s.source = (dep && dep.source) || sources.get(s.source)
|
|
777
739
|
|
|
778
|
-
#
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
740
|
+
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
|
741
|
+
s.source = if dep && dep.source
|
|
742
|
+
gemfile_source = dep.source
|
|
743
|
+
lockfile_source = s.source
|
|
782
744
|
|
|
783
|
-
|
|
784
|
-
# unlock a single gem by passing its name via `--source`. See issue #3759
|
|
785
|
-
# TODO: delete in Bundler 2
|
|
786
|
-
next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
|
|
745
|
+
@specs_that_changed_sources << s if gemfile_source != lockfile_source
|
|
787
746
|
|
|
788
|
-
|
|
789
|
-
|
|
747
|
+
gemfile_source
|
|
748
|
+
else
|
|
749
|
+
sources.get_with_fallback(s.source)
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
next if @unlock[:sources].include?(s.source.name)
|
|
790
753
|
|
|
791
754
|
# Path sources have special logic
|
|
792
755
|
if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
|
|
@@ -795,8 +758,8 @@ module Bundler
|
|
|
795
758
|
rescue PathError, GitError
|
|
796
759
|
# if we won't need the source (according to the lockfile),
|
|
797
760
|
# don't error if the path/git source isn't available
|
|
798
|
-
next if
|
|
799
|
-
for(requested_dependencies,
|
|
761
|
+
next if specs.
|
|
762
|
+
for(requested_dependencies, false).
|
|
800
763
|
none? {|locked_spec| locked_spec.source == s.source }
|
|
801
764
|
|
|
802
765
|
raise
|
|
@@ -811,116 +774,56 @@ module Bundler
|
|
|
811
774
|
s.dependencies.replace(new_spec.dependencies)
|
|
812
775
|
end
|
|
813
776
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
|
|
819
|
-
resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
|
|
820
|
-
diff = nil
|
|
821
|
-
|
|
822
|
-
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
823
|
-
sources.all_sources.each do |source|
|
|
824
|
-
next unless source.respond_to?(:unlock!)
|
|
825
|
-
|
|
826
|
-
unless resolve.any? {|s| s.source == source }
|
|
827
|
-
diff ||= @locked_specs.to_a - resolve.to_a
|
|
828
|
-
source.unlock! if diff.any? {|s| s.source == source }
|
|
777
|
+
if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
|
|
778
|
+
@unlock[:gems] << s.name
|
|
779
|
+
else
|
|
780
|
+
converged << s
|
|
829
781
|
end
|
|
830
782
|
end
|
|
831
783
|
|
|
832
|
-
|
|
833
|
-
end
|
|
834
|
-
|
|
835
|
-
def in_locked_deps?(dep, locked_dep)
|
|
836
|
-
# Because the lockfile can't link a dep to a specific remote, we need to
|
|
837
|
-
# treat sources as equivalent anytime the locked dep has all the remotes
|
|
838
|
-
# that the Gemfile dep does.
|
|
839
|
-
locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
def satisfies_locked_spec?(dep)
|
|
843
|
-
@locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
|
784
|
+
filter_specs(converged, deps)
|
|
844
785
|
end
|
|
845
786
|
|
|
846
787
|
def metadata_dependencies
|
|
847
|
-
@metadata_dependencies ||=
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
Dependency.new("RubyGems\0", Gem::VERSION),
|
|
852
|
-
]
|
|
853
|
-
end
|
|
854
|
-
end
|
|
855
|
-
|
|
856
|
-
def ruby_version_requirements(ruby_version)
|
|
857
|
-
return [] unless ruby_version
|
|
858
|
-
if ruby_version.patchlevel
|
|
859
|
-
[ruby_version.to_gem_version_with_patchlevel]
|
|
860
|
-
else
|
|
861
|
-
ruby_version.versions.map do |version|
|
|
862
|
-
requirement = Gem::Requirement.new(version)
|
|
863
|
-
if requirement.exact?
|
|
864
|
-
"~> #{version}.0"
|
|
865
|
-
else
|
|
866
|
-
requirement
|
|
867
|
-
end
|
|
868
|
-
end
|
|
869
|
-
end
|
|
870
|
-
end
|
|
871
|
-
|
|
872
|
-
def expand_dependencies(dependencies, remote = false)
|
|
873
|
-
deps = []
|
|
874
|
-
dependencies.each do |dep|
|
|
875
|
-
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
|
|
876
|
-
next unless remote || dep.current_platform?
|
|
877
|
-
target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
|
|
878
|
-
deps += expand_dependency_with_platforms(dep, target_platforms)
|
|
879
|
-
end
|
|
880
|
-
deps
|
|
881
|
-
end
|
|
882
|
-
|
|
883
|
-
def expand_dependency_with_platforms(dep, platforms)
|
|
884
|
-
platforms.map do |p|
|
|
885
|
-
DepProxy.get_proxy(dep, p)
|
|
886
|
-
end
|
|
788
|
+
@metadata_dependencies ||= [
|
|
789
|
+
Dependency.new("Ruby\0", Gem.ruby_version),
|
|
790
|
+
Dependency.new("RubyGems\0", Gem::VERSION),
|
|
791
|
+
]
|
|
887
792
|
end
|
|
888
793
|
|
|
889
794
|
def source_requirements
|
|
890
|
-
# Load all specs from remote sources
|
|
891
|
-
index
|
|
892
|
-
|
|
893
795
|
# Record the specs available in each gem's source, so that those
|
|
894
796
|
# specs will be available later when the resolver knows where to
|
|
895
797
|
# look for that gemspec (or its dependencies)
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
798
|
+
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
|
|
799
|
+
all_requirements = source_map.all_requirements
|
|
800
|
+
all_requirements = pin_locally_available_names(all_requirements) if @prefer_local
|
|
801
|
+
{ :default => sources.default_source }.merge(all_requirements)
|
|
802
|
+
else
|
|
803
|
+
{ :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
|
|
902
804
|
end
|
|
805
|
+
source_requirements.merge!(source_map.locked_requirements) unless @remote
|
|
903
806
|
metadata_dependencies.each do |dep|
|
|
904
807
|
source_requirements[dep.name] = sources.metadata_source
|
|
905
808
|
end
|
|
906
|
-
source_requirements[:default_bundler] = source_requirements["bundler"] ||
|
|
809
|
+
source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
|
|
907
810
|
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
|
811
|
+
verify_changed_sources!
|
|
908
812
|
source_requirements
|
|
909
813
|
end
|
|
910
814
|
|
|
911
|
-
def
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
next if dep_source == skip
|
|
917
|
-
pinned_names << dep.name
|
|
815
|
+
def verify_changed_sources!
|
|
816
|
+
@specs_that_changed_sources.each do |s|
|
|
817
|
+
if s.source.specs.search(s.name).empty?
|
|
818
|
+
raise GemNotFound, "Could not find gem '#{s.name}' in #{s.source}"
|
|
819
|
+
end
|
|
918
820
|
end
|
|
919
|
-
pinned_names
|
|
920
821
|
end
|
|
921
822
|
|
|
922
823
|
def requested_groups
|
|
923
|
-
groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
|
824
|
+
values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
|
825
|
+
values &= Bundler.settings[:only] unless Bundler.settings[:only].empty?
|
|
826
|
+
values
|
|
924
827
|
end
|
|
925
828
|
|
|
926
829
|
def lockfiles_equal?(current, proposed, preserve_unknown_sections)
|
|
@@ -936,12 +839,6 @@ module Bundler
|
|
|
936
839
|
current == proposed
|
|
937
840
|
end
|
|
938
841
|
|
|
939
|
-
def extract_gem_info(error)
|
|
940
|
-
# This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
|
|
941
|
-
# to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
|
|
942
|
-
error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
|
|
943
|
-
end
|
|
944
|
-
|
|
945
842
|
def compute_requires
|
|
946
843
|
dependencies.reduce({}) do |requires, dep|
|
|
947
844
|
next requires unless dep.should_include?
|
|
@@ -953,25 +850,26 @@ module Bundler
|
|
|
953
850
|
end
|
|
954
851
|
end
|
|
955
852
|
|
|
956
|
-
def additional_base_requirements_for_resolve
|
|
957
|
-
return [] unless @locked_gems &&
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
dependency = dependencies_by_name[name]
|
|
962
|
-
next requirements unless dependency
|
|
963
|
-
next requirements if @locked_gems.dependencies[name] != dependency
|
|
964
|
-
next requirements if dependency.source.is_a?(Source::Path)
|
|
965
|
-
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
|
966
|
-
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
|
|
967
|
-
requirements
|
|
968
|
-
end.values
|
|
853
|
+
def additional_base_requirements_for_resolve(last_resolve)
|
|
854
|
+
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
|
|
855
|
+
converge_specs(@originally_locked_specs - last_resolve).map do |locked_spec|
|
|
856
|
+
Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
|
|
857
|
+
end.uniq
|
|
969
858
|
end
|
|
970
859
|
|
|
971
|
-
def
|
|
972
|
-
return
|
|
860
|
+
def remove_ruby_from_platforms_if_necessary!(dependencies)
|
|
861
|
+
return if Bundler.frozen_bundle? ||
|
|
862
|
+
Bundler.local_platform == Gem::Platform::RUBY ||
|
|
863
|
+
!platforms.include?(Gem::Platform::RUBY) ||
|
|
864
|
+
(@new_platform && platforms.last == Gem::Platform::RUBY) ||
|
|
865
|
+
!@originally_locked_specs.incomplete_ruby_specs?(dependencies)
|
|
866
|
+
|
|
867
|
+
remove_platform(Gem::Platform::RUBY)
|
|
868
|
+
add_current_platform
|
|
869
|
+
end
|
|
973
870
|
|
|
974
|
-
|
|
871
|
+
def source_map
|
|
872
|
+
@source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
|
|
975
873
|
end
|
|
976
874
|
end
|
|
977
875
|
end
|