rubygems-update 3.2.29 → 3.2.33

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.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +136 -0
  3. data/Manifest.txt +32 -1
  4. data/bundler/CHANGELOG.md +79 -1
  5. data/bundler/README.md +1 -1
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/cli/doctor.rb +3 -2
  8. data/bundler/lib/bundler/cli/gem.rb +69 -7
  9. data/bundler/lib/bundler/cli/info.rb +16 -4
  10. data/bundler/lib/bundler/cli/issue.rb +4 -3
  11. data/bundler/lib/bundler/cli/update.rb +2 -2
  12. data/bundler/lib/bundler/cli.rb +4 -1
  13. data/bundler/lib/bundler/compact_index_client/updater.rb +0 -5
  14. data/bundler/lib/bundler/compact_index_client.rb +2 -2
  15. data/bundler/lib/bundler/definition.rb +62 -124
  16. data/bundler/lib/bundler/digest.rb +71 -0
  17. data/bundler/lib/bundler/dsl.rb +18 -3
  18. data/bundler/lib/bundler/environment_preserver.rb +4 -1
  19. data/bundler/lib/bundler/errors.rb +18 -2
  20. data/bundler/lib/bundler/fetcher.rb +2 -1
  21. data/bundler/lib/bundler/friendly_errors.rb +5 -30
  22. data/bundler/lib/bundler/gem_helper.rb +5 -16
  23. data/bundler/lib/bundler/lazy_specification.rb +17 -1
  24. data/bundler/lib/bundler/lockfile_parser.rb +1 -0
  25. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  26. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  27. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  28. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  29. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  30. data/bundler/lib/bundler/man/bundle-config.1 +3 -3
  31. data/bundler/lib/bundler/man/bundle-config.1.ronn +2 -2
  32. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  33. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  34. data/bundler/lib/bundler/man/bundle-gem.1 +14 -1
  35. data/bundler/lib/bundler/man/bundle-gem.1.ronn +16 -0
  36. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  37. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  38. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  39. data/bundler/lib/bundler/man/bundle-install.1 +1 -1
  40. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  41. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  42. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  43. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  44. data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
  45. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  46. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  47. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  48. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  49. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  50. data/bundler/lib/bundler/man/bundle.1 +1 -1
  51. data/bundler/lib/bundler/man/gemfile.5 +27 -1
  52. data/bundler/lib/bundler/man/gemfile.5.ronn +8 -0
  53. data/bundler/lib/bundler/plugin/api/source.rb +1 -0
  54. data/bundler/lib/bundler/resolver.rb +2 -4
  55. data/bundler/lib/bundler/rubygems_ext.rb +4 -0
  56. data/bundler/lib/bundler/rubygems_gem_installer.rb +20 -4
  57. data/bundler/lib/bundler/rubygems_integration.rb +26 -9
  58. data/bundler/lib/bundler/runtime.rb +2 -2
  59. data/bundler/lib/bundler/shared_helpers.rb +2 -3
  60. data/bundler/lib/bundler/source/git/git_proxy.rb +7 -4
  61. data/bundler/lib/bundler/source/git.rb +3 -1
  62. data/bundler/lib/bundler/source/rubygems.rb +52 -84
  63. data/bundler/lib/bundler/source/rubygems_aggregate.rb +1 -1
  64. data/bundler/lib/bundler/source.rb +1 -1
  65. data/bundler/lib/bundler/source_list.rb +7 -29
  66. data/bundler/lib/bundler/spec_set.rb +1 -1
  67. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  68. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +5 -1
  69. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -2
  70. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -12
  71. data/bundler/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  72. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +2 -0
  73. data/bundler/lib/bundler/vendor/.document +1 -0
  74. data/bundler/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  75. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  76. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  77. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  78. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  79. data/bundler/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  80. data/bundler/lib/bundler/vendor/molinillo/LICENSE +9 -0
  81. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  82. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  83. data/bundler/lib/bundler/vendor/thor/LICENSE.md +20 -0
  84. data/bundler/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  85. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  86. data/bundler/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  87. data/bundler/lib/bundler/vendored_tsort.rb +4 -0
  88. data/bundler/lib/bundler/version.rb +1 -1
  89. data/bundler/lib/bundler/worker.rb +2 -2
  90. data/bundler/lib/bundler.rb +2 -1
  91. data/lib/rubygems/command.rb +4 -4
  92. data/lib/rubygems/command_manager.rb +3 -1
  93. data/lib/rubygems/commands/cert_command.rb +18 -11
  94. data/lib/rubygems/commands/fetch_command.rb +1 -1
  95. data/lib/rubygems/commands/pristine_command.rb +8 -2
  96. data/lib/rubygems/commands/server_command.rb +3 -3
  97. data/lib/rubygems/commands/setup_command.rb +82 -62
  98. data/lib/rubygems/commands/uninstall_command.rb +1 -1
  99. data/lib/rubygems/commands/update_command.rb +1 -1
  100. data/lib/rubygems/core_ext/tcpsocket_init.rb +2 -2
  101. data/lib/rubygems/dependency_list.rb +2 -2
  102. data/lib/rubygems/exceptions.rb +1 -0
  103. data/lib/rubygems/ext/builder.rb +6 -5
  104. data/lib/rubygems/ext/cmake_builder.rb +1 -1
  105. data/lib/rubygems/install_update_options.rb +2 -2
  106. data/lib/rubygems/installer.rb +35 -26
  107. data/lib/rubygems/local_remote_options.rb +3 -3
  108. data/lib/rubygems/optparse/.document +1 -0
  109. data/lib/rubygems/optparse/COPYING +56 -0
  110. data/lib/rubygems/optparse/lib/optionparser.rb +2 -0
  111. data/lib/rubygems/optparse/lib/optparse/ac.rb +54 -0
  112. data/lib/rubygems/optparse/lib/optparse/date.rb +18 -0
  113. data/lib/rubygems/optparse/lib/optparse/kwargs.rb +22 -0
  114. data/lib/rubygems/optparse/lib/optparse/shellwords.rb +7 -0
  115. data/lib/rubygems/optparse/lib/optparse/time.rb +11 -0
  116. data/lib/rubygems/optparse/lib/optparse/uri.rb +7 -0
  117. data/lib/rubygems/optparse/lib/optparse/version.rb +71 -0
  118. data/lib/rubygems/optparse/lib/optparse.rb +2230 -0
  119. data/lib/rubygems/optparse.rb +3 -0
  120. data/lib/rubygems/package.rb +24 -34
  121. data/lib/rubygems/query_utils.rb +4 -4
  122. data/lib/rubygems/remote_fetcher.rb +2 -2
  123. data/lib/rubygems/request/connection_pools.rb +1 -1
  124. data/lib/rubygems/request/http_pool.rb +1 -1
  125. data/lib/rubygems/request.rb +2 -0
  126. data/lib/rubygems/request_set.rb +3 -3
  127. data/lib/rubygems/resolver/molinillo/LICENSE +9 -0
  128. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  129. data/lib/rubygems/s3_uri_signer.rb +4 -5
  130. data/lib/rubygems/security/policy.rb +5 -3
  131. data/lib/rubygems/security/signer.rb +3 -4
  132. data/lib/rubygems/security.rb +49 -15
  133. data/lib/rubygems/security_option.rb +3 -3
  134. data/lib/rubygems/source/git.rb +2 -2
  135. data/lib/rubygems/source.rb +1 -1
  136. data/lib/rubygems/specification.rb +45 -43
  137. data/lib/rubygems/tsort/.document +1 -0
  138. data/lib/rubygems/tsort/LICENSE.txt +22 -0
  139. data/lib/rubygems/tsort/lib/tsort.rb +454 -0
  140. data/lib/rubygems/tsort.rb +3 -0
  141. data/lib/rubygems/user_interaction.rb +1 -1
  142. data/lib/rubygems/util/licenses.rb +2 -0
  143. data/lib/rubygems/util.rb +1 -1
  144. data/lib/rubygems/version_option.rb +2 -2
  145. data/lib/rubygems.rb +22 -22
  146. data/rubygems-update.gemspec +1 -1
  147. data/test/rubygems/encrypted_private_key.pem +26 -26
  148. data/test/rubygems/helper.rb +30 -44
  149. data/test/rubygems/private_ec_key.pem +9 -0
  150. data/test/rubygems/test_gem.rb +59 -71
  151. data/test/rubygems/test_gem_command.rb +1 -1
  152. data/test/rubygems/test_gem_command_manager.rb +12 -0
  153. data/test/rubygems/test_gem_commands_cert_command.rb +71 -12
  154. data/test/rubygems/test_gem_commands_fetch_command.rb +36 -0
  155. data/test/rubygems/test_gem_commands_server_command.rb +3 -3
  156. data/test/rubygems/test_gem_commands_setup_command.rb +67 -19
  157. data/test/rubygems/test_gem_commands_signin_command.rb +1 -1
  158. data/test/rubygems/test_gem_commands_uninstall_command.rb +1 -1
  159. data/test/rubygems/test_gem_commands_yank_command.rb +1 -1
  160. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +7 -3
  161. data/test/rubygems/test_gem_install_update_options.rb +2 -2
  162. data/test/rubygems/test_gem_installer.rb +37 -5
  163. data/test/rubygems/test_gem_package.rb +27 -26
  164. data/test/rubygems/test_gem_request.rb +10 -4
  165. data/test/rubygems/test_gem_resolver.rb +7 -7
  166. data/test/rubygems/test_gem_security.rb +32 -4
  167. data/test/rubygems/test_gem_specification.rb +211 -232
  168. data/test/rubygems/test_require.rb +10 -30
  169. metadata +38 -7
  170. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -76,6 +76,7 @@ module Bundler
76
76
  "#{Bundler.preferred_gemfile_name}.tt" => Bundler.preferred_gemfile_name,
77
77
  "lib/newgem.rb.tt" => "lib/#{namespaced_path}.rb",
78
78
  "lib/newgem/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
79
+ "sig/newgem.rbs.tt" => "sig/#{namespaced_path}.rbs",
79
80
  "newgem.gemspec.tt" => "#{name}.gemspec",
80
81
  "Rakefile.tt" => "Rakefile",
81
82
  "README.md.tt" => "README.md",
@@ -163,15 +164,16 @@ module Bundler
163
164
  templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
164
165
  end
165
166
 
166
- if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
167
- "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
168
- "of the guidelines in the community style guide. " \
169
- "For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
170
- "and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
171
- config[:rubocop] = true
172
- config[:rubocop_version] = rubocop_version
167
+ config[:linter] = ask_and_set_linter
168
+ case config[:linter]
169
+ when "rubocop"
170
+ config[:linter_version] = rubocop_version
173
171
  Bundler.ui.info "RuboCop enabled in config"
174
172
  templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
173
+ when "standard"
174
+ config[:linter_version] = standard_version
175
+ Bundler.ui.info "Standard enabled in config"
176
+ templates.merge!("standard.yml.tt" => ".standard.yml")
175
177
  end
176
178
 
177
179
  templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
@@ -317,6 +319,58 @@ module Bundler
317
319
  ci_template
318
320
  end
319
321
 
322
+ def ask_and_set_linter
323
+ linter_template = options[:linter] || Bundler.settings["gem.linter"]
324
+ linter_template = deprecated_rubocop_option if linter_template.nil?
325
+
326
+ if linter_template.to_s.empty?
327
+ Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
328
+ "Supported Linters:\n" \
329
+ "* RuboCop: https://rubocop.org\n" \
330
+ "* Standard: https://github.com/testdouble/standard\n" \
331
+ "\n"
332
+ Bundler.ui.info hint_text("linter")
333
+
334
+ result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
335
+ if result =~ /rubocop|standard/
336
+ linter_template = result
337
+ else
338
+ linter_template = false
339
+ end
340
+ end
341
+
342
+ if Bundler.settings["gem.linter"].nil?
343
+ Bundler.settings.set_global("gem.linter", linter_template)
344
+ end
345
+
346
+ # Once gem.linter safely set, unset the deprecated gem.rubocop
347
+ unless Bundler.settings["gem.rubocop"].nil?
348
+ Bundler.settings.set_global("gem.rubocop", nil)
349
+ end
350
+
351
+ if options[:linter] == Bundler.settings["gem.linter"]
352
+ Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
353
+ end
354
+
355
+ linter_template
356
+ end
357
+
358
+ def deprecated_rubocop_option
359
+ if !options[:rubocop].nil?
360
+ if options[:rubocop]
361
+ Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
362
+ "rubocop"
363
+ else
364
+ Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
365
+ false
366
+ end
367
+ elsif !Bundler.settings["gem.rubocop"].nil?
368
+ Bundler::SharedHelpers.major_deprecation 2,
369
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
370
+ Bundler.settings["gem.rubocop"] ? "rubocop" : false
371
+ end
372
+ end
373
+
320
374
  def bundler_dependency_version
321
375
  v = Gem::Version.new(Bundler::VERSION)
322
376
  req = v.segments[0..1]
@@ -367,5 +421,13 @@ module Bundler
367
421
  "1.21"
368
422
  end
369
423
  end
424
+
425
+ def standard_version
426
+ if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5"
427
+ elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0"
428
+ else
429
+ "1.3"
430
+ end
431
+ end
370
432
  end
371
433
  end
@@ -18,6 +18,7 @@ module Bundler
18
18
 
19
19
  if spec
20
20
  return print_gem_path(spec) if @options[:path]
21
+ return print_gem_version(spec) if @options[:version]
21
22
  print_gem_info(spec)
22
23
  end
23
24
  end
@@ -39,13 +40,18 @@ module Bundler
39
40
  raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(gem_name, Bundler.definition.dependencies)
40
41
  end
41
42
 
43
+ def print_gem_version(spec)
44
+ Bundler.ui.info spec.version.to_s
45
+ end
46
+
42
47
  def print_gem_path(spec)
43
- if spec.name == "bundler"
48
+ name = spec.name
49
+ if name == "bundler"
44
50
  path = File.expand_path("../../../..", __FILE__)
45
51
  else
46
52
  path = spec.full_gem_path
47
- unless File.directory?(path)
48
- return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
53
+ if spec.deleted_gem?
54
+ return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}"
49
55
  end
50
56
  end
51
57
 
@@ -54,8 +60,9 @@ module Bundler
54
60
 
55
61
  def print_gem_info(spec)
56
62
  metadata = spec.metadata
63
+ name = spec.name
57
64
  gem_info = String.new
58
- gem_info << " * #{spec.name} (#{spec.version}#{spec.git_version})\n"
65
+ gem_info << " * #{name} (#{spec.version}#{spec.git_version})\n"
59
66
  gem_info << "\tSummary: #{spec.summary}\n" if spec.summary
60
67
  gem_info << "\tHomepage: #{spec.homepage}\n" if spec.homepage
61
68
  gem_info << "\tDocumentation: #{metadata["documentation_uri"]}\n" if metadata.key?("documentation_uri")
@@ -67,6 +74,11 @@ module Bundler
67
74
  gem_info << "\tMailing List: #{metadata["mailing_list_uri"]}\n" if metadata.key?("mailing_list_uri")
68
75
  gem_info << "\tPath: #{spec.full_gem_path}\n"
69
76
  gem_info << "\tDefault Gem: yes" if spec.respond_to?(:default_gem?) && spec.default_gem?
77
+
78
+ if name != "bundler" && spec.deleted_gem?
79
+ return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}"
80
+ end
81
+
70
82
  Bundler.ui.info gem_info
71
83
  end
72
84
  end
@@ -20,9 +20,10 @@ module Bundler
20
20
 
21
21
  Hopefully the troubleshooting steps above resolved your problem! If things
22
22
  still aren't working the way you expect them to, please let us know so
23
- that we can diagnose and help fix the problem you're having. Please
24
- view the Filing Issues guide for more information:
25
- https://github.com/rubygems/rubygems/blob/master/bundler/doc/contributing/ISSUES.md
23
+ that we can diagnose and help fix the problem you're having, by filling
24
+ in the new issue form located at
25
+ https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md,
26
+ and copy and pasting the information below.
26
27
 
27
28
  EOS
28
29
 
@@ -66,7 +66,7 @@ module Bundler
66
66
 
67
67
  if locked_gems = Bundler.definition.locked_gems
68
68
  previous_locked_info = locked_gems.specs.reduce({}) do |h, s|
69
- h[s.name] = { :spec => s, :version => s.version, :source => s.source.to_s }
69
+ h[s.name] = { :spec => s, :version => s.version, :source => s.source.identifier }
70
70
  h
71
71
  end
72
72
  end
@@ -95,7 +95,7 @@ module Bundler
95
95
  end
96
96
 
97
97
  locked_source = locked_info[:source]
98
- new_source = new_spec.source.to_s
98
+ new_source = new_spec.source.identifier
99
99
  next if locked_source != new_source
100
100
 
101
101
  new_version = new_spec.version
@@ -331,6 +331,7 @@ module Bundler
331
331
 
332
332
  desc "info GEM [OPTIONS]", "Show information for the given gem"
333
333
  method_option "path", :type => :boolean, :banner => "Print full path to gem"
334
+ method_option "version", :type => :boolean, :banner => "Print gem version"
334
335
  def info(gem_name)
335
336
  require_relative "cli/info"
336
337
  Info.new(options, gem_name).run
@@ -552,7 +553,7 @@ module Bundler
552
553
  method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
553
554
  method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
554
555
  def viz
555
- SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
556
+ SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
556
557
  require_relative "cli/viz"
557
558
  Viz.new(options.dup).run
558
559
  end
@@ -575,6 +576,8 @@ module Bundler
575
576
  :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
576
577
  method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
577
578
  :desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
579
+ method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
580
+ :desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
578
581
  method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
579
582
 
580
583
  def gem(name)
@@ -76,11 +76,6 @@ module Bundler
76
76
 
77
77
  update(local_path, remote_path, :retrying)
78
78
  end
79
- rescue Errno::EACCES
80
- raise Bundler::PermissionError,
81
- "Bundler does not have write access to create a temp directory " \
82
- "within #{Dir.tmpdir}. Bundler must have write access to your " \
83
- "systems temp directory to function properly. "
84
79
  rescue Zlib::GzipFile::Error
85
80
  raise Bundler::HTTPError
86
81
  end
@@ -5,7 +5,7 @@ require "set"
5
5
 
6
6
  module Bundler
7
7
  class CompactIndexClient
8
- DEBUG_MUTEX = Mutex.new
8
+ DEBUG_MUTEX = Thread::Mutex.new
9
9
  def self.debug
10
10
  return unless ENV["DEBUG_COMPACT_INDEX"]
11
11
  DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
@@ -25,7 +25,7 @@ module Bundler
25
25
  @endpoints = Set.new
26
26
  @info_checksums_by_name = {}
27
27
  @parsed_checksums = false
28
- @mutex = Mutex.new
28
+ @mutex = Thread::Mutex.new
29
29
  end
30
30
 
31
31
  def execution_mode=(block)
@@ -73,7 +73,6 @@ module Bundler
73
73
  @lockfile_contents = String.new
74
74
  @locked_bundler_version = nil
75
75
  @locked_ruby_version = nil
76
- @locked_specs_incomplete_for_platform = false
77
76
  @new_platform = nil
78
77
 
79
78
  if lockfile && File.exist?(lockfile)
@@ -139,6 +138,8 @@ module Bundler
139
138
  @dependency_changes = converge_dependencies
140
139
  @local_changes = converge_locals
141
140
 
141
+ @locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
142
+
142
143
  @requires = compute_requires
143
144
  end
144
145
 
@@ -157,10 +158,6 @@ module Bundler
157
158
  end
158
159
  end
159
160
 
160
- def multisource_allowed?
161
- @multisource_allowed
162
- end
163
-
164
161
  def resolve_only_locally!
165
162
  @remote = false
166
163
  sources.local_only!
@@ -228,17 +225,22 @@ module Bundler
228
225
  end
229
226
  end
230
227
 
228
+ def locked_dependencies
229
+ @locked_deps.values
230
+ end
231
+
231
232
  def specs_for(groups)
232
- groups = requested_groups if groups.empty?
233
+ return specs if groups.empty?
233
234
  deps = dependencies_for(groups)
234
- materialize(expand_dependencies(deps))
235
+ materialize(deps)
235
236
  end
236
237
 
237
238
  def dependencies_for(groups)
238
239
  groups.map!(&:to_sym)
239
- current_dependencies.reject do |d|
240
+ deps = current_dependencies.reject do |d|
240
241
  (d.groups & groups).empty?
241
242
  end
243
+ expand_dependencies(deps)
242
244
  end
243
245
 
244
246
  # Resolve all the dependencies specified in Gemfile. It ensures that
@@ -362,44 +364,26 @@ module Bundler
362
364
  added.concat new_platforms.map {|p| "* platform: #{p}" }
363
365
  deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
364
366
 
365
- gemfile_sources = sources.lock_sources
366
-
367
- new_sources = gemfile_sources - @locked_sources
368
- deleted_sources = @locked_sources - gemfile_sources
369
-
370
- new_deps = @dependencies - @locked_deps.values
371
- deleted_deps = @locked_deps.values - @dependencies
372
-
373
- # Check if it is possible that the source is only changed thing
374
- if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
375
- new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
376
- deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
377
- end
378
-
379
- if @locked_sources != gemfile_sources
380
- if new_sources.any?
381
- added.concat new_sources.map {|source| "* source: #{source}" }
382
- end
383
-
384
- if deleted_sources.any?
385
- deleted.concat deleted_sources.map {|source| "* source: #{source}" }
386
- end
387
- end
367
+ new_deps = @dependencies - locked_dependencies
368
+ deleted_deps = locked_dependencies - @dependencies
388
369
 
389
370
  added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
390
- if deleted_deps.any?
391
- deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
392
- end
371
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
393
372
 
394
373
  both_sources = Hash.new {|h, k| h[k] = [] }
395
374
  @dependencies.each {|d| both_sources[d.name][0] = d }
396
- @locked_deps.each {|name, d| both_sources[name][1] = d.source }
375
+ locked_dependencies.each {|d| both_sources[d.name][1] = d }
376
+
377
+ both_sources.each do |name, (dep, lock_dep)|
378
+ next if dep.nil? || lock_dep.nil?
397
379
 
398
- both_sources.each do |name, (dep, lock_source)|
399
- next if lock_source.nil? || (dep && lock_source.can_lock?(dep))
400
- gemfile_source_name = (dep && dep.source) || "no specified source"
401
- lockfile_source_name = lock_source
402
- changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
380
+ gemfile_source = dep.source || sources.default_source
381
+ lock_source = lock_dep.source || sources.default_source
382
+ next if lock_source.include?(gemfile_source)
383
+
384
+ gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source"
385
+ lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
386
+ changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
403
387
  end
404
388
 
405
389
  reason = change_reason
@@ -560,7 +544,7 @@ module Bundler
560
544
 
561
545
  def dependencies_for_source_changed?(source, locked_source = source)
562
546
  deps_for_source = @dependencies.select {|s| s.source == source }
563
- locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
547
+ locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
564
548
 
565
549
  deps_for_source.uniq.sort != locked_deps_for_source.sort
566
550
  end
@@ -643,25 +627,14 @@ module Bundler
643
627
  end
644
628
 
645
629
  def converge_dependencies
646
- frozen = Bundler.frozen_bundle?
647
- (@dependencies + @locked_deps.values).each do |dep|
648
- locked_source = @locked_deps[dep.name]
649
- # This is to make sure that if bundler is installing in deployment mode and
650
- # after locked_source and sources don't match, we still use locked_source.
651
- if frozen && !locked_source.nil? &&
652
- locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
653
- dep.source = locked_source.source
654
- elsif dep.source
630
+ changes = false
631
+
632
+ @dependencies.each do |dep|
633
+ if dep.source
655
634
  dep.source = sources.get(dep.source)
656
635
  end
657
- end
658
636
 
659
- changes = false
660
- # We want to know if all match, but don't want to check all entries
661
- # This means we need to return false if any dependency doesn't match
662
- # the lock or doesn't exist in the lock.
663
- @dependencies.each do |dependency|
664
- unless locked_dep = @locked_deps[dependency.name]
637
+ unless locked_dep = @locked_deps[dep.name]
665
638
  changes = true
666
639
  next
667
640
  end
@@ -672,11 +645,11 @@ module Bundler
672
645
  # directive, the lockfile dependencies and resolved dependencies end up
673
646
  # with a mismatch on #type. Work around that by setting the type on the
674
647
  # dep from the lockfile.
675
- locked_dep.instance_variable_set(:@type, dependency.type)
648
+ locked_dep.instance_variable_set(:@type, dep.type)
676
649
 
677
650
  # We already know the name matches from the hash lookup
678
651
  # so we only need to check the requirement now
679
- changes ||= dependency.requirement != locked_dep.requirement
652
+ changes ||= dep.requirement != locked_dep.requirement
680
653
  end
681
654
 
682
655
  changes
@@ -686,39 +659,36 @@ module Bundler
686
659
  # commonly happen if the Gemfile has changed since the lockfile was last
687
660
  # generated
688
661
  def converge_locked_specs
689
- deps = []
690
-
691
- # Build a list of dependencies that are the same in the Gemfile
692
- # and Gemfile.lock. If the Gemfile modified a dependency, but
693
- # the gem in the Gemfile.lock still satisfies it, this is fine
694
- # too.
695
- @dependencies.each do |dep|
696
- locked_dep = @locked_deps[dep.name]
662
+ resolve = converge_specs(@locked_specs)
697
663
 
698
- # If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
699
- locked_dep = nil unless locked_dep == dep
664
+ diff = nil
700
665
 
701
- if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
702
- deps << dep
703
- elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
704
- @locked_specs.each do |s|
705
- @unlock[:gems] << s.name if s.source == dep.source
706
- end
666
+ # Now, we unlock any sources that do not have anymore gems pinned to it
667
+ sources.all_sources.each do |source|
668
+ next unless source.respond_to?(:unlock!)
707
669
 
708
- dep.source.unlock! if dep.source.respond_to?(:unlock!)
709
- dep.source.specs.each {|s| @unlock[:gems] << s.name }
670
+ unless resolve.any? {|s| s.source == source }
671
+ diff ||= @locked_specs.to_a - resolve.to_a
672
+ source.unlock! if diff.any? {|s| s.source == source }
710
673
  end
711
674
  end
712
675
 
676
+ resolve
677
+ end
678
+
679
+ def converge_specs(specs)
680
+ deps = []
713
681
  converged = []
714
- @locked_specs.each do |s|
682
+ specs.each do |s|
715
683
  # Replace the locked dependency's source with the equivalent source from the Gemfile
716
684
  dep = @dependencies.find {|d| s.satisfies?(d) }
717
- s.source = (dep && dep.source) || sources.get(s.source) unless multisource_allowed?
718
685
 
719
- # Don't add a spec to the list if its source is expired. For example,
720
- # if you change a Git gem to RubyGems.
721
- next if s.source.nil?
686
+ if dep && (!dep.source || s.source.include?(dep.source))
687
+ deps << dep
688
+ end
689
+
690
+ s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle?
691
+
722
692
  next if @unlock[:sources].include?(s.source.name)
723
693
 
724
694
  # If the spec is from a path source and it doesn't exist anymore
@@ -731,7 +701,7 @@ module Bundler
731
701
  rescue PathError, GitError
732
702
  # if we won't need the source (according to the lockfile),
733
703
  # don't error if the path/git source isn't available
734
- next if @locked_specs.
704
+ next if specs.
735
705
  for(requested_dependencies, false, true).
736
706
  none? {|locked_spec| locked_spec.source == s.source }
737
707
 
@@ -747,36 +717,15 @@ module Bundler
747
717
  s.dependencies.replace(new_spec.dependencies)
748
718
  end
749
719
 
750
- converged << s
751
- end
752
-
753
- resolve = SpecSet.new(converged)
754
- @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
755
- resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
756
- diff = nil
757
-
758
- # Now, we unlock any sources that do not have anymore gems pinned to it
759
- sources.all_sources.each do |source|
760
- next unless source.respond_to?(:unlock!)
761
-
762
- unless resolve.any? {|s| s.source == source }
763
- diff ||= @locked_specs.to_a - resolve.to_a
764
- source.unlock! if diff.any? {|s| s.source == source }
720
+ if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
721
+ @unlock[:gems] << s.name
722
+ else
723
+ converged << s
765
724
  end
766
725
  end
767
726
 
768
- resolve
769
- end
770
-
771
- def in_locked_deps?(dep, locked_dep)
772
- # Because the lockfile can't link a dep to a specific remote, we need to
773
- # treat sources as equivalent anytime the locked dep has all the remotes
774
- # that the Gemfile dep does.
775
- locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
776
- end
777
-
778
- def satisfies_locked_spec?(dep)
779
- @locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
727
+ resolve = SpecSet.new(converged)
728
+ SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
780
729
  end
781
730
 
782
731
  def metadata_dependencies
@@ -869,22 +818,11 @@ module Bundler
869
818
 
870
819
  def additional_base_requirements_for_resolve
871
820
  return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
872
- dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
873
- @locked_gems.specs.reduce({}) do |requirements, locked_spec|
821
+ converge_specs(@locked_gems.specs).map do |locked_spec|
874
822
  name = locked_spec.name
875
- dependency = dependencies_by_name[name]
876
- next requirements if @locked_gems.dependencies[name] != dependency
877
- next requirements if dependency && dependency.source.is_a?(Source::Path)
878
823
  dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
879
- requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
880
- requirements
881
- end.values
882
- end
883
-
884
- def equivalent_rubygems_remotes?(source)
885
- return false unless source.is_a?(Source::Rubygems)
886
-
887
- Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
824
+ DepProxy.get_proxy(dep, locked_spec.platform)
825
+ end
888
826
  end
889
827
 
890
828
  def source_map
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This code was extracted from https://github.com/Solistra/ruby-digest which is under public domain
4
+ module Bundler
5
+ module Digest
6
+ # The initial constant values for the 32-bit constant words A, B, C, D, and
7
+ # E, respectively.
8
+ SHA1_WORDS = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0].freeze
9
+
10
+ # The 8-bit field used for bitwise `AND` masking. Defaults to `0xFFFFFFFF`.
11
+ SHA1_MASK = 0xFFFFFFFF
12
+
13
+ class << self
14
+ def sha1(string)
15
+ unless string.is_a?(String)
16
+ raise TypeError, "can't convert #{string.class.inspect} into String"
17
+ end
18
+
19
+ buffer = string.b
20
+
21
+ words = SHA1_WORDS.dup
22
+ generate_split_buffer(buffer) do |chunk|
23
+ w = []
24
+ chunk.each_slice(4) do |a, b, c, d|
25
+ w << (((a << 8 | b) << 8 | c) << 8 | d)
26
+ end
27
+ a, b, c, d, e = *words
28
+ (16..79).each do |i|
29
+ w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
30
+ end
31
+ 0.upto(79) do |i|
32
+ case i
33
+ when 0..19
34
+ f = ((b & c) | (~b & d))
35
+ k = 0x5A827999
36
+ when 20..39
37
+ f = (b ^ c ^ d)
38
+ k = 0x6ED9EBA1
39
+ when 40..59
40
+ f = ((b & c) | (b & d) | (c & d))
41
+ k = 0x8F1BBCDC
42
+ when 60..79
43
+ f = (b ^ c ^ d)
44
+ k = 0xCA62C1D6
45
+ end
46
+ t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i])
47
+ a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment
48
+ end
49
+ mutated = [a, b, c, d, e]
50
+ words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) }
51
+ end
52
+
53
+ words.pack("N*").unpack("H*").first
54
+ end
55
+
56
+ private
57
+
58
+ def generate_split_buffer(string, &block)
59
+ size = string.bytesize * 8
60
+ buffer = string.bytes << 128
61
+ buffer << 0 while buffer.size % 64 != 56
62
+ buffer.concat([size].pack("Q>").bytes)
63
+ buffer.each_slice(64, &block)
64
+ end
65
+
66
+ def rotate(value, spaces)
67
+ value << spaces | value >> (32 - spaces)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -18,6 +18,8 @@ module Bundler
18
18
  VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
19
19
  platform platforms type source install_if gemfile].freeze
20
20
 
21
+ GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze
22
+
21
23
  attr_reader :gemspecs
22
24
  attr_accessor :dependencies
23
25
 
@@ -278,8 +280,17 @@ module Bundler
278
280
  warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
279
281
  "https://github.com/#{repo_name}.git"
280
282
  RUBY
281
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
282
- "https://github.com/#{repo_name}.git"
283
+ if repo_name =~ GITHUB_PULL_REQUEST_URL
284
+ {
285
+ "git" => "https://github.com/#{$1}.git",
286
+ "branch" => "refs/pull/#{$2}/head",
287
+ "ref" => nil,
288
+ "tag" => nil,
289
+ }
290
+ else
291
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
292
+ "https://github.com/#{repo_name}.git"
293
+ end
283
294
  end
284
295
 
285
296
  git_source(:gist) do |repo_name|
@@ -365,7 +376,11 @@ repo_name ||= user_name
365
376
 
366
377
  git_name = (git_names & opts.keys).last
367
378
  if @git_sources[git_name]
368
- opts["git"] = @git_sources[git_name].call(opts[git_name])
379
+ git_opts = @git_sources[git_name].call(opts[git_name])
380
+ git_opts = { "git" => git_opts } if git_opts.is_a?(String)
381
+ opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value|
382
+ raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`)
383
+ end
369
384
  end
370
385
 
371
386
  %w[git path].each do |type|