bundler 4.0.21 → 4.1.0.beta1
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/{lib/bundler/vendor/connection_pool/LICENSE → MIT.txt} +8 -6
- data/bundler.gemspec +23 -6
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/checksum.rb +40 -25
- data/lib/bundler/ci_detector.rb +1 -1
- data/lib/bundler/cli/add.rb +3 -4
- data/lib/bundler/cli/cache.rb +4 -0
- data/lib/bundler/cli/clean.rb +5 -0
- data/lib/bundler/cli/common.rb +37 -1
- data/lib/bundler/cli/config.rb +4 -2
- data/lib/bundler/cli/gem.rb +0 -17
- data/lib/bundler/cli/install.rb +4 -5
- data/lib/bundler/cli/lock.rb +1 -2
- data/lib/bundler/cli/outdated.rb +8 -3
- data/lib/bundler/cli/pristine.rb +2 -1
- data/lib/bundler/cli/update.rb +21 -12
- data/lib/bundler/cli.rb +14 -11
- data/lib/bundler/definition.rb +61 -24
- data/lib/bundler/dependency.rb +4 -0
- data/lib/bundler/dsl.rb +77 -11
- data/lib/bundler/endpoint_specification.rb +51 -14
- data/lib/bundler/env.rb +7 -24
- data/lib/bundler/errors.rb +34 -5
- data/lib/bundler/fetcher/compact_index.rb +14 -5
- data/lib/bundler/fetcher/connection_pools.rb +150 -0
- data/lib/bundler/fetcher/downloader.rb +31 -16
- data/lib/bundler/fetcher.rb +8 -47
- data/lib/bundler/injector.rb +3 -3
- data/lib/bundler/inline.rb +44 -4
- data/lib/bundler/installer/parallel_installer.rb +25 -30
- data/lib/bundler/installer.rb +20 -6
- data/lib/bundler/lazy_specification.rb +44 -17
- data/lib/bundler/lockfile_generator.rb +24 -2
- data/lib/bundler/lockfile_parser.rb +43 -5
- data/lib/bundler/man/bundle-add.1 +7 -4
- data/lib/bundler/man/bundle-add.1.ronn +8 -4
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +2 -2
- data/lib/bundler/man/bundle-cache.1.ronn +2 -2
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +38 -6
- data/lib/bundler/man/bundle-config.1.ronn +143 -10
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +1 -1
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +2 -2
- data/lib/bundler/man/bundle-install.1.ronn +4 -4
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +3 -3
- data/lib/bundler/man/bundle-lock.1.ronn +5 -5
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +3 -3
- data/lib/bundler/man/bundle-update.1.ronn +3 -5
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +45 -1
- data/lib/bundler/man/gemfile.5.ronn +53 -0
- data/lib/bundler/match_metadata.rb +20 -0
- data/lib/bundler/match_platform.rb +25 -2
- data/lib/bundler/match_remote_metadata.rb +21 -6
- data/lib/bundler/materialization.rb +2 -1
- data/lib/bundler/override.rb +69 -0
- data/lib/bundler/plugin/dsl.rb +3 -5
- data/lib/bundler/plugin/events.rb +55 -13
- data/lib/bundler/plugin/index.rb +87 -11
- data/lib/bundler/plugin/installer/path.rb +1 -1
- data/lib/bundler/plugin/installer.rb +13 -5
- data/lib/bundler/plugin.rb +58 -30
- data/lib/bundler/remote_specification.rb +6 -3
- data/lib/bundler/resolver/base.rb +2 -1
- data/lib/bundler/resolver/incompatibility.rb +1 -1
- data/lib/bundler/resolver.rb +73 -23
- data/lib/bundler/ruby_version.rb +0 -2
- data/lib/bundler/rubygems_ext.rb +71 -1
- data/lib/bundler/rubygems_gem_installer.rb +41 -2
- data/lib/bundler/rubygems_integration.rb +7 -2
- data/lib/bundler/runtime.rb +69 -2
- data/lib/bundler/self_manager.rb +9 -15
- data/lib/bundler/settings.rb +373 -30
- data/lib/bundler/shared_helpers.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +2 -10
- data/lib/bundler/source/git.rb +15 -6
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/rubygems/remote.rb +10 -5
- data/lib/bundler/source/rubygems.rb +48 -12
- data/lib/bundler/spec_set.rb +16 -4
- data/lib/bundler/stub_specification.rb +2 -1
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -3
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
- data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +1 -1
- data/lib/bundler/ui/shell.rb +0 -4
- data/lib/bundler/ui/silent.rb +0 -4
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
- data/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +34 -1
- data/lib/bundler/vendored_pub_grub.rb +5 -2
- data/lib/bundler/vendored_securerandom.rb +11 -8
- data/lib/bundler/vendored_uri.rb +14 -14
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +3 -2
- data/lib/bundler.rb +1 -1
- data/lib/rubygems/compact_index_client/cache.rb +122 -0
- data/lib/rubygems/compact_index_client/cache_file.rb +147 -0
- data/lib/rubygems/compact_index_client/http_fetcher.rb +88 -0
- data/lib/rubygems/compact_index_client/parser.rb +90 -0
- data/lib/rubygems/compact_index_client/updater.rb +113 -0
- data/lib/rubygems/compact_index_client.rb +111 -0
- data/lib/rubygems/cooldown_settings.rb +57 -0
- data/lib/rubygems/credential_store/native/linux.rb +97 -0
- data/lib/rubygems/credential_store/native/macos.rb +88 -0
- data/lib/rubygems/credential_store/native/windows.rb +130 -0
- data/lib/rubygems/credential_store.rb +332 -0
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/assignment.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +7 -7
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/failure_writer.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/incompatibility.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/package.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/partial_solution.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/rubygems.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/solve_failure.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/static_package_source.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/strategy.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/term.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_constraint.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_range.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_solver.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_union.rb +1 -1
- data/lib/rubygems/vendor/pub_grub/lib/pub_grub.rb +57 -0
- data/lib/{bundler → rubygems}/vendor/securerandom/lib/securerandom.rb +10 -6
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/common.rb +119 -119
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/file.rb +13 -13
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ftp.rb +24 -24
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/generic.rb +132 -132
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/http.rb +18 -18
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/https.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldap.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldaps.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/mailto.rb +21 -21
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc2396_parser.rb +39 -39
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc3986_parser.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ws.rb +12 -12
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/wss.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri.rb +35 -31
- data/lib/rubygems/yaml_serializer.rb +880 -0
- metadata +77 -68
- data/CHANGELOG.md +0 -5784
- data/LICENSE.md +0 -22
- data/README.md +0 -58
- data/lib/bundler/compact_index_client/cache.rb +0 -107
- data/lib/bundler/compact_index_client/cache_file.rb +0 -148
- data/lib/bundler/compact_index_client/parser.rb +0 -87
- data/lib/bundler/compact_index_client/updater.rb +0 -105
- data/lib/bundler/compact_index_client.rb +0 -92
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +0 -227
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +0 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -56
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +0 -230
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +0 -82
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +0 -41
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +0 -65
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +0 -80
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +0 -1153
- data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +0 -31
- data/lib/bundler/vendored_persistent.rb +0 -11
- data/lib/bundler/yaml_serializer.rb +0 -98
- /data/lib/{bundler → rubygems}/vendor/pub_grub/LICENSE.txt +0 -0
- /data/lib/{bundler → rubygems}/vendor/securerandom/COPYING +0 -0
- /data/lib/{bundler → rubygems}/vendor/uri/COPYING +0 -0
data/lib/bundler/plugin.rb
CHANGED
|
@@ -18,6 +18,14 @@ module Bundler
|
|
|
18
18
|
|
|
19
19
|
PLUGIN_FILE_NAME = "plugins.rb"
|
|
20
20
|
|
|
21
|
+
# Module-level flag set while .gemfile_install parses the Gemfile and
|
|
22
|
+
# consulted by .from_lock to substitute plugin sources with
|
|
23
|
+
# UnloadedSource. It relies on definitions being built one at a time in
|
|
24
|
+
# a single thread; if they are ever built concurrently or reentrantly,
|
|
25
|
+
# this needs to be replaced by explicit state passed down to the
|
|
26
|
+
# lockfile parser.
|
|
27
|
+
@gemfile_parse = false
|
|
28
|
+
|
|
21
29
|
module_function
|
|
22
30
|
|
|
23
31
|
def reset!
|
|
@@ -27,6 +35,7 @@ module Bundler
|
|
|
27
35
|
@commands = {}
|
|
28
36
|
@hooks_by_event = Hash.new {|h, k| h[k] = [] }
|
|
29
37
|
@loaded_plugin_names = []
|
|
38
|
+
@index = nil
|
|
30
39
|
end
|
|
31
40
|
|
|
32
41
|
reset!
|
|
@@ -41,7 +50,7 @@ module Bundler
|
|
|
41
50
|
|
|
42
51
|
specs = Installer.new.install(names, options)
|
|
43
52
|
|
|
44
|
-
save_plugins names
|
|
53
|
+
save_plugins specs.slice(*names)
|
|
45
54
|
rescue PluginError
|
|
46
55
|
specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
|
|
47
56
|
specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
|
|
@@ -101,29 +110,44 @@ module Bundler
|
|
|
101
110
|
#
|
|
102
111
|
# @param [Pathname] gemfile path
|
|
103
112
|
# @param [Proc] block that can be evaluated for (inline) Gemfile
|
|
104
|
-
def gemfile_install(gemfile = nil, &inline)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return if definition.dependencies.empty?
|
|
113
|
+
def gemfile_install(gemfile = nil, lockfile = nil, unlock = {}, &inline)
|
|
114
|
+
@gemfile_parse = true
|
|
115
|
+
Bundler.configure
|
|
116
|
+
builder = DSL.new
|
|
117
|
+
if block_given?
|
|
118
|
+
builder.instance_eval(&inline)
|
|
119
|
+
else
|
|
120
|
+
builder.eval_gemfile(gemfile)
|
|
121
|
+
end
|
|
122
|
+
builder.check_primary_source_safety
|
|
116
123
|
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
plugins = builder.dependencies.map(&:name)
|
|
125
|
+
return if plugins.empty?
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
# skip the update if unlocking specific gems, but none of them are plugins
|
|
128
|
+
# declared in the Gemfile
|
|
129
|
+
if unlock.is_a?(Hash) && unlock[:gems] && !unlock[:gems].empty? &&
|
|
130
|
+
(unlock[:gems] & plugins).empty?
|
|
131
|
+
unlock = {}
|
|
121
132
|
end
|
|
133
|
+
|
|
134
|
+
# resolve remotely when unlocking, so that plugins can be updated.
|
|
135
|
+
# Definition#initialize consumes the unlock hash, so this must be decided
|
|
136
|
+
# before building the definition.
|
|
137
|
+
updating = unlock == true || (unlock.is_a?(Hash) && !unlock.empty?)
|
|
138
|
+
|
|
139
|
+
definition = builder.to_definition(lockfile, unlock)
|
|
140
|
+
|
|
141
|
+
installed_specs = Installer.new.install_definition(definition, updating)
|
|
142
|
+
|
|
143
|
+
save_plugins installed_specs.slice(*plugins), builder.inferred_plugins
|
|
122
144
|
rescue RuntimeError => e
|
|
123
145
|
unless e.is_a?(GemfileError)
|
|
124
146
|
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
|
|
125
147
|
end
|
|
126
148
|
raise
|
|
149
|
+
ensure
|
|
150
|
+
@gemfile_parse = false
|
|
127
151
|
end
|
|
128
152
|
|
|
129
153
|
# The index object used to store the details about the plugin
|
|
@@ -184,12 +208,17 @@ module Bundler
|
|
|
184
208
|
|
|
185
209
|
# Checks if any plugin declares the source
|
|
186
210
|
def source?(name)
|
|
187
|
-
|
|
211
|
+
!!source_plugin(name)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Returns the plugin that handles the source +name+ if any
|
|
215
|
+
def source_plugin(name)
|
|
216
|
+
index.source_plugin(name.to_s)
|
|
188
217
|
end
|
|
189
218
|
|
|
190
219
|
# @return [Class] that handles the source. The class includes API::Source
|
|
191
220
|
def source(name)
|
|
192
|
-
raise UnknownSourceError, "Source #{name} not found" unless
|
|
221
|
+
raise UnknownSourceError, "Source #{name} not found" unless source_plugin(name)
|
|
193
222
|
|
|
194
223
|
load_plugin(index.source_plugin(name)) unless @sources.key? name
|
|
195
224
|
|
|
@@ -201,6 +230,9 @@ module Bundler
|
|
|
201
230
|
# type passed in locked_opts
|
|
202
231
|
def from_lock(locked_opts)
|
|
203
232
|
opts = locked_opts.merge("uri" => locked_opts["remote"])
|
|
233
|
+
# when reading the lockfile while doing the plugin-install-from-gemfile phase,
|
|
234
|
+
# we need to ignore any plugin sources
|
|
235
|
+
return UnloadedSource.new(opts) if @gemfile_parse
|
|
204
236
|
# use an inert placeholder when the plugin handling this source is not
|
|
205
237
|
# installed, so that the lockfile can still be parsed
|
|
206
238
|
return UnloadedSource.new(opts) unless source?(locked_opts["type"])
|
|
@@ -243,7 +275,9 @@ module Bundler
|
|
|
243
275
|
#
|
|
244
276
|
# @return [String, nil] installed path
|
|
245
277
|
def installed?(plugin)
|
|
246
|
-
|
|
278
|
+
(path = index.installed?(plugin)) &&
|
|
279
|
+
index.plugin_path(plugin).join(PLUGIN_FILE_NAME).file? &&
|
|
280
|
+
path
|
|
247
281
|
end
|
|
248
282
|
|
|
249
283
|
# @return [true, false] whether the plugin is loaded
|
|
@@ -253,19 +287,11 @@ module Bundler
|
|
|
253
287
|
|
|
254
288
|
# Post installation processing and registering with index
|
|
255
289
|
#
|
|
256
|
-
# @param [Array<String>] plugins list to be installed
|
|
257
290
|
# @param [Hash] specs of plugins mapped to installation path (currently they
|
|
258
291
|
# contain all the installed specs, including plugins)
|
|
259
292
|
# @param [Array<String>] names of inferred source plugins that can be ignored
|
|
260
|
-
def save_plugins(
|
|
261
|
-
|
|
262
|
-
spec = specs[name]
|
|
263
|
-
|
|
264
|
-
# It's possible that the `plugin` found in the Gemfile don't appear in the specs. For instance when
|
|
265
|
-
# calling `BUNDLE_WITHOUT=default bundle install`, the plugins will not get installed.
|
|
266
|
-
next if spec.nil?
|
|
267
|
-
next if index.up_to_date?(spec)
|
|
268
|
-
|
|
293
|
+
def save_plugins(specs, optional_plugins = [])
|
|
294
|
+
specs.each do |name, spec|
|
|
269
295
|
save_plugin(name, spec, optional_plugins.include?(name))
|
|
270
296
|
end
|
|
271
297
|
end
|
|
@@ -290,6 +316,8 @@ module Bundler
|
|
|
290
316
|
#
|
|
291
317
|
# @raise [PluginInstallError] if validation or registration raises any error
|
|
292
318
|
def save_plugin(name, spec, optional_plugin = false)
|
|
319
|
+
return if index.up_to_date?(spec)
|
|
320
|
+
|
|
293
321
|
validate_plugin! Pathname.new(spec.full_gem_path)
|
|
294
322
|
installed = register_plugin(name, spec, optional_plugin)
|
|
295
323
|
Bundler.ui.info "Installed plugin #{name}" if installed
|
|
@@ -325,7 +353,7 @@ module Bundler
|
|
|
325
353
|
raise MalformattedPlugin, "#{e.class}: #{e.message}"
|
|
326
354
|
end
|
|
327
355
|
|
|
328
|
-
if optional_plugin && @sources.keys.any? {|s|
|
|
356
|
+
if optional_plugin && @sources.keys.any? {|s| source_plugin(s) }
|
|
329
357
|
Bundler.rm_rf(path)
|
|
330
358
|
false
|
|
331
359
|
else
|
|
@@ -10,11 +10,11 @@ module Bundler
|
|
|
10
10
|
include MatchPlatform
|
|
11
11
|
include Comparable
|
|
12
12
|
|
|
13
|
-
attr_reader :name, :version, :platform
|
|
13
|
+
attr_reader :name, :version, :platform, :content_address
|
|
14
14
|
attr_writer :dependencies
|
|
15
15
|
attr_accessor :source, :remote, :locked_platform, :created_at
|
|
16
16
|
|
|
17
|
-
def initialize(name, version, platform, spec_fetcher)
|
|
17
|
+
def initialize(name, version, platform, spec_fetcher, content_address: nil)
|
|
18
18
|
@name = name
|
|
19
19
|
@version = Gem::Version.create version
|
|
20
20
|
@original_platform = platform || Gem::Platform::RUBY
|
|
@@ -22,6 +22,7 @@ module Bundler
|
|
|
22
22
|
@spec_fetcher = spec_fetcher
|
|
23
23
|
@dependencies = nil
|
|
24
24
|
@locked_platform = nil
|
|
25
|
+
@content_address = content_address
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def insecurely_materialized?
|
|
@@ -35,7 +36,9 @@ module Bundler
|
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def full_name
|
|
38
|
-
@full_name ||= if
|
|
39
|
+
@full_name ||= if Gem::ContentAddress.content_addressed?(self, validate_ruby_abi: false)
|
|
40
|
+
"#{@name}-#{@version}-#{@content_address}"
|
|
41
|
+
elsif @platform == Gem::Platform::RUBY
|
|
39
42
|
"#{@name}-#{@version}"
|
|
40
43
|
else
|
|
41
44
|
"#{@name}-#{@version}-#{@platform}"
|
|
@@ -5,9 +5,10 @@ require_relative "package"
|
|
|
5
5
|
module Bundler
|
|
6
6
|
class Resolver
|
|
7
7
|
class Base
|
|
8
|
-
attr_reader :packages, :requirements, :source_requirements, :locked_specs
|
|
8
|
+
attr_reader :packages, :requirements, :source_requirements, :locked_specs, :overrides
|
|
9
9
|
|
|
10
10
|
def initialize(source_requirements, dependencies, base, platforms, options)
|
|
11
|
+
@overrides = options.delete(:overrides) || []
|
|
11
12
|
@explicit_unlocks = options.delete(:explicit_unlocks) || []
|
|
12
13
|
@source_requirements = source_requirements
|
|
13
14
|
@locked_specs = options[:locked_specs]
|
data/lib/bundler/resolver.rb
CHANGED
|
@@ -70,7 +70,9 @@ module Bundler
|
|
|
70
70
|
|
|
71
71
|
@cached_dependencies = Hash.new do |dependencies, package|
|
|
72
72
|
dependencies[package] = Hash.new do |versions, version|
|
|
73
|
-
|
|
73
|
+
deps = version.dependencies.reject {|d| d.name == package.name }
|
|
74
|
+
deps = apply_metadata_overrides(deps, package.name)
|
|
75
|
+
versions[version] = to_dependency_hash(deps, @packages)
|
|
74
76
|
end
|
|
75
77
|
end
|
|
76
78
|
|
|
@@ -83,13 +85,14 @@ module Bundler
|
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
def solve_versions(root:, logger:)
|
|
86
|
-
solver = PubGrub::VersionSolver.new(source: self, root: root, strategy: Strategy.new(self), logger: logger)
|
|
88
|
+
solver = Gem::PubGrub::VersionSolver.new(source: self, root: root, strategy: Strategy.new(self), logger: logger)
|
|
87
89
|
result = solver.solve
|
|
88
90
|
resolved_specs = result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) }
|
|
91
|
+
Override.attach(resolved_specs, @base.overrides)
|
|
89
92
|
spec_set = SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
|
|
90
93
|
@cooldown_skipped = cooldown_skipped_summary(spec_set)
|
|
91
94
|
spec_set
|
|
92
|
-
rescue PubGrub::SolveFailure => e
|
|
95
|
+
rescue Gem::PubGrub::SolveFailure => e
|
|
93
96
|
incompatibility = e.incompatibility
|
|
94
97
|
|
|
95
98
|
names_to_unlock, names_to_allow_prereleases_for, names_to_allow_remote_specs_for, extended_explanation = find_names_to_relax(incompatibility)
|
|
@@ -128,9 +131,25 @@ module Bundler
|
|
|
128
131
|
explanation << extended_explanation
|
|
129
132
|
end
|
|
130
133
|
|
|
134
|
+
override_summary = override_diagnostic_summary
|
|
135
|
+
explanation << override_summary if override_summary
|
|
136
|
+
|
|
131
137
|
raise SolveFailure.new(explanation)
|
|
132
138
|
end
|
|
133
139
|
|
|
140
|
+
def override_diagnostic_summary
|
|
141
|
+
return nil if @base.overrides.empty?
|
|
142
|
+
|
|
143
|
+
lines = ["Bundler applied the following overrides while resolving:"]
|
|
144
|
+
@base.overrides.each do |override|
|
|
145
|
+
target = override.target == :all ? ":all" : override.target.inspect
|
|
146
|
+
location = override.source_location_label
|
|
147
|
+
lines << " override #{target}, #{override.field}: #{override.operation.inspect}" \
|
|
148
|
+
"#{location ? " (declared at #{location})" : ""}"
|
|
149
|
+
end
|
|
150
|
+
"\n\n#{lines.join("\n")}"
|
|
151
|
+
end
|
|
152
|
+
|
|
134
153
|
def find_names_to_relax(incompatibility)
|
|
135
154
|
names_to_unlock = []
|
|
136
155
|
names_to_allow_prereleases_for = []
|
|
@@ -153,7 +172,7 @@ module Bundler
|
|
|
153
172
|
names_to_allow_remote_specs_for << name
|
|
154
173
|
end
|
|
155
174
|
|
|
156
|
-
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(PubGrub::Incompatibility::NoVersions) }
|
|
175
|
+
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(Gem::PubGrub::Incompatibility::NoVersions) }
|
|
157
176
|
next unless no_versions_incompat
|
|
158
177
|
|
|
159
178
|
extended_explanation = no_versions_incompat.extended_explanation
|
|
@@ -165,12 +184,12 @@ module Bundler
|
|
|
165
184
|
|
|
166
185
|
def parse_dependency(package, dependency)
|
|
167
186
|
range = if repository_for(package).is_a?(Source::Gemspec)
|
|
168
|
-
PubGrub::VersionRange.any
|
|
187
|
+
Gem::PubGrub::VersionRange.any
|
|
169
188
|
else
|
|
170
189
|
requirement_to_range(dependency)
|
|
171
190
|
end
|
|
172
191
|
|
|
173
|
-
PubGrub::VersionConstraint.new(package, range: range)
|
|
192
|
+
Gem::PubGrub::VersionConstraint.new(package, range: range)
|
|
174
193
|
end
|
|
175
194
|
|
|
176
195
|
def versions_for(package, range = VersionRange.any)
|
|
@@ -178,7 +197,7 @@ module Bundler
|
|
|
178
197
|
end
|
|
179
198
|
|
|
180
199
|
def no_versions_incompatibility_for(package, unsatisfied_term)
|
|
181
|
-
cause = PubGrub::Incompatibility::NoVersions.new(unsatisfied_term)
|
|
200
|
+
cause = Gem::PubGrub::Incompatibility::NoVersions.new(unsatisfied_term)
|
|
182
201
|
name = package.name
|
|
183
202
|
constraint = unsatisfied_term.constraint
|
|
184
203
|
constraint_string = constraint.constraint_string
|
|
@@ -239,24 +258,24 @@ module Bundler
|
|
|
239
258
|
sorted_versions[high]
|
|
240
259
|
end
|
|
241
260
|
|
|
242
|
-
range = PubGrub::VersionRange.new(min: low, max: high, include_min: !low.nil?)
|
|
261
|
+
range = Gem::PubGrub::VersionRange.new(min: low, max: high, include_min: !low.nil?)
|
|
243
262
|
|
|
244
|
-
self_constraint = PubGrub::VersionConstraint.new(package, range: range)
|
|
263
|
+
self_constraint = Gem::PubGrub::VersionConstraint.new(package, range: range)
|
|
245
264
|
|
|
246
|
-
dep_term = PubGrub::Term.new(dep_constraint, false)
|
|
247
|
-
self_term = PubGrub::Term.new(self_constraint, true)
|
|
265
|
+
dep_term = Gem::PubGrub::Term.new(dep_constraint, false)
|
|
266
|
+
self_term = Gem::PubGrub::Term.new(self_constraint, true)
|
|
248
267
|
|
|
249
268
|
custom_explanation = if dep_package.meta? && package.root?
|
|
250
269
|
"current #{dep_package} version is #{dep_constraint.constraint_string}"
|
|
251
270
|
end
|
|
252
271
|
|
|
253
|
-
PubGrub::Incompatibility.new([self_term, dep_term], cause: :dependency, custom_explanation: custom_explanation)
|
|
272
|
+
Gem::PubGrub::Incompatibility.new([self_term, dep_term], cause: :dependency, custom_explanation: custom_explanation)
|
|
254
273
|
end
|
|
255
274
|
end
|
|
256
275
|
|
|
257
276
|
def all_versions_for(package)
|
|
258
277
|
name = package.name
|
|
259
|
-
results = (@base[name] + filter_specs(@all_specs[name], package)).uniq {|spec| [spec.version.hash, spec.platform] }
|
|
278
|
+
results = (@base[name] + filter_specs(@all_specs[name], package)).uniq {|spec| [spec.version.hash, spec.platform, spec.content_address] }
|
|
260
279
|
|
|
261
280
|
if name == "bundler" && !bundler_pinned_to_current_version?
|
|
262
281
|
bundler_spec = Gem.loaded_specs["bundler"]
|
|
@@ -294,11 +313,15 @@ module Bundler
|
|
|
294
313
|
next groups if package.force_ruby_platform?
|
|
295
314
|
end
|
|
296
315
|
|
|
297
|
-
|
|
316
|
+
platform_specs = platform_specs.flatten.uniq
|
|
317
|
+
platform_group = Resolver::SpecGroup.new((platform_specs + ruby_specs).uniq)
|
|
298
318
|
next groups if platform_group == ruby_group
|
|
299
319
|
|
|
300
320
|
groups << Resolver::Candidate.new(version, group: platform_group, priority: 1)
|
|
301
321
|
|
|
322
|
+
platform_only_group = Resolver::SpecGroup.new(platform_specs)
|
|
323
|
+
groups << Resolver::Candidate.new(version, group: platform_only_group, priority: 0) unless platform_only_group == platform_group
|
|
324
|
+
|
|
302
325
|
groups
|
|
303
326
|
end
|
|
304
327
|
end
|
|
@@ -446,9 +469,9 @@ module Bundler
|
|
|
446
469
|
def cooldown_excluded?(spec)
|
|
447
470
|
return false unless spec.respond_to?(:created_at) && spec.created_at
|
|
448
471
|
return false unless spec.respond_to?(:remote) && spec.remote
|
|
449
|
-
return false if locked_by_lockfile?(spec)
|
|
450
472
|
days = spec.remote.effective_cooldown
|
|
451
473
|
return false if days.nil? || days <= 0
|
|
474
|
+
return false if locked_by_lockfile?(spec)
|
|
452
475
|
(cooldown_now - spec.created_at) < (days * 86_400)
|
|
453
476
|
end
|
|
454
477
|
|
|
@@ -602,19 +625,19 @@ module Bundler
|
|
|
602
625
|
when "~>"
|
|
603
626
|
name = "~> #{ver}"
|
|
604
627
|
bump = Resolver::Candidate.new(version.bump.to_s + ".A")
|
|
605
|
-
PubGrub::VersionRange.new(name: name, min: ver, max: bump, include_min: true)
|
|
628
|
+
Gem::PubGrub::VersionRange.new(name: name, min: ver, max: bump, include_min: true)
|
|
606
629
|
when ">"
|
|
607
|
-
PubGrub::VersionRange.new(min: platform_ver)
|
|
630
|
+
Gem::PubGrub::VersionRange.new(min: platform_ver)
|
|
608
631
|
when ">="
|
|
609
|
-
PubGrub::VersionRange.new(min: ver, include_min: true)
|
|
632
|
+
Gem::PubGrub::VersionRange.new(min: ver, include_min: true)
|
|
610
633
|
when "<"
|
|
611
|
-
PubGrub::VersionRange.new(max: ver)
|
|
634
|
+
Gem::PubGrub::VersionRange.new(max: ver)
|
|
612
635
|
when "<="
|
|
613
|
-
PubGrub::VersionRange.new(max: platform_ver, include_max: true)
|
|
636
|
+
Gem::PubGrub::VersionRange.new(max: platform_ver, include_max: true)
|
|
614
637
|
when "="
|
|
615
|
-
PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true)
|
|
638
|
+
Gem::PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true)
|
|
616
639
|
when "!="
|
|
617
|
-
PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true).invert
|
|
640
|
+
Gem::PubGrub::VersionRange.new(min: ver, max: platform_ver, include_min: true, include_max: true).invert
|
|
618
641
|
else
|
|
619
642
|
raise "bad version specifier: #{op}"
|
|
620
643
|
end
|
|
@@ -624,7 +647,7 @@ module Bundler
|
|
|
624
647
|
end
|
|
625
648
|
|
|
626
649
|
def to_dependency_hash(dependencies, packages)
|
|
627
|
-
dependencies.inject({}) do |deps, dep|
|
|
650
|
+
apply_overrides(dependencies).inject({}) do |deps, dep|
|
|
628
651
|
package = packages[dep.name]
|
|
629
652
|
|
|
630
653
|
current_req = deps[package]
|
|
@@ -640,6 +663,33 @@ module Bundler
|
|
|
640
663
|
end
|
|
641
664
|
end
|
|
642
665
|
|
|
666
|
+
def apply_overrides(dependencies)
|
|
667
|
+
return dependencies if @base.overrides.empty?
|
|
668
|
+
|
|
669
|
+
dependencies.map do |dep|
|
|
670
|
+
override = Override.find_for(@base.overrides, dep.name, :version)
|
|
671
|
+
next dep unless override
|
|
672
|
+
Gem::Dependency.new(dep.name, override.apply_to(dep.requirement))
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
METADATA_DEP_FIELD = {
|
|
677
|
+
"Ruby\0" => :required_ruby_version,
|
|
678
|
+
"RubyGems\0" => :required_rubygems_version,
|
|
679
|
+
}.freeze
|
|
680
|
+
|
|
681
|
+
def apply_metadata_overrides(dependencies, name)
|
|
682
|
+
return dependencies if @base.overrides.empty?
|
|
683
|
+
|
|
684
|
+
dependencies.map do |dep|
|
|
685
|
+
field = METADATA_DEP_FIELD[dep.name]
|
|
686
|
+
next dep unless field
|
|
687
|
+
override = Override.find_for(@base.overrides, name, field)
|
|
688
|
+
next dep unless override
|
|
689
|
+
Gem::Dependency.new(dep.name, override.apply_to(dep.requirement))
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
|
|
643
693
|
def bundler_not_found_message(conflict_dependencies)
|
|
644
694
|
candidate_specs = filter_matching_specs(default_bundler_source.specs.search("bundler"), conflict_dependencies)
|
|
645
695
|
|
data/lib/bundler/ruby_version.rb
CHANGED
|
@@ -96,8 +96,6 @@ module Bundler
|
|
|
96
96
|
[:version, versions_string(versions), versions_string(other.versions)]
|
|
97
97
|
elsif @input_engine && !matches?(engine_versions, other.engine_gem_version)
|
|
98
98
|
[:engine_version, versions_string(engine_versions), versions_string(other.engine_versions)]
|
|
99
|
-
elsif patchlevel && (!patchlevel.is_a?(String) || !other.patchlevel.is_a?(String) || !matches?(patchlevel, other.patchlevel))
|
|
100
|
-
[:patchlevel, patchlevel, other.patchlevel]
|
|
101
99
|
end
|
|
102
100
|
end
|
|
103
101
|
|
data/lib/bundler/rubygems_ext.rb
CHANGED
|
@@ -13,7 +13,53 @@ require "rubygems" unless defined?(Gem)
|
|
|
13
13
|
# `Gem::Source` from the redefined `Gem::Specification#source`.
|
|
14
14
|
require "rubygems/source"
|
|
15
15
|
|
|
16
|
+
# Can be removed once RubyGems 4.0.0 support is dropped
|
|
17
|
+
unless Gem::BasicSpecification.method_defined?(:content_address)
|
|
18
|
+
Gem::BasicSpecification.attr_accessor :content_address
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Can be removed once RubyGems 4.0.0 support is dropped
|
|
22
|
+
unless Gem::NameTuple.method_defined?(:content_address)
|
|
23
|
+
Gem::NameTuple.attr_reader :content_address
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
module Gem
|
|
27
|
+
# Can be removed once RubyGems 4.0.0 support is dropped
|
|
28
|
+
unless defined?(Gem::ContentAddress)
|
|
29
|
+
module ContentAddress
|
|
30
|
+
def self.match?(token)
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.eligible?(spec, validate_ruby_abi: true)
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.content_addressed?(spec, validate_ruby_abi: true)
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.content_addressed_row?(suffix, platform, required_ruby_version = nil, validate_ruby_abi: true)
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Can be removed once RubyGems 4.0.0 support is dropped
|
|
49
|
+
class SpecificationRecord
|
|
50
|
+
unless respond_to?(:specification_dir_for)
|
|
51
|
+
def self.specification_dir_for(spec, base_dir)
|
|
52
|
+
File.join(base_dir, "specifications")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
unless respond_to?(:dirs_from)
|
|
57
|
+
def self.dirs_from(paths)
|
|
58
|
+
paths.map {|path| File.join(path, "specifications") }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
17
63
|
# Can be removed once RubyGems 3.5.11 support is dropped
|
|
18
64
|
unless Gem.respond_to?(:freebsd_platform?)
|
|
19
65
|
def self.freebsd_platform?
|
|
@@ -235,6 +281,20 @@ module Gem
|
|
|
235
281
|
end
|
|
236
282
|
end
|
|
237
283
|
|
|
284
|
+
alias_method :rg_build_info_dir, :build_info_dir
|
|
285
|
+
def build_info_dir
|
|
286
|
+
# A git checkout's build logs belong with that checkout's extension build.
|
|
287
|
+
# base_dir points at the directory holding every checkout, so logs keyed by
|
|
288
|
+
# full_name would collide between revisions of the same gem and would sit
|
|
289
|
+
# outside anything `bundle clean` prunes. extension_dir is unique per
|
|
290
|
+
# revision and goes away with the checkout.
|
|
291
|
+
if source.respond_to?(:extension_dir_name)
|
|
292
|
+
extension_dir
|
|
293
|
+
else
|
|
294
|
+
rg_build_info_dir
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
238
298
|
# Can be removed once RubyGems 3.5.21 support is dropped
|
|
239
299
|
remove_method :gem_dir if method_defined?(:gem_dir, false)
|
|
240
300
|
|
|
@@ -417,7 +477,8 @@ module Gem
|
|
|
417
477
|
unless Gem::NameTuple.new("a", Gem::Version.new("1"), Gem::Platform.new("x86_64-linux")).platform.is_a?(String)
|
|
418
478
|
alias_method :initialize_with_platform, :initialize
|
|
419
479
|
|
|
420
|
-
def initialize(name, version, platform = Gem::Platform::RUBY)
|
|
480
|
+
def initialize(name, version, platform = Gem::Platform::RUBY, content_address = nil)
|
|
481
|
+
@content_address = content_address
|
|
421
482
|
if Gem::Platform === platform
|
|
422
483
|
initialize_with_platform(name, version, platform.to_s)
|
|
423
484
|
else
|
|
@@ -426,6 +487,15 @@ module Gem
|
|
|
426
487
|
end
|
|
427
488
|
end
|
|
428
489
|
|
|
490
|
+
unless instance_method(:initialize).parameters.any? {|kind, name| kind == :key && name == :content_address }
|
|
491
|
+
alias_method :initialize_without_content_address, :initialize
|
|
492
|
+
|
|
493
|
+
def initialize(name, version, platform = Gem::Platform::RUBY, content_address: nil)
|
|
494
|
+
initialize_without_content_address(name, version, platform)
|
|
495
|
+
@content_address = content_address
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
429
499
|
def lock_name
|
|
430
500
|
if platform == Gem::Platform::RUBY
|
|
431
501
|
"#{name} (#{version})"
|
|
@@ -4,6 +4,11 @@ require "rubygems/installer"
|
|
|
4
4
|
|
|
5
5
|
module Bundler
|
|
6
6
|
class RubyGemsGemInstaller < Gem::Installer
|
|
7
|
+
# Can be removed once RubyGems 4.0.0 support is dropped
|
|
8
|
+
unless private_method_defined?(:assign_content_address)
|
|
9
|
+
private def assign_content_address; end
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
# Cap how many jobserver slots a single gem's `make` may grab so that one
|
|
8
13
|
# gem with many recipes doesn't starve the others sharing the pool. Beyond
|
|
9
14
|
# a handful of jobs the extra parallelism rarely pays off in practice.
|
|
@@ -14,6 +19,8 @@ module Bundler
|
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
def install
|
|
22
|
+
assign_content_address
|
|
23
|
+
|
|
17
24
|
pre_install_checks
|
|
18
25
|
|
|
19
26
|
run_pre_install_hooks
|
|
@@ -32,7 +39,11 @@ module Bundler
|
|
|
32
39
|
extract_files
|
|
33
40
|
end
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
if options[:build_extension] == false
|
|
43
|
+
warn_skipped_extensions
|
|
44
|
+
elsif spec.extensions.any?
|
|
45
|
+
build_extensions
|
|
46
|
+
end
|
|
36
47
|
write_build_info_file
|
|
37
48
|
run_post_build_hooks
|
|
38
49
|
|
|
@@ -40,7 +51,12 @@ module Bundler
|
|
|
40
51
|
generate_bin
|
|
41
52
|
end
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
if options[:install_plugin] == false
|
|
55
|
+
remove_stale_plugins
|
|
56
|
+
warn_skipped_plugins
|
|
57
|
+
else
|
|
58
|
+
generate_plugins
|
|
59
|
+
end
|
|
44
60
|
|
|
45
61
|
write_spec
|
|
46
62
|
|
|
@@ -85,6 +101,29 @@ module Bundler
|
|
|
85
101
|
end
|
|
86
102
|
end
|
|
87
103
|
|
|
104
|
+
# Reimplemented from RubyGems, since RubyGems older than 4.1 doesn't
|
|
105
|
+
# provide it
|
|
106
|
+
def remove_stale_plugins
|
|
107
|
+
return unless spec.plugins.empty?
|
|
108
|
+
|
|
109
|
+
ensure_writable_dir @plugins_dir
|
|
110
|
+
remove_plugins_for(spec, @plugins_dir)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def warn_skipped_extensions
|
|
114
|
+
return if spec.extensions.empty?
|
|
115
|
+
|
|
116
|
+
Bundler.ui.warn "#{spec.full_name} contains native extensions that were not built.\n" \
|
|
117
|
+
"To build extensions, unset no_build_extension and run `bundle pristine #{spec.name}`."
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def warn_skipped_plugins
|
|
121
|
+
return if spec.plugins.empty?
|
|
122
|
+
|
|
123
|
+
Bundler.ui.warn "#{spec.full_name} contains plugins that were not installed.\n" \
|
|
124
|
+
"To install plugins, unset no_install_plugin and run `bundle pristine #{spec.name}`."
|
|
125
|
+
end
|
|
126
|
+
|
|
88
127
|
if Bundler.rubygems.provides?("< 3.5.19")
|
|
89
128
|
def generate_bin_script(filename, bindir)
|
|
90
129
|
bin_script_path = File.join bindir, formatted_program_filename(filename)
|
|
@@ -111,7 +111,7 @@ module Bundler
|
|
|
111
111
|
|
|
112
112
|
def spec_cache_dirs
|
|
113
113
|
@spec_cache_dirs ||= begin
|
|
114
|
-
dirs = gem_path.
|
|
114
|
+
dirs = gem_path.flat_map {|dir| Gem::SpecificationRecord.dirs_from([dir]) }
|
|
115
115
|
dirs << Gem.spec_cache_dir
|
|
116
116
|
dirs.uniq.select {|dir| File.directory? dir }
|
|
117
117
|
end
|
|
@@ -144,7 +144,12 @@ module Bundler
|
|
|
144
144
|
|
|
145
145
|
def spec_from_gem(path)
|
|
146
146
|
require "rubygems/package"
|
|
147
|
-
Gem::Package.new(path)
|
|
147
|
+
package = Gem::Package.new(path)
|
|
148
|
+
spec = package.spec
|
|
149
|
+
if package.respond_to?(:content_address)
|
|
150
|
+
spec.content_address = package.content_address
|
|
151
|
+
end
|
|
152
|
+
spec
|
|
148
153
|
end
|
|
149
154
|
|
|
150
155
|
def build_gem(gem_dir, spec)
|