bundler 2.2.7 → 2.2.17

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -5
  3. data/lib/bundler.rb +1 -1
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli.rb +4 -2
  6. data/lib/bundler/cli/common.rb +15 -2
  7. data/lib/bundler/cli/gem.rb +43 -17
  8. data/lib/bundler/cli/outdated.rb +1 -1
  9. data/lib/bundler/compact_index_client/updater.rb +10 -6
  10. data/lib/bundler/current_ruby.rb +1 -0
  11. data/lib/bundler/definition.rb +63 -58
  12. data/lib/bundler/dsl.rb +36 -25
  13. data/lib/bundler/feature_flag.rb +0 -1
  14. data/lib/bundler/fetcher.rb +2 -1
  15. data/lib/bundler/fetcher/downloader.rb +8 -4
  16. data/lib/bundler/gem_helper.rb +16 -0
  17. data/lib/bundler/index.rb +6 -5
  18. data/lib/bundler/injector.rb +2 -2
  19. data/lib/bundler/inline.rb +2 -1
  20. data/lib/bundler/installer.rb +2 -0
  21. data/lib/bundler/installer/parallel_installer.rb +36 -15
  22. data/lib/bundler/installer/standalone.rb +2 -1
  23. data/lib/bundler/lazy_specification.rb +14 -18
  24. data/lib/bundler/lockfile_parser.rb +3 -13
  25. data/lib/bundler/man/bundle-add.1 +1 -1
  26. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  27. data/lib/bundler/man/bundle-cache.1 +1 -1
  28. data/lib/bundler/man/bundle-check.1 +1 -1
  29. data/lib/bundler/man/bundle-clean.1 +1 -1
  30. data/lib/bundler/man/bundle-config.1 +25 -8
  31. data/lib/bundler/man/bundle-config.1.ronn +29 -10
  32. data/lib/bundler/man/bundle-doctor.1 +1 -1
  33. data/lib/bundler/man/bundle-exec.1 +1 -1
  34. data/lib/bundler/man/bundle-gem.1 +1 -1
  35. data/lib/bundler/man/bundle-info.1 +1 -1
  36. data/lib/bundler/man/bundle-init.1 +1 -1
  37. data/lib/bundler/man/bundle-inject.1 +1 -1
  38. data/lib/bundler/man/bundle-install.1 +1 -1
  39. data/lib/bundler/man/bundle-list.1 +1 -1
  40. data/lib/bundler/man/bundle-lock.1 +1 -1
  41. data/lib/bundler/man/bundle-open.1 +1 -1
  42. data/lib/bundler/man/bundle-outdated.1 +1 -1
  43. data/lib/bundler/man/bundle-platform.1 +1 -1
  44. data/lib/bundler/man/bundle-pristine.1 +1 -1
  45. data/lib/bundler/man/bundle-remove.1 +1 -1
  46. data/lib/bundler/man/bundle-show.1 +1 -1
  47. data/lib/bundler/man/bundle-update.1 +1 -1
  48. data/lib/bundler/man/bundle-viz.1 +1 -1
  49. data/lib/bundler/man/bundle.1 +1 -1
  50. data/lib/bundler/man/gemfile.5 +1 -1
  51. data/lib/bundler/plugin.rb +3 -2
  52. data/lib/bundler/plugin/api/source.rb +7 -0
  53. data/lib/bundler/plugin/installer.rb +8 -10
  54. data/lib/bundler/plugin/source_list.rb +4 -0
  55. data/lib/bundler/resolver.rb +82 -65
  56. data/lib/bundler/resolver/spec_group.rb +53 -38
  57. data/lib/bundler/retry.rb +1 -1
  58. data/lib/bundler/rubygems_gem_installer.rb +47 -0
  59. data/lib/bundler/settings.rb +60 -10
  60. data/lib/bundler/shared_helpers.rb +2 -2
  61. data/lib/bundler/source.rb +6 -0
  62. data/lib/bundler/source/metadata.rb +0 -4
  63. data/lib/bundler/source/path.rb +3 -1
  64. data/lib/bundler/source/path/installer.rb +1 -1
  65. data/lib/bundler/source/rubygems.rb +22 -6
  66. data/lib/bundler/source_list.rb +29 -24
  67. data/lib/bundler/spec_set.rb +22 -8
  68. data/lib/bundler/stub_specification.rb +8 -0
  69. data/lib/bundler/templates/Gemfile +1 -1
  70. data/lib/bundler/templates/gems.rb +1 -1
  71. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  72. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  73. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -4
  74. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -1
  75. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  76. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  77. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  78. data/lib/bundler/vendor/thor/lib/thor.rb +5 -6
  79. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  80. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  81. data/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  82. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  83. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  84. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  85. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  86. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  87. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  88. data/lib/bundler/version.rb +1 -1
  89. metadata +4 -3
data/lib/bundler/retry.rb CHANGED
@@ -49,7 +49,7 @@ module Bundler
49
49
  raise e
50
50
  end
51
51
  return true unless name
52
- Bundler.ui.info "" unless Bundler.ui.debug? # Add new line incase dots preceded this
52
+ Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
53
53
  Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
54
54
  end
55
55
 
@@ -8,6 +8,53 @@ module Bundler
8
8
  # Bundler needs to install gems regardless of binstub overwriting
9
9
  end
10
10
 
11
+ def install
12
+ pre_install_checks
13
+
14
+ run_pre_install_hooks
15
+
16
+ spec.loaded_from = spec_file
17
+
18
+ # Completely remove any previous gem files
19
+ FileUtils.rm_rf gem_dir
20
+ FileUtils.rm_rf spec.extension_dir
21
+
22
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
23
+
24
+ extract_files
25
+
26
+ build_extensions
27
+ write_build_info_file
28
+ run_post_build_hooks
29
+
30
+ generate_bin
31
+ generate_plugins
32
+
33
+ write_spec
34
+ write_cache_file
35
+
36
+ say spec.post_install_message unless spec.post_install_message.nil?
37
+
38
+ run_post_install_hooks
39
+
40
+ spec
41
+ end
42
+
43
+ def generate_plugins
44
+ return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
45
+
46
+ latest = Gem::Specification.stubs_for(spec.name).first
47
+ return if latest && latest.version > spec.version
48
+
49
+ ensure_writable_dir @plugins_dir
50
+
51
+ if spec.plugins.empty?
52
+ remove_plugins_for(spec, @plugins_dir)
53
+ else
54
+ regenerate_plugins_for(spec, @plugins_dir)
55
+ end
56
+ end
57
+
11
58
  def pre_install_checks
12
59
  super && validate_bundler_checksum(options[:bundler_expected_checksum])
13
60
  end
@@ -13,6 +13,7 @@ module Bundler
13
13
  auto_install
14
14
  cache_all
15
15
  cache_all_platforms
16
+ clean
16
17
  default_install_uses_path
17
18
  deployment
18
19
  deployment_means_frozen
@@ -26,14 +27,16 @@ module Bundler
26
27
  force_ruby_platform
27
28
  forget_cli_options
28
29
  frozen
30
+ gem.changelog
29
31
  gem.coc
30
32
  gem.mit
33
+ git.allow_insecure
31
34
  global_gem_cache
32
35
  ignore_messages
33
36
  init_gems_rb
37
+ inline
34
38
  no_install
35
39
  no_prune
36
- only_update_to_newer_versions
37
40
  path_relative_to_cwd
38
41
  path.system
39
42
  plugins
@@ -61,6 +64,22 @@ module Bundler
61
64
  without
62
65
  ].freeze
63
66
 
67
+ STRING_KEYS = %w[
68
+ bin
69
+ cache_path
70
+ console
71
+ gem.ci
72
+ gem.github_username
73
+ gem.linter
74
+ gem.rubocop
75
+ gem.test
76
+ gemfile
77
+ path
78
+ shebang
79
+ system_bindir
80
+ trust-policy
81
+ ].freeze
82
+
64
83
  DEFAULT_CONFIG = {
65
84
  "BUNDLE_SILENCE_DEPRECATIONS" => false,
66
85
  "BUNDLE_DISABLE_VERSION_CHECK" => true,
@@ -126,8 +145,8 @@ module Bundler
126
145
  keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys
127
146
 
128
147
  keys.map do |key|
129
- key.sub(/^BUNDLE_/, "").gsub(/__/, ".").downcase
130
- end
148
+ key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase
149
+ end.sort
131
150
  end
132
151
 
133
152
  def local_overrides
@@ -173,19 +192,19 @@ module Bundler
173
192
  locations = []
174
193
 
175
194
  if value = @temporary[key]
176
- locations << "Set for the current command: #{converted_value(value, exposed_key).inspect}"
195
+ locations << "Set for the current command: #{printable_value(value, exposed_key).inspect}"
177
196
  end
178
197
 
179
198
  if value = @local_config[key]
180
- locations << "Set for your local app (#{local_config_file}): #{converted_value(value, exposed_key).inspect}"
199
+ locations << "Set for your local app (#{local_config_file}): #{printable_value(value, exposed_key).inspect}"
181
200
  end
182
201
 
183
202
  if value = @env_config[key]
184
- locations << "Set via #{key}: #{converted_value(value, exposed_key).inspect}"
203
+ locations << "Set via #{key}: #{printable_value(value, exposed_key).inspect}"
185
204
  end
186
205
 
187
206
  if value = @global_config[key]
188
- locations << "Set for the current user (#{global_config_file}): #{converted_value(value, exposed_key).inspect}"
207
+ locations << "Set for the current user (#{global_config_file}): #{printable_value(value, exposed_key).inspect}"
189
208
  end
190
209
 
191
210
  return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
@@ -277,9 +296,7 @@ module Bundler
277
296
  end
278
297
 
279
298
  def key_for(key)
280
- key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
281
- key = key.to_s.gsub(".", "__").upcase
282
- "BUNDLE_#{key}"
299
+ self.class.key_for(key)
283
300
  end
284
301
 
285
302
  private
@@ -314,6 +331,10 @@ module Bundler
314
331
  BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
315
332
  end
316
333
 
334
+ def is_string(name)
335
+ STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.")
336
+ end
337
+
317
338
  def to_bool(value)
318
339
  case value
319
340
  when nil, /\A(false|f|no|n|0|)\z/i, false
@@ -331,6 +352,14 @@ module Bundler
331
352
  ARRAY_KEYS.include?(key.to_s)
332
353
  end
333
354
 
355
+ def is_credential(key)
356
+ key == "gem.push_key"
357
+ end
358
+
359
+ def is_userinfo(value)
360
+ value.include?(":")
361
+ end
362
+
334
363
  def to_array(value)
335
364
  return [] unless value
336
365
  value.split(":").map(&:to_sym)
@@ -377,6 +406,21 @@ module Bundler
377
406
  end
378
407
  end
379
408
 
409
+ def printable_value(value, key)
410
+ converted = converted_value(value, key)
411
+ return converted unless converted.is_a?(String)
412
+
413
+ if is_string(key)
414
+ converted
415
+ elsif is_credential(key)
416
+ "[REDACTED]"
417
+ elsif is_userinfo(converted)
418
+ converted.gsub(/:.*$/, ":[REDACTED]")
419
+ else
420
+ converted
421
+ end
422
+ end
423
+
380
424
  def global_config_file
381
425
  if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
382
426
  Pathname.new(ENV["BUNDLE_CONFIG"])
@@ -416,6 +460,12 @@ module Bundler
416
460
  \z
417
461
  /ix.freeze
418
462
 
463
+ def self.key_for(key)
464
+ key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
465
+ key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
466
+ "BUNDLE_#{key}"
467
+ end
468
+
419
469
  # TODO: duplicates Rubygems#normalize_uri
420
470
  # TODO: is this the correct place to validate mirror URIs?
421
471
  def self.normalize_uri(uri)
@@ -194,11 +194,11 @@ module Bundler
194
194
  return @md5_available if defined?(@md5_available)
195
195
  @md5_available = begin
196
196
  require "openssl"
197
- OpenSSL::Digest.digest("MD5", "")
197
+ ::OpenSSL::Digest.digest("MD5", "")
198
198
  true
199
199
  rescue LoadError
200
200
  true
201
- rescue OpenSSL::Digest::DigestError
201
+ rescue ::OpenSSL::Digest::DigestError
202
202
  false
203
203
  end
204
204
  end
@@ -33,6 +33,12 @@ module Bundler
33
33
  spec.source == self
34
34
  end
35
35
 
36
+ def local!; end
37
+
38
+ def cached!; end
39
+
40
+ def remote!; end
41
+
36
42
  # it's possible that gems from one source depend on gems from some
37
43
  # other source, so now we download gemspecs and iterate over those
38
44
  # dependencies, looking for gems we don't have info on yet.
@@ -33,10 +33,6 @@ module Bundler
33
33
  end
34
34
  end
35
35
 
36
- def cached!; end
37
-
38
- def remote!; end
39
-
40
36
  def options
41
37
  {}
42
38
  end
@@ -82,7 +82,9 @@ module Bundler
82
82
  end
83
83
 
84
84
  def install(spec, options = {})
85
- print_using_message "Using #{version_message(spec)} from #{self}"
85
+ using_message = "Using #{version_message(spec)} from #{self}"
86
+ using_message += " and installing its executables" unless spec.executables.empty?
87
+ print_using_message using_message
86
88
  generate_bin(spec, :disable_extensions => true)
87
89
  nil # no post-install message
88
90
  end
@@ -35,7 +35,7 @@ module Bundler
35
35
  run_hooks(:post_build)
36
36
  end
37
37
 
38
- generate_bin unless spec.executables.nil? || spec.executables.empty?
38
+ generate_bin unless spec.executables.empty?
39
39
 
40
40
  run_hooks(:post_install)
41
41
  ensure
@@ -20,17 +20,29 @@ module Bundler
20
20
  @dependency_names = []
21
21
  @allow_remote = false
22
22
  @allow_cached = false
23
+ @allow_local = options["allow_local"] || false
23
24
  @caches = [cache_path, *Bundler.rubygems.gem_cache]
24
25
 
25
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
26
+ Array(options["remotes"]).reverse_each {|r| add_remote(r) }
27
+ end
28
+
29
+ def local!
30
+ return if @allow_local
31
+
32
+ @specs = nil
33
+ @allow_local = true
26
34
  end
27
35
 
28
36
  def remote!
37
+ return if @allow_remote
38
+
29
39
  @specs = nil
30
40
  @allow_remote = true
31
41
  end
32
42
 
33
43
  def cached!
44
+ return if @allow_cached
45
+
34
46
  @specs = nil
35
47
  @allow_cached = true
36
48
  end
@@ -49,8 +61,12 @@ module Bundler
49
61
  o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
50
62
  end
51
63
 
64
+ def disable_multisource?
65
+ @remotes.size <= 1
66
+ end
67
+
52
68
  def can_lock?(spec)
53
- return super if Bundler.feature_flag.disable_multisource?
69
+ return super if disable_multisource?
54
70
  spec.source.is_a?(Rubygems)
55
71
  end
56
72
 
@@ -87,7 +103,7 @@ module Bundler
87
103
  # small_idx.use large_idx.
88
104
  idx = @allow_remote ? remote_specs.dup : Index.new
89
105
  idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
90
- idx.use(installed_specs, :override_dupes)
106
+ idx.use(installed_specs, :override_dupes) if @allow_local
91
107
  idx
92
108
  end
93
109
  end
@@ -365,7 +381,7 @@ module Bundler
365
381
 
366
382
  def cached_specs
367
383
  @cached_specs ||= begin
368
- idx = installed_specs.dup
384
+ idx = @allow_local ? installed_specs.dup : Index.new
369
385
 
370
386
  Dir["#{cache_path}/*.gem"].each do |gemfile|
371
387
  next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
@@ -407,11 +423,11 @@ module Bundler
407
423
  def fetch_names(fetchers, dependency_names, index, override_dupes)
408
424
  fetchers.each do |f|
409
425
  if dependency_names
410
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
426
+ Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
411
427
  index.use f.specs_with_retry(dependency_names, self), override_dupes
412
428
  Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
413
429
  else
414
- Bundler.ui.info "Fetching source index from #{f.uri}"
430
+ Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
415
431
  index.use f.specs_with_retry(nil, self), override_dupes
416
432
  end
417
433
  end
@@ -1,30 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  module Bundler
6
4
  class SourceList
7
5
  attr_reader :path_sources,
8
6
  :git_sources,
9
7
  :plugin_sources,
10
- :global_rubygems_source,
8
+ :global_path_source,
11
9
  :metadata_source
12
10
 
11
+ def global_rubygems_source
12
+ @global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
13
+ end
14
+
13
15
  def initialize
14
16
  @path_sources = []
15
17
  @git_sources = []
16
18
  @plugin_sources = []
17
19
  @global_rubygems_source = nil
18
- @rubygems_aggregate = rubygems_aggregate_class.new
20
+ @global_path_source = nil
19
21
  @rubygems_sources = []
20
22
  @metadata_source = Source::Metadata.new
23
+
24
+ @disable_multisource = true
25
+ end
26
+
27
+ def disable_multisource?
28
+ @disable_multisource
29
+ end
30
+
31
+ def merged_gem_lockfile_sections!
32
+ @disable_multisource = false
21
33
  end
22
34
 
23
35
  def add_path_source(options = {})
24
36
  if options["gemspec"]
25
37
  add_source_to_list Source::Gemspec.new(options), path_sources
26
38
  else
27
- add_source_to_list Source::Path.new(options), path_sources
39
+ path_source = add_source_to_list Source::Path.new(options), path_sources
40
+ @global_path_source ||= path_source if options["global"]
41
+ path_source
28
42
  end
29
43
  end
30
44
 
@@ -43,24 +57,20 @@ module Bundler
43
57
  end
44
58
 
45
59
  def global_rubygems_source=(uri)
46
- if Bundler.feature_flag.disable_multisource?
47
- @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
48
- end
49
- add_rubygems_remote(uri)
60
+ @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
50
61
  end
51
62
 
52
63
  def add_rubygems_remote(uri)
53
- return if Bundler.feature_flag.disable_multisource?
54
- @rubygems_aggregate.add_remote(uri)
55
- @rubygems_aggregate
64
+ global_rubygems_source.add_remote(uri)
65
+ global_rubygems_source
56
66
  end
57
67
 
58
68
  def default_source
59
- global_rubygems_source || @rubygems_aggregate
69
+ global_path_source || global_rubygems_source
60
70
  end
61
71
 
62
72
  def rubygems_sources
63
- @rubygems_sources + [default_source]
73
+ @rubygems_sources + [global_rubygems_source]
64
74
  end
65
75
 
66
76
  def rubygems_remotes
@@ -77,8 +87,8 @@ module Bundler
77
87
 
78
88
  def lock_sources
79
89
  lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
80
- if Bundler.feature_flag.disable_multisource?
81
- lock_sources + rubygems_sources.sort_by(&:to_s)
90
+ if disable_multisource?
91
+ lock_sources + rubygems_sources.sort_by(&:to_s).uniq
82
92
  else
83
93
  lock_sources << combine_rubygems_sources
84
94
  end
@@ -94,12 +104,11 @@ module Bundler
94
104
  end
95
105
  end
96
106
 
97
- replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
107
+ replacement_rubygems = !disable_multisource? &&
98
108
  replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
99
- @rubygems_aggregate = replacement_rubygems if replacement_rubygems
109
+ @global_rubygems_source = replacement_rubygems if replacement_rubygems
100
110
 
101
111
  return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
102
- return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
103
112
 
104
113
  false
105
114
  end
@@ -112,10 +121,6 @@ module Bundler
112
121
  all_sources.each(&:remote!)
113
122
  end
114
123
 
115
- def rubygems_primary_remotes
116
- @rubygems_aggregate.remotes
117
- end
118
-
119
124
  private
120
125
 
121
126
  def rubygems_aggregate_class
@@ -153,7 +158,7 @@ module Bundler
153
158
  end
154
159
 
155
160
  def equal_sources?(lock_sources, replacement_sources)
156
- lock_sources.to_set == replacement_sources.to_set
161
+ lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
157
162
  end
158
163
 
159
164
  def equal_source?(source, other_source)