bundler 4.0.19 → 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 +24 -7
- 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/doctor/diagnose.rb +1 -1
- data/lib/bundler/cli/exec.rb +15 -1
- data/lib/bundler/cli/gem.rb +0 -17
- data/lib/bundler/cli/init.rb +4 -0
- data/lib/bundler/cli/install.rb +4 -5
- data/lib/bundler/cli/lock.rb +1 -2
- data/lib/bundler/cli/outdated.rb +45 -10
- data/lib/bundler/cli/pristine.rb +2 -1
- data/lib/bundler/cli/update.rb +20 -11
- data/lib/bundler/cli.rb +12 -9
- data/lib/bundler/definition.rb +60 -13
- data/lib/bundler/dependency.rb +4 -0
- data/lib/bundler/dsl.rb +78 -12
- 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 +40 -16
- data/lib/bundler/fetcher.rb +8 -47
- data/lib/bundler/gem_helper.rb +2 -2
- 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 +2 -2
- data/lib/bundler/man/bundle-lock.1.ronn +3 -2
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +2 -2
- data/lib/bundler/man/bundle-outdated.1.ronn +7 -1
- data/lib/bundler/man/bundle-platform.1 +5 -1
- data/lib/bundler/man/bundle-platform.1.ronn +4 -0
- 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 +2 -2
- data/lib/bundler/man/bundle-update.1.ronn +2 -2
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +46 -2
- data/lib/bundler/man/gemfile.5.ronn +56 -1
- 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 +79 -12
- data/lib/bundler/settings.rb +373 -30
- data/lib/bundler/shared_helpers.rb +17 -1
- data/lib/bundler/source/git/git_proxy.rb +65 -4
- data/lib/bundler/source/git.rb +25 -14
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/path.rb +1 -1
- data/lib/bundler/source/rubygems/remote.rb +10 -5
- data/lib/bundler/source/rubygems.rb +49 -13
- data/lib/bundler/spec_set.rb +16 -4
- data/lib/bundler/stub_specification.rb +5 -2
- 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 +16 -6
- 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 +79 -70
- data/CHANGELOG.md +0 -5749
- 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
|
@@ -105,7 +105,8 @@ module Bundler
|
|
|
105
105
|
def filesystem_access(path, action = :write, &block)
|
|
106
106
|
yield(path.dup)
|
|
107
107
|
rescue Errno::EACCES => e
|
|
108
|
-
|
|
108
|
+
path_basename = File.basename(path.to_s)
|
|
109
|
+
raise unless e.message.include?(path_basename) || action == :create
|
|
109
110
|
|
|
110
111
|
raise PermissionError.new(path, action)
|
|
111
112
|
rescue Errno::EAGAIN
|
|
@@ -231,6 +232,21 @@ module Bundler
|
|
|
231
232
|
destination
|
|
232
233
|
end
|
|
233
234
|
|
|
235
|
+
# Globs for entries matching +glob+ inside of +base_path+, returning
|
|
236
|
+
# absolute paths. Glob metacharacters in +base_path+ are not treated as
|
|
237
|
+
# part of the pattern, and matched entries are joined literally, so an
|
|
238
|
+
# entry starting with `~` is not expanded into the home directory.
|
|
239
|
+
#
|
|
240
|
+
# Bundler runs against whatever RubyGems the host provides, so this cannot
|
|
241
|
+
# delegate to Gem::Util.glob_files_in_dir, which only gained the literal
|
|
242
|
+
# join in RubyGems 4.1.
|
|
243
|
+
def glob_files_in_dir(glob, base_path)
|
|
244
|
+
expanded_path = nil
|
|
245
|
+
Dir.glob(glob, base: base_path).map! do |f|
|
|
246
|
+
File.join(expanded_path ||= File.expand_path(base_path), f)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
234
250
|
private
|
|
235
251
|
|
|
236
252
|
def validate_bundle_path
|
|
@@ -193,7 +193,13 @@ module Bundler
|
|
|
193
193
|
return out if status.success?
|
|
194
194
|
|
|
195
195
|
if err.include?("couldn't find remote ref") || err.include?("not our ref")
|
|
196
|
-
|
|
196
|
+
default_branch = renamed_remote_default_branch if tracking_remote_default_branch?
|
|
197
|
+
if default_branch
|
|
198
|
+
out = follow_remote_default_branch(args, default_branch)
|
|
199
|
+
return out if out
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
raise MissingGitRevisionError.new(command_with_no_credentials, path, commit || explicit_ref || current_branch, credential_filtered_uri)
|
|
197
203
|
else
|
|
198
204
|
if shallow?
|
|
199
205
|
args -= depth_args
|
|
@@ -298,6 +304,61 @@ module Bundler
|
|
|
298
304
|
branch_option || ref.nil?
|
|
299
305
|
end
|
|
300
306
|
|
|
307
|
+
def tracking_remote_default_branch?
|
|
308
|
+
explicit_ref.nil? && commit.nil?
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Returns nil on any failure, leaving HEAD untouched so the caller reports
|
|
312
|
+
# the original fetch failure. Runs inside the retry block, so it must not
|
|
313
|
+
# touch the caller's command locals.
|
|
314
|
+
def follow_remote_default_branch(args, default_branch)
|
|
315
|
+
reference = "refs/heads/#{default_branch}"
|
|
316
|
+
command = fetch_command(args, "#{reference}:#{reference}")
|
|
317
|
+
check_allowed(command)
|
|
318
|
+
|
|
319
|
+
out, err, status = capture(command, path)
|
|
320
|
+
unless status.success?
|
|
321
|
+
Bundler.ui.debug "Could not fetch #{reference} from #{credential_filtered_uri}: #{err}"
|
|
322
|
+
return
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
previous_branch = current_branch
|
|
326
|
+
begin
|
|
327
|
+
git "symbolic-ref", "HEAD", reference, dir: path
|
|
328
|
+
rescue GitError => e
|
|
329
|
+
Bundler.ui.debug "Could not repoint the cached clone at #{reference}: #{e.message}"
|
|
330
|
+
return
|
|
331
|
+
end
|
|
332
|
+
@current_branch = nil
|
|
333
|
+
Bundler.ui.warn "#{credential_filtered_uri} no longer has #{previous_branch}, " \
|
|
334
|
+
"now following its default branch #{default_branch}"
|
|
335
|
+
out
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# The cached clone's HEAD branch is gone from the remote, so the remote's
|
|
339
|
+
# own idea of its default branch is the only thing left to follow.
|
|
340
|
+
def renamed_remote_default_branch
|
|
341
|
+
default_branch = remote_default_branch
|
|
342
|
+
return if default_branch.nil? || default_branch == current_branch
|
|
343
|
+
|
|
344
|
+
default_branch
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def remote_default_branch
|
|
348
|
+
command = ["ls-remote", "--symref", "--", configured_uri, "HEAD"]
|
|
349
|
+
check_allowed(command)
|
|
350
|
+
|
|
351
|
+
out, err, status = capture(command, path)
|
|
352
|
+
unless status.success?
|
|
353
|
+
Bundler.ui.debug "Could not ask #{credential_filtered_uri} for its default branch: #{err}"
|
|
354
|
+
return
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# A remote is free to advertise a ref name that is not valid UTF-8, and
|
|
358
|
+
# matching that as text raises out of the GitError family.
|
|
359
|
+
out.b[%r{^ref:\s+refs/heads/(.+?)\s+HEAD}, 1]
|
|
360
|
+
end
|
|
361
|
+
|
|
301
362
|
def pinned_to_full_sha?
|
|
302
363
|
full_sha_revision?(ref)
|
|
303
364
|
end
|
|
@@ -369,7 +430,7 @@ module Bundler
|
|
|
369
430
|
def configured_uri
|
|
370
431
|
@configured_uri ||= if /https?:/.match?(uri)
|
|
371
432
|
remote = Gem::URI(uri)
|
|
372
|
-
config_auth = Bundler.settings
|
|
433
|
+
config_auth = Bundler.settings.credentials_for(remote)
|
|
373
434
|
remote.userinfo ||= config_auth
|
|
374
435
|
remote.to_s
|
|
375
436
|
else
|
|
@@ -465,8 +526,8 @@ module Bundler
|
|
|
465
526
|
args
|
|
466
527
|
end
|
|
467
528
|
|
|
468
|
-
def fetch_command(args)
|
|
469
|
-
["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri,
|
|
529
|
+
def fetch_command(args, spec = refspec)
|
|
530
|
+
["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, spec].compact
|
|
470
531
|
end
|
|
471
532
|
|
|
472
533
|
def clone_command(args)
|
data/lib/bundler/source/git.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Bundler
|
|
|
30
30
|
|
|
31
31
|
@copied = false
|
|
32
32
|
@local = false
|
|
33
|
+
@cached_app_cache_path = nil
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
def remote!
|
|
@@ -91,9 +92,9 @@ module Bundler
|
|
|
91
92
|
|
|
92
93
|
def to_s
|
|
93
94
|
begin
|
|
94
|
-
at = humanized_ref
|
|
95
|
-
|
|
96
|
-
rev = "at #{at}
|
|
95
|
+
at = humanized_ref
|
|
96
|
+
at = "#{at}@" if at
|
|
97
|
+
rev = "at #{at}#{shortref_for_display(revision)}"
|
|
97
98
|
rescue GitError
|
|
98
99
|
""
|
|
99
100
|
end
|
|
@@ -191,8 +192,13 @@ module Bundler
|
|
|
191
192
|
set_cache_path!(app_cache_path) if use_app_cache?
|
|
192
193
|
|
|
193
194
|
if requires_checkout? && !@copied
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
Plugin.hook(Plugin::Events::GIT_BEFORE_FETCH, self)
|
|
196
|
+
begin
|
|
197
|
+
fetch unless use_app_cache?
|
|
198
|
+
checkout
|
|
199
|
+
ensure
|
|
200
|
+
Plugin.hook(Plugin::Events::GIT_AFTER_FETCH, self)
|
|
201
|
+
end
|
|
196
202
|
end
|
|
197
203
|
|
|
198
204
|
local_specs
|
|
@@ -272,6 +278,11 @@ module Bundler
|
|
|
272
278
|
|
|
273
279
|
app_cache_path = app_cache_path(custom_path)
|
|
274
280
|
|
|
281
|
+
# When several gems share a single git source, this is called once per
|
|
282
|
+
# gem. Copying the repository is expensive for large repos, so skip it
|
|
283
|
+
# if we already populated this cache during the same command.
|
|
284
|
+
return if @cached_app_cache_path == app_cache_path
|
|
285
|
+
|
|
275
286
|
migrate = try_migrate ? bare_repo?(app_cache_path) : false
|
|
276
287
|
|
|
277
288
|
set_cache_path!(nil) if migrate
|
|
@@ -283,6 +294,8 @@ module Bundler
|
|
|
283
294
|
git_proxy.checkout if migrate || requires_checkout?
|
|
284
295
|
git_proxy.copy_to(app_cache_path, @submodules)
|
|
285
296
|
serialize_gemspecs_in(app_cache_path)
|
|
297
|
+
|
|
298
|
+
@cached_app_cache_path = app_cache_path
|
|
286
299
|
end
|
|
287
300
|
|
|
288
301
|
def checkout
|
|
@@ -320,7 +333,7 @@ module Bundler
|
|
|
320
333
|
|
|
321
334
|
def serialize_gemspecs_in(destination)
|
|
322
335
|
destination = destination.expand_path(Bundler.root) if destination.relative?
|
|
323
|
-
|
|
336
|
+
SharedHelpers.glob_files_in_dir(@glob, destination.to_s).each do |spec_path|
|
|
324
337
|
# Evaluate gemspecs and cache the result. Gemspecs
|
|
325
338
|
# in git might require git or other dependencies.
|
|
326
339
|
# The gemspecs we cache should already be evaluated.
|
|
@@ -405,10 +418,6 @@ module Bundler
|
|
|
405
418
|
options["revision"]
|
|
406
419
|
end
|
|
407
420
|
|
|
408
|
-
def cached?
|
|
409
|
-
cache_path.exist?
|
|
410
|
-
end
|
|
411
|
-
|
|
412
421
|
def git_proxy
|
|
413
422
|
@git_proxy ||= GitProxy.new(cache_path, uri, options, locked_revision, self)
|
|
414
423
|
end
|
|
@@ -423,10 +432,12 @@ module Bundler
|
|
|
423
432
|
def validate_spec(_spec); end
|
|
424
433
|
|
|
425
434
|
def load_gemspec(file)
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
435
|
+
# Expand the path before the chdir below, since resolving it inside the
|
|
436
|
+
# block would base it on the gemspec directory instead of `root`.
|
|
437
|
+
gemspec_path = Pathname.new(file).expand_path(root)
|
|
438
|
+
SharedHelpers.chdir(gemspec_path.dirname.to_s) do
|
|
439
|
+
stub = Gem::StubSpecification.gemspec_stub(gemspec_path.to_s, install_path.parent, install_path.parent)
|
|
440
|
+
stub.full_gem_path = gemspec_path.dirname.to_s
|
|
430
441
|
StubSpecification.from_stub(stub)
|
|
431
442
|
end
|
|
432
443
|
end
|
data/lib/bundler/source/path.rb
CHANGED
|
@@ -161,7 +161,7 @@ module Bundler
|
|
|
161
161
|
|
|
162
162
|
if File.directory?(expanded_path)
|
|
163
163
|
# We sort depth-first since `<<` will override the earlier-found specs
|
|
164
|
-
|
|
164
|
+
SharedHelpers.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
|
|
165
165
|
next unless spec = load_gemspec(file)
|
|
166
166
|
spec.source = self
|
|
167
167
|
|
|
@@ -18,12 +18,17 @@ module Bundler
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Returns the cooldown days that apply to this remote, resolving the
|
|
21
|
-
# precedence CLI > config > Gemfile per-source
|
|
22
|
-
# cooldown applies.
|
|
21
|
+
# precedence CLI > config > Gemfile per-source and then raising the
|
|
22
|
+
# result to RubyGems' own setting. Returns nil if no cooldown applies.
|
|
23
|
+
#
|
|
24
|
+
# The resolver asks once per candidate spec, so the settings lookup is
|
|
25
|
+
# memoized. That snapshots the value: a Remote created before a
|
|
26
|
+
# settings change keeps the old one. Nothing in Bundler changes the
|
|
27
|
+
# cooldown setting after the sources are built (the CLI flag is applied
|
|
28
|
+
# before the Definition exists), so build a new Remote if you need to.
|
|
23
29
|
def effective_cooldown
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@cooldown
|
|
30
|
+
return @effective_cooldown if defined?(@effective_cooldown)
|
|
31
|
+
@effective_cooldown = Bundler.settings.cooldown_for(@cooldown)
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
MAX_CACHE_SLUG_HOST_SIZE = 255 - 1 - 32 # 255 minus dot minus MD5 length
|
|
@@ -25,6 +25,7 @@ module Bundler
|
|
|
25
25
|
@checksum_store = Checksum::Store.new
|
|
26
26
|
@gem_installers = {}
|
|
27
27
|
@gem_installers_mutex = Mutex.new
|
|
28
|
+
@remote_spec_for_mutex = Mutex.new
|
|
28
29
|
@remote_specs_mutex = Mutex.new
|
|
29
30
|
|
|
30
31
|
cooldown = options["cooldown"]
|
|
@@ -196,6 +197,8 @@ module Bundler
|
|
|
196
197
|
"the security policy didn't allow it, with the message: #{e.message}"
|
|
197
198
|
end
|
|
198
199
|
|
|
200
|
+
s.content_address = spec.content_address if spec.content_address
|
|
201
|
+
|
|
199
202
|
spec.__swap__(s)
|
|
200
203
|
end
|
|
201
204
|
|
|
@@ -230,8 +233,12 @@ module Bundler
|
|
|
230
233
|
spec.post_install_message
|
|
231
234
|
end
|
|
232
235
|
|
|
236
|
+
def uncached?(spec)
|
|
237
|
+
caches.none? {|cache| File.exist?(package_path(cache, spec)) }
|
|
238
|
+
end
|
|
239
|
+
|
|
233
240
|
def cache(spec, custom_path = nil)
|
|
234
|
-
cached_path =
|
|
241
|
+
cached_path = fetch_gem_if_possible(spec)
|
|
235
242
|
raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path
|
|
236
243
|
return if File.dirname(cached_path) == Bundler.app_cache.to_s
|
|
237
244
|
Bundler.ui.info " * #{File.basename(cached_path)}"
|
|
@@ -406,7 +413,7 @@ module Bundler
|
|
|
406
413
|
@cached_specs ||= begin
|
|
407
414
|
idx = Index.new
|
|
408
415
|
|
|
409
|
-
|
|
416
|
+
SharedHelpers.glob_files_in_dir("*.gem", cache_path.to_s).each do |gemfile|
|
|
410
417
|
s ||= Bundler.rubygems.spec_from_gem(gemfile)
|
|
411
418
|
s.source = self
|
|
412
419
|
idx << s
|
|
@@ -437,12 +444,14 @@ module Bundler
|
|
|
437
444
|
# Looks up a single spec in the remote sources, fetching only its own
|
|
438
445
|
# name when the full remote index is not already materialized.
|
|
439
446
|
def remote_spec_for(spec)
|
|
440
|
-
|
|
447
|
+
@remote_spec_for_mutex.synchronize do
|
|
448
|
+
return remote_specs.search(spec).first if @remote_specs || api_fetchers.empty?
|
|
441
449
|
|
|
442
|
-
|
|
443
|
-
|
|
450
|
+
index = Index.build do |idx|
|
|
451
|
+
fetch_names(api_fetchers, [spec.name], idx)
|
|
452
|
+
end
|
|
453
|
+
index.search(spec).first
|
|
444
454
|
end
|
|
445
|
-
index.search(spec).first
|
|
446
455
|
end
|
|
447
456
|
|
|
448
457
|
def fetch_names(fetchers, dependency_names, index)
|
|
@@ -462,10 +471,24 @@ module Bundler
|
|
|
462
471
|
if spec.remote
|
|
463
472
|
fetch_gem(spec, previous_spec)
|
|
464
473
|
else
|
|
465
|
-
cached_gem(spec)
|
|
474
|
+
cached_gem(spec) || refetch_gem(spec, previous_spec)
|
|
466
475
|
end
|
|
467
476
|
end
|
|
468
477
|
|
|
478
|
+
# An installed gem materializes without a remote, so a reinstall forced by
|
|
479
|
+
# `--redownload` has to look the gem up in the remote index again before it
|
|
480
|
+
# can download the archive that the cache no longer holds.
|
|
481
|
+
def refetch_gem(spec, previous_spec = nil)
|
|
482
|
+
return unless @allow_remote
|
|
483
|
+
|
|
484
|
+
remote_spec = remote_spec_for(spec)
|
|
485
|
+
return unless remote_spec && remote_spec.full_name == spec.full_name
|
|
486
|
+
|
|
487
|
+
path = fetch_gem(remote_spec, previous_spec)
|
|
488
|
+
spec.remote = remote_spec.remote
|
|
489
|
+
path
|
|
490
|
+
end
|
|
491
|
+
|
|
469
492
|
def fetch_gem(spec, previous_spec = nil)
|
|
470
493
|
spec.fetch_platform
|
|
471
494
|
|
|
@@ -545,8 +568,13 @@ module Bundler
|
|
|
545
568
|
Bundler.ui.confirm("Fetching #{version_message(spec, previous_spec)}")
|
|
546
569
|
gem_remote_fetcher = remote_fetchers.fetch(spec.remote).gem_remote_fetcher
|
|
547
570
|
|
|
548
|
-
|
|
549
|
-
|
|
571
|
+
Plugin.hook(Plugin::Events::GEM_BEFORE_FETCH, spec)
|
|
572
|
+
begin
|
|
573
|
+
Gem.time("Downloaded #{spec.name} in", 0, true) do
|
|
574
|
+
Bundler.rubygems.download_gem(spec, uri, download_cache_path, gem_remote_fetcher)
|
|
575
|
+
end
|
|
576
|
+
ensure
|
|
577
|
+
Plugin.hook(Plugin::Events::GEM_AFTER_FETCH, spec)
|
|
550
578
|
end
|
|
551
579
|
end
|
|
552
580
|
|
|
@@ -566,7 +594,12 @@ module Bundler
|
|
|
566
594
|
return unless remote = spec.remote
|
|
567
595
|
return unless cache_slug = remote.cache_slug
|
|
568
596
|
|
|
569
|
-
|
|
597
|
+
if Gem.respond_to?(:global_gem_cache_path)
|
|
598
|
+
Pathname.new(Gem.global_gem_cache_path).join(cache_slug)
|
|
599
|
+
else
|
|
600
|
+
# Fall back to old location for older RubyGems versions
|
|
601
|
+
Bundler.user_cache.join("gems", cache_slug)
|
|
602
|
+
end
|
|
570
603
|
end
|
|
571
604
|
|
|
572
605
|
def extension_cache_slug(spec)
|
|
@@ -574,11 +607,11 @@ module Bundler
|
|
|
574
607
|
remote.cache_slug
|
|
575
608
|
end
|
|
576
609
|
|
|
577
|
-
# We are using a mutex to
|
|
610
|
+
# We are using a mutex to read and write from/to the hash.
|
|
578
611
|
# The reason this double synchronization was added is for performance
|
|
579
612
|
# and to lock the mutex for the shortest possible amount of time. Otherwise,
|
|
580
613
|
# all threads are fighting over this mutex and when it gets acquired it gets locked
|
|
581
|
-
# until a
|
|
614
|
+
# until a thread finishes downloading a gem, leaving the other threads waiting
|
|
582
615
|
# doing nothing.
|
|
583
616
|
def rubygems_gem_installer(spec, options)
|
|
584
617
|
@gem_installers_mutex.synchronize { @gem_installers[spec.name] } || begin
|
|
@@ -589,6 +622,7 @@ module Bundler
|
|
|
589
622
|
|
|
590
623
|
installer = Bundler::RubyGemsGemInstaller.at(
|
|
591
624
|
path,
|
|
625
|
+
content_address: (spec.content_address if Gem::ContentAddress.content_addressed?(spec, validate_ruby_abi: false)),
|
|
592
626
|
security_policy: Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]],
|
|
593
627
|
install_dir: rubygems_dir.to_s,
|
|
594
628
|
bin_dir: Bundler.system_bindir.to_s,
|
|
@@ -596,7 +630,9 @@ module Bundler
|
|
|
596
630
|
wrappers: true,
|
|
597
631
|
env_shebang: true,
|
|
598
632
|
build_args: options[:build_args],
|
|
599
|
-
bundler_extension_cache_path: extension_cache_path(spec)
|
|
633
|
+
bundler_extension_cache_path: extension_cache_path(spec),
|
|
634
|
+
build_extension: Bundler.settings[:no_build_extension] ? false : nil,
|
|
635
|
+
install_plugin: Bundler.settings[:no_install_plugin] ? false : nil
|
|
600
636
|
)
|
|
601
637
|
@gem_installers_mutex.synchronize { @gem_installers[spec.name] ||= installer }
|
|
602
638
|
end
|
data/lib/bundler/spec_set.rb
CHANGED
|
@@ -178,7 +178,7 @@ module Bundler
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def find_by_name_and_platform(name, platform)
|
|
181
|
-
|
|
181
|
+
lookup[name]&.detect {|spec| spec.installable_on_platform?(platform) }
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
def specs_with_additional_variants_from(other)
|
|
@@ -274,13 +274,25 @@ module Bundler
|
|
|
274
274
|
|
|
275
275
|
valid_platform = lookup.all? do |_, specs|
|
|
276
276
|
spec = specs.first
|
|
277
|
+
# The matching candidates returned by source.specs.search are remote
|
|
278
|
+
# specs that do not carry the override list themselves. Borrow it from
|
|
279
|
+
# the LazySpec we are validating so platform-variant validation honors
|
|
280
|
+
# the same overrides the install/resolve path already applies.
|
|
281
|
+
overrides = spec.is_a?(LazySpecification) ? Array(spec.overrides) : []
|
|
277
282
|
matching_specs = spec.source.specs.search([spec.name, spec.version])
|
|
278
283
|
platform_spec = MatchPlatform.select_best_platform_match(matching_specs, platform).find do |s|
|
|
279
|
-
|
|
284
|
+
s.matches_current_metadata_with_overrides?(overrides) && valid_dependencies?(s)
|
|
280
285
|
end
|
|
281
286
|
|
|
282
287
|
if platform_spec
|
|
283
|
-
|
|
288
|
+
unless specs.include?(platform_spec)
|
|
289
|
+
new_lazy = LazySpecification.from_spec(platform_spec)
|
|
290
|
+
# Carry the overrides forward so a follow-up complete_platform
|
|
291
|
+
# call that picks this synthesized variant as its exemplar still
|
|
292
|
+
# honors the user's override list.
|
|
293
|
+
new_lazy.overrides = overrides if overrides.any?
|
|
294
|
+
new_specs << new_lazy
|
|
295
|
+
end
|
|
284
296
|
true
|
|
285
297
|
else
|
|
286
298
|
false
|
|
@@ -314,7 +326,7 @@ module Bundler
|
|
|
314
326
|
end
|
|
315
327
|
|
|
316
328
|
def sorted
|
|
317
|
-
@sorted ||= ([
|
|
329
|
+
@sorted ||= ([lookup["rake"]&.first] + tsort).compact.uniq
|
|
318
330
|
rescue Gem::TSort::Cyclic => error
|
|
319
331
|
cgems = extract_circular_gems(error)
|
|
320
332
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
|
@@ -4,7 +4,8 @@ module Bundler
|
|
|
4
4
|
class StubSpecification < RemoteSpecification
|
|
5
5
|
def self.from_stub(stub)
|
|
6
6
|
return stub if stub.is_a?(Bundler::StubSpecification)
|
|
7
|
-
|
|
7
|
+
content_address = stub.content_address
|
|
8
|
+
spec = new(stub.name, stub.version, stub.platform, nil, content_address: content_address)
|
|
8
9
|
spec.stub = stub
|
|
9
10
|
spec
|
|
10
11
|
end
|
|
@@ -126,7 +127,9 @@ module Bundler
|
|
|
126
127
|
def _remote_specification
|
|
127
128
|
@_remote_specification ||= begin
|
|
128
129
|
rs = stub.to_spec
|
|
129
|
-
|
|
130
|
+
# Gem::StubSpecification#to_spec may return an activated specification
|
|
131
|
+
# with the same name and version from a different gem installation.
|
|
132
|
+
if rs.equal?(self) || rs.loaded_from != loaded_from
|
|
130
133
|
rs = Gem::Specification.load(loaded_from)
|
|
131
134
|
Bundler.rubygems.stub_set_spec(stub, rs)
|
|
132
135
|
end
|
|
@@ -6,19 +6,19 @@ source "https://rubygems.org"
|
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
8
|
gem "irb"
|
|
9
|
-
gem "rake", "
|
|
9
|
+
gem "rake", ">= 13.0"
|
|
10
10
|
<%- if config[:ext] -%>
|
|
11
11
|
|
|
12
12
|
gem "rake-compiler"
|
|
13
13
|
<%- end -%>
|
|
14
14
|
<%- if config[:test] -%>
|
|
15
15
|
|
|
16
|
-
gem "<%= config[:test] %>"
|
|
16
|
+
gem "<%= config[:test] %>"
|
|
17
17
|
<%- end -%>
|
|
18
18
|
<%- if config[:linter] == "rubocop" -%>
|
|
19
19
|
|
|
20
|
-
gem "rubocop"
|
|
20
|
+
gem "rubocop"
|
|
21
21
|
<%- elsif config[:linter] == "standard" -%>
|
|
22
22
|
|
|
23
|
-
gem "standard"
|
|
23
|
+
gem "standard"
|
|
24
24
|
<%- end -%>
|
|
@@ -45,12 +45,12 @@ Gem::Specification.new do |spec|
|
|
|
45
45
|
<%- end -%>
|
|
46
46
|
|
|
47
47
|
# Uncomment to register a new dependency of your gem
|
|
48
|
-
# spec.add_dependency "example-gem", "
|
|
48
|
+
# spec.add_dependency "example-gem", ">= 1.0"
|
|
49
49
|
<%- if config[:ext] == 'rust' -%>
|
|
50
|
-
spec.add_dependency "rb_sys", "
|
|
50
|
+
spec.add_dependency "rb_sys", ">= 0.9.128"
|
|
51
51
|
<%- end -%>
|
|
52
52
|
<%- if config[:ext] == 'go' -%>
|
|
53
|
-
spec.add_dependency "go_gem", "
|
|
53
|
+
spec.add_dependency "go_gem", ">= 0.2"
|
|
54
54
|
<%- end -%>
|
|
55
55
|
|
|
56
56
|
# For more information and examples about making a new gem, check out our
|
|
@@ -9,7 +9,7 @@ RSpec.describe <%= config[:constant_name] %> do
|
|
|
9
9
|
it "can call into Rust" do
|
|
10
10
|
result = <%= config[:constant_name] %>.hello("world")
|
|
11
11
|
|
|
12
|
-
expect(result).to
|
|
12
|
+
expect(result).to eq("Hello world, from Rust!")
|
|
13
13
|
end
|
|
14
14
|
<%- else -%>
|
|
15
15
|
it "does something useful" do
|
|
@@ -9,7 +9,7 @@ class <%= config[:minitest_constant_name] %> < Minitest::Test
|
|
|
9
9
|
|
|
10
10
|
<%- if config[:ext] == 'rust' -%>
|
|
11
11
|
def test_hello_world
|
|
12
|
-
assert_equal "Hello
|
|
12
|
+
assert_equal "Hello world, from Rust!", <%= config[:constant_name] %>.hello("world")
|
|
13
13
|
end
|
|
14
14
|
<%- else -%>
|
|
15
15
|
def test_it_does_something_useful
|
data/lib/bundler/ui/shell.rb
CHANGED
data/lib/bundler/ui/silent.rb
CHANGED
|
@@ -2,6 +2,38 @@ require_relative "empty_directory"
|
|
|
2
2
|
|
|
3
3
|
class Bundler::Thor
|
|
4
4
|
module Actions
|
|
5
|
+
WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
|
|
6
|
+
|
|
7
|
+
# Injects the given content into a file, raising an error if the contents of
|
|
8
|
+
# the file are not changed. Different from gsub_file, this method is reversible.
|
|
9
|
+
#
|
|
10
|
+
# ==== Parameters
|
|
11
|
+
# destination<String>:: Relative path to the destination root
|
|
12
|
+
# data<String>:: Data to add to the file. Can be given as a block.
|
|
13
|
+
# config<Hash>:: give :verbose => false to not log the status and the flag
|
|
14
|
+
# for injection (:after or :before) or :force => true for
|
|
15
|
+
# insert two or more times the same content.
|
|
16
|
+
#
|
|
17
|
+
# ==== Examples
|
|
18
|
+
#
|
|
19
|
+
# insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
|
|
20
|
+
#
|
|
21
|
+
# insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
|
|
22
|
+
# gems = ask "Which gems would you like to add?"
|
|
23
|
+
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
def insert_into_file!(destination, *args, &block)
|
|
27
|
+
data = block_given? ? block : args.shift
|
|
28
|
+
|
|
29
|
+
config = args.shift || {}
|
|
30
|
+
config[:after] = /\z/ unless config.key?(:before) || config.key?(:after)
|
|
31
|
+
config = config.merge({error_on_no_change: true})
|
|
32
|
+
|
|
33
|
+
action InjectIntoFile.new(self, destination, data, config)
|
|
34
|
+
end
|
|
35
|
+
alias_method :inject_into_file!, :insert_into_file!
|
|
36
|
+
|
|
5
37
|
# Injects the given content into a file. Different from gsub_file, this
|
|
6
38
|
# method is reversible.
|
|
7
39
|
#
|
|
@@ -21,8 +53,6 @@ class Bundler::Thor
|
|
|
21
53
|
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
|
|
22
54
|
# end
|
|
23
55
|
#
|
|
24
|
-
WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
|
|
25
|
-
|
|
26
56
|
def insert_into_file(destination, *args, &block)
|
|
27
57
|
data = block_given? ? block : args.shift
|
|
28
58
|
|
|
@@ -47,6 +77,7 @@ class Bundler::Thor
|
|
|
47
77
|
|
|
48
78
|
@replacement = data.is_a?(Proc) ? data.call : data
|
|
49
79
|
@flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
|
|
80
|
+
@error_on_no_change = @config.fetch(:error_on_no_change, false)
|
|
50
81
|
end
|
|
51
82
|
|
|
52
83
|
def invoke!
|
|
@@ -59,6 +90,8 @@ class Bundler::Thor
|
|
|
59
90
|
if exists?
|
|
60
91
|
if replace!(/#{flag}/, content, config[:force])
|
|
61
92
|
say_status(:invoke)
|
|
93
|
+
elsif @error_on_no_change
|
|
94
|
+
raise Bundler::Thor::Error, "The content of #{destination} did not change"
|
|
62
95
|
elsif replacement_present?
|
|
63
96
|
say_status(:unchanged, color: :blue)
|
|
64
97
|
else
|
|
@@ -13,8 +13,9 @@ class Bundler::Thor
|
|
|
13
13
|
autoload :RakeCompat, File.expand_path("rake_compat", __dir__)
|
|
14
14
|
autoload :Group, File.expand_path("group", __dir__)
|
|
15
15
|
|
|
16
|
-
# Shortcuts for help.
|
|
16
|
+
# Shortcuts for help and tree commands.
|
|
17
17
|
HELP_MAPPINGS = %w(-h -? --help -D)
|
|
18
|
+
TREE_MAPPINGS = %w(-t --tree)
|
|
18
19
|
|
|
19
20
|
# Bundler::Thor methods that should not be overwritten by the user.
|
|
20
21
|
THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
|