bundler 2.2.11 → 2.2.16

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -0
  3. data/lib/bundler/build_metadata.rb +2 -2
  4. data/lib/bundler/cli.rb +1 -0
  5. data/lib/bundler/cli/common.rb +13 -2
  6. data/lib/bundler/cli/gem.rb +31 -17
  7. data/lib/bundler/cli/outdated.rb +1 -1
  8. data/lib/bundler/compact_index_client/updater.rb +1 -1
  9. data/lib/bundler/definition.rb +48 -31
  10. data/lib/bundler/dsl.rb +36 -25
  11. data/lib/bundler/feature_flag.rb +0 -1
  12. data/lib/bundler/gem_helper.rb +16 -0
  13. data/lib/bundler/inline.rb +1 -0
  14. data/lib/bundler/installer.rb +2 -0
  15. data/lib/bundler/installer/parallel_installer.rb +36 -15
  16. data/lib/bundler/lazy_specification.rb +6 -1
  17. data/lib/bundler/lockfile_parser.rb +3 -13
  18. data/lib/bundler/man/bundle-add.1 +1 -1
  19. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  20. data/lib/bundler/man/bundle-cache.1 +1 -1
  21. data/lib/bundler/man/bundle-check.1 +1 -1
  22. data/lib/bundler/man/bundle-clean.1 +1 -1
  23. data/lib/bundler/man/bundle-config.1 +4 -4
  24. data/lib/bundler/man/bundle-config.1.ronn +4 -3
  25. data/lib/bundler/man/bundle-doctor.1 +1 -1
  26. data/lib/bundler/man/bundle-exec.1 +1 -1
  27. data/lib/bundler/man/bundle-gem.1 +1 -1
  28. data/lib/bundler/man/bundle-info.1 +1 -1
  29. data/lib/bundler/man/bundle-init.1 +1 -1
  30. data/lib/bundler/man/bundle-inject.1 +1 -1
  31. data/lib/bundler/man/bundle-install.1 +1 -1
  32. data/lib/bundler/man/bundle-list.1 +1 -1
  33. data/lib/bundler/man/bundle-lock.1 +1 -1
  34. data/lib/bundler/man/bundle-open.1 +1 -1
  35. data/lib/bundler/man/bundle-outdated.1 +1 -1
  36. data/lib/bundler/man/bundle-platform.1 +1 -1
  37. data/lib/bundler/man/bundle-pristine.1 +1 -1
  38. data/lib/bundler/man/bundle-remove.1 +1 -1
  39. data/lib/bundler/man/bundle-show.1 +1 -1
  40. data/lib/bundler/man/bundle-update.1 +1 -1
  41. data/lib/bundler/man/bundle-viz.1 +1 -1
  42. data/lib/bundler/man/bundle.1 +1 -1
  43. data/lib/bundler/man/gemfile.5 +1 -1
  44. data/lib/bundler/plugin.rb +1 -0
  45. data/lib/bundler/plugin/api/source.rb +7 -0
  46. data/lib/bundler/plugin/installer.rb +8 -10
  47. data/lib/bundler/plugin/source_list.rb +4 -0
  48. data/lib/bundler/resolver.rb +34 -36
  49. data/lib/bundler/rubygems_gem_installer.rb +47 -0
  50. data/lib/bundler/settings.rb +0 -1
  51. data/lib/bundler/source.rb +6 -0
  52. data/lib/bundler/source/metadata.rb +0 -4
  53. data/lib/bundler/source/path.rb +3 -1
  54. data/lib/bundler/source/path/installer.rb +1 -1
  55. data/lib/bundler/source/rubygems.rb +20 -4
  56. data/lib/bundler/source_list.rb +28 -21
  57. data/lib/bundler/spec_set.rb +2 -0
  58. data/lib/bundler/stub_specification.rb +8 -0
  59. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  60. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -4
  61. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  62. data/lib/bundler/version.rb +1 -1
  63. metadata +3 -3
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-REMOVE" "1" "January 2021" "" ""
4
+ .TH "BUNDLE\-REMOVE" "1" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-remove\fR \- Removes gems from the Gemfile
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-SHOW" "1" "January 2021" "" ""
4
+ .TH "BUNDLE\-SHOW" "1" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-UPDATE" "1" "January 2021" "" ""
4
+ .TH "BUNDLE\-UPDATE" "1" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-update\fR \- Update your gems to the latest available versions
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-VIZ" "1" "January 2021" "" ""
4
+ .TH "BUNDLE\-VIZ" "1" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE" "1" "January 2021" "" ""
4
+ .TH "BUNDLE" "1" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\fR \- Ruby Dependency Management
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "GEMFILE" "5" "January 2021" "" ""
4
+ .TH "GEMFILE" "5" "April 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
@@ -105,6 +105,7 @@ module Bundler
105
105
  else
106
106
  builder.eval_gemfile(gemfile)
107
107
  end
108
+ builder.check_primary_source_safety
108
109
  definition = builder.to_definition(nil, true)
109
110
 
110
111
  return if definition.dependencies.empty?
@@ -140,6 +140,13 @@ module Bundler
140
140
  end
141
141
  end
142
142
 
143
+ # Set internal representation to fetch the gems/specs locally.
144
+ #
145
+ # When this is called, the source should try to fetch the specs and
146
+ # install from the local system.
147
+ def local!
148
+ end
149
+
143
150
  # Set internal representation to fetch the gems/specs from remote.
144
151
  #
145
152
  # When this is called, the source should try to fetch the specs and
@@ -16,15 +16,13 @@ module Bundler
16
16
 
17
17
  version = options[:version] || [">= 0"]
18
18
 
19
- Bundler.settings.temporary(:disable_multisource => false) do
20
- if options[:git]
21
- install_git(names, version, options)
22
- elsif options[:local_git]
23
- install_local_git(names, version, options)
24
- else
25
- sources = options[:source] || Bundler.rubygems.sources
26
- install_rubygems(names, version, sources)
27
- end
19
+ if options[:git]
20
+ install_git(names, version, options)
21
+ elsif options[:local_git]
22
+ install_local_git(names, version, options)
23
+ else
24
+ sources = options[:source] || Bundler.rubygems.sources
25
+ install_rubygems(names, version, sources)
28
26
  end
29
27
  end
30
28
 
@@ -79,7 +77,7 @@ module Bundler
79
77
  source_list = SourceList.new
80
78
 
81
79
  source_list.add_git_source(git_source_options) if git_source_options
82
- source_list.add_rubygems_source("remotes" => rubygems_source) if rubygems_source
80
+ source_list.global_rubygems_source = rubygems_source if rubygems_source
83
81
 
84
82
  deps = names.map {|name| Dependency.new name, version }
85
83
 
@@ -17,6 +17,10 @@ module Bundler
17
17
  path_sources + git_sources + rubygems_sources + [metadata_source]
18
18
  end
19
19
 
20
+ def default_source
21
+ git_sources.first || global_rubygems_source
22
+ end
23
+
20
24
  private
21
25
 
22
26
  def rubygems_aggregate_class
@@ -17,16 +17,21 @@ module Bundler
17
17
  # ==== Returns
18
18
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
19
19
  # collection of gemspecs is returned. Otherwise, nil is returned.
20
- def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
20
+ def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
21
21
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
22
- resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
+ resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
23
23
  result = resolver.start(requirements)
24
24
  SpecSet.new(result)
25
25
  end
26
26
 
27
- def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
28
- @index = index
27
+ def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
29
28
  @source_requirements = source_requirements
29
+
30
+ @index_requirements = source_requirements.each_with_object({}) do |source_requirement, index_requirements|
31
+ name, source = source_requirement
32
+ index_requirements[name] = name == :global ? source : source.specs
33
+ end
34
+
30
35
  @base = base
31
36
  @resolver = Molinillo::Resolver.new(self, self)
32
37
  @search_for = {}
@@ -40,7 +45,7 @@ module Bundler
40
45
  @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
41
46
  @gem_version_promoter = gem_version_promoter
42
47
  @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
43
- @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
48
+ @no_aggregate_global_source = @source_requirements[:global].nil?
44
49
 
45
50
  @variant_specific_names = []
46
51
  @generic_names = ["Ruby\0", "RubyGems\0"]
@@ -125,8 +130,7 @@ module Bundler
125
130
  dependency = dependency_proxy.dep
126
131
  name = dependency.name
127
132
  search_result = @search_for[dependency_proxy] ||= begin
128
- index = index_for(dependency)
129
- results = index.search(dependency, @base[name])
133
+ results = results_for(dependency, @base[name])
130
134
 
131
135
  if vertex = @base_dg.vertex_named(name)
132
136
  locked_requirement = vertex.payload.requirement
@@ -196,22 +200,22 @@ module Bundler
196
200
  end
197
201
 
198
202
  def index_for(dependency)
199
- source = @source_requirements[dependency.name]
203
+ source = @index_requirements[dependency.name]
200
204
  if source
201
- source.specs
202
- elsif @lockfile_uses_separate_rubygems_sources
205
+ source
206
+ elsif @no_aggregate_global_source
203
207
  Index.build do |idx|
204
- if dependency.all_sources
205
- dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
206
- else
207
- idx.add_source @source_requirements[:default].specs
208
- end
208
+ dependency.all_sources.each {|s| idx.add_source(s.specs) }
209
209
  end
210
210
  else
211
- @index
211
+ @index_requirements[:global]
212
212
  end
213
213
  end
214
214
 
215
+ def results_for(dependency, base)
216
+ index_for(dependency).search(dependency, base)
217
+ end
218
+
215
219
  def name_for(dependency)
216
220
  dependency.name
217
221
  end
@@ -239,18 +243,20 @@ module Bundler
239
243
  def relevant_sources_for_vertex(vertex)
240
244
  if vertex.root?
241
245
  [@source_requirements[vertex.name]]
242
- elsif @lockfile_uses_separate_rubygems_sources
246
+ elsif @no_aggregate_global_source
243
247
  vertex.recursive_predecessors.map do |v|
244
248
  @source_requirements[v.name]
245
- end << @source_requirements[:default]
249
+ end.compact << @source_requirements[:default]
250
+ else
251
+ []
246
252
  end
247
253
  end
248
254
 
249
255
  def sort_dependencies(dependencies, activated, conflicts)
250
256
  dependencies.sort_by do |dependency|
251
- dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
252
257
  name = name_for(dependency)
253
258
  vertex = activated.vertex_named(name)
259
+ dependency.all_sources = relevant_sources_for_vertex(vertex)
254
260
  [
255
261
  @base_dg.vertex_named(name) ? 0 : 1,
256
262
  vertex.payload ? 0 : 1,
@@ -317,7 +323,7 @@ module Bundler
317
323
  "If you are updating multiple gems in your Gemfile at once,\n" \
318
324
  "try passing them all to `bundle update`"
319
325
  elsif source = @source_requirements[name]
320
- specs = source.specs[name]
326
+ specs = source.specs.search(name)
321
327
  versions_with_platforms = specs.map {|s| [s.version, s.platform] }
322
328
  message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
323
329
  message << if versions_with_platforms.any?
@@ -326,7 +332,7 @@ module Bundler
326
332
  "The source does not contain any versions of '#{name}'"
327
333
  end
328
334
  else
329
- message = "Could not find gem '#{requirement}' in any of the gem sources " \
335
+ message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
330
336
  "listed in your Gemfile#{cache_message}."
331
337
  end
332
338
  raise GemNotFound, message
@@ -392,7 +398,7 @@ module Bundler
392
398
  if other_bundler_required
393
399
  o << "\n\n"
394
400
 
395
- candidate_specs = @source_requirements[:default_bundler].specs.search(conflict_dependency)
401
+ candidate_specs = @index_requirements[:default_bundler].search(conflict_dependency)
396
402
  if candidate_specs.any?
397
403
  target_version = candidate_specs.last.version
398
404
  new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
@@ -411,14 +417,8 @@ module Bundler
411
417
 
412
418
  relevant_sources = if conflict.requirement.source
413
419
  [conflict.requirement.source]
414
- elsif conflict.requirement.all_sources
415
- conflict.requirement.all_sources
416
- elsif @lockfile_uses_separate_rubygems_sources
417
- # every conflict should have an explicit group of sources when we
418
- # enforce strict pinning
419
- raise "no source set for #{conflict}"
420
420
  else
421
- []
421
+ conflict.requirement.all_sources
422
422
  end.compact.map(&:to_s).uniq.sort
423
423
 
424
424
  metadata_requirement = name.end_with?("\0")
@@ -455,23 +455,21 @@ module Bundler
455
455
  def validate_resolved_specs!(resolved_specs)
456
456
  resolved_specs.each do |v|
457
457
  name = v.name
458
- next unless sources = relevant_sources_for_vertex(v)
459
- sources.compact!
458
+ sources = relevant_sources_for_vertex(v)
459
+ next unless sources.any?
460
460
  if default_index = sources.index(@source_requirements[:default])
461
461
  sources.delete_at(default_index)
462
462
  end
463
- sources.reject! {|s| s.specs[name].empty? }
463
+ sources.reject! {|s| s.specs.search(name).empty? }
464
464
  sources.uniq!
465
465
  next if sources.size <= 1
466
466
 
467
- multisource_disabled = Bundler.feature_flag.disable_multisource?
468
-
469
467
  msg = ["The gem '#{name}' was found in multiple relevant sources."]
470
468
  msg.concat sources.map {|s| " * #{s}" }.sort
471
- msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
469
+ msg << "You #{@no_aggregate_global_source ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
472
470
  msg = msg.join("\n")
473
471
 
474
- raise SecurityError, msg if multisource_disabled
472
+ raise SecurityError, msg if @no_aggregate_global_source
475
473
  Bundler.ui.warn "Warning: #{msg}"
476
474
  end
477
475
  end
@@ -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
@@ -33,7 +33,6 @@ module Bundler
33
33
  init_gems_rb
34
34
  no_install
35
35
  no_prune
36
- only_update_to_newer_versions
37
36
  path_relative_to_cwd
38
37
  path.system
39
38
  plugins
@@ -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/