bundler 2.2.17 → 2.2.18

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/bundler.gemspec +2 -3
  4. data/lib/bundler.rb +1 -0
  5. data/lib/bundler/build_metadata.rb +2 -2
  6. data/lib/bundler/cli.rb +13 -33
  7. data/lib/bundler/cli/outdated.rb +7 -10
  8. data/lib/bundler/definition.rb +14 -75
  9. data/lib/bundler/feature_flag.rb +0 -1
  10. data/lib/bundler/friendly_errors.rb +1 -1
  11. data/lib/bundler/index.rb +1 -2
  12. data/lib/bundler/man/bundle-add.1 +1 -1
  13. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  14. data/lib/bundler/man/bundle-cache.1 +1 -1
  15. data/lib/bundler/man/bundle-check.1 +1 -1
  16. data/lib/bundler/man/bundle-clean.1 +1 -1
  17. data/lib/bundler/man/bundle-config.1 +1 -7
  18. data/lib/bundler/man/bundle-config.1.ronn +0 -8
  19. data/lib/bundler/man/bundle-doctor.1 +1 -1
  20. data/lib/bundler/man/bundle-exec.1 +1 -1
  21. data/lib/bundler/man/bundle-gem.1 +1 -1
  22. data/lib/bundler/man/bundle-info.1 +1 -1
  23. data/lib/bundler/man/bundle-init.1 +1 -1
  24. data/lib/bundler/man/bundle-inject.1 +1 -1
  25. data/lib/bundler/man/bundle-install.1 +1 -1
  26. data/lib/bundler/man/bundle-list.1 +1 -1
  27. data/lib/bundler/man/bundle-lock.1 +1 -1
  28. data/lib/bundler/man/bundle-open.1 +1 -1
  29. data/lib/bundler/man/bundle-outdated.1 +1 -1
  30. data/lib/bundler/man/bundle-platform.1 +1 -1
  31. data/lib/bundler/man/bundle-pristine.1 +1 -1
  32. data/lib/bundler/man/bundle-remove.1 +1 -1
  33. data/lib/bundler/man/bundle-show.1 +1 -1
  34. data/lib/bundler/man/bundle-update.1 +1 -1
  35. data/lib/bundler/man/bundle-viz.1 +1 -1
  36. data/lib/bundler/man/bundle.1 +1 -1
  37. data/lib/bundler/man/gemfile.5 +1 -1
  38. data/lib/bundler/plugin/api/source.rb +14 -0
  39. data/lib/bundler/resolver.rb +13 -96
  40. data/lib/bundler/resolver/spec_group.rb +0 -24
  41. data/lib/bundler/rubygems_ext.rb +2 -2
  42. data/lib/bundler/settings.rb +0 -1
  43. data/lib/bundler/source.rb +9 -0
  44. data/lib/bundler/source/rubygems.rb +15 -4
  45. data/lib/bundler/source/rubygems_aggregate.rb +64 -0
  46. data/lib/bundler/source_list.rb +29 -10
  47. data/lib/bundler/source_map.rb +58 -0
  48. data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
  49. data/lib/bundler/version.rb +1 -1
  50. metadata +9 -4
@@ -21,7 +21,6 @@ module Bundler
21
21
  disable_exec_load
22
22
  disable_local_branch_check
23
23
  disable_local_revision_check
24
- disable_multisource
25
24
  disable_shared_gems
26
25
  disable_version_check
27
26
  force_ruby_platform
@@ -7,6 +7,7 @@ module Bundler
7
7
  autoload :Metadata, File.expand_path("source/metadata", __dir__)
8
8
  autoload :Path, File.expand_path("source/path", __dir__)
9
9
  autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
10
+ autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
10
11
 
11
12
  attr_accessor :dependency_names
12
13
 
@@ -39,6 +40,10 @@ module Bundler
39
40
 
40
41
  def remote!; end
41
42
 
43
+ def add_dependency_names(names)
44
+ @dependency_names = Array(dependency_names) | Array(names)
45
+ end
46
+
42
47
  # it's possible that gems from one source depend on gems from some
43
48
  # other source, so now we download gemspecs and iterate over those
44
49
  # dependencies, looking for gems we don't have info on yet.
@@ -48,6 +53,10 @@ module Bundler
48
53
  specs.dependency_names
49
54
  end
50
55
 
56
+ def spec_names
57
+ specs.spec_names
58
+ end
59
+
51
60
  def include?(other)
52
61
  other == self
53
62
  end
@@ -259,8 +259,16 @@ module Bundler
259
259
  !equivalent
260
260
  end
261
261
 
262
+ def spec_names
263
+ if @allow_remote && dependency_api_available?
264
+ remote_specs.spec_names
265
+ else
266
+ []
267
+ end
268
+ end
269
+
262
270
  def unmet_deps
263
- if @allow_remote && api_fetchers.any?
271
+ if @allow_remote && dependency_api_available?
264
272
  remote_specs.unmet_dependency_names
265
273
  else
266
274
  []
@@ -276,7 +284,7 @@ module Bundler
276
284
 
277
285
  def double_check_for(unmet_dependency_names)
278
286
  return unless @allow_remote
279
- return unless api_fetchers.any?
287
+ return unless dependency_api_available?
280
288
 
281
289
  unmet_dependency_names = unmet_dependency_names.call
282
290
  unless unmet_dependency_names.nil?
@@ -298,17 +306,20 @@ module Bundler
298
306
  remote_specs.each do |spec|
299
307
  case spec
300
308
  when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
301
- names.concat(spec.runtime_dependencies)
309
+ names.concat(spec.runtime_dependencies.map(&:name))
302
310
  when RemoteSpecification # from the full index
303
311
  return nil
304
312
  else
305
313
  raise "unhandled spec type (#{spec.inspect})"
306
314
  end
307
315
  end
308
- names.map!(&:name) if names
309
316
  names
310
317
  end
311
318
 
319
+ def dependency_api_available?
320
+ api_fetchers.any?
321
+ end
322
+
312
323
  protected
313
324
 
314
325
  def credless_remotes
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Source
5
+ class RubygemsAggregate
6
+ attr_reader :source_map, :sources
7
+
8
+ def initialize(sources, source_map)
9
+ @sources = sources
10
+ @source_map = source_map
11
+
12
+ @index = build_index
13
+ end
14
+
15
+ def specs
16
+ @index
17
+ end
18
+
19
+ def to_s
20
+ "any of the sources"
21
+ end
22
+
23
+ private
24
+
25
+ def build_index
26
+ Index.build do |idx|
27
+ dependency_names = source_map.pinned_spec_names
28
+
29
+ sources.all_sources.each do |source|
30
+ source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
31
+ idx.add_source source.specs
32
+ dependency_names.concat(source.unmet_deps).uniq!
33
+ end
34
+
35
+ double_check_for_index(idx, dependency_names)
36
+ end
37
+ end
38
+
39
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
40
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
41
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
42
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
43
+ # each spec we found, we add all possible versions from all sources to the index.
44
+ def double_check_for_index(idx, dependency_names)
45
+ pinned_names = source_map.pinned_spec_names
46
+
47
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
48
+ unmet_dependency_names = lambda do
49
+ return names unless names == :names
50
+ new_names = sources.all_sources.map(&:dependency_names_to_double_check)
51
+ return names = nil if new_names.compact!
52
+ names = new_names.flatten(1).concat(dependency_names)
53
+ names.uniq!
54
+ names -= pinned_names
55
+ names
56
+ end
57
+
58
+ sources.all_sources.each do |source|
59
+ source.double_check_for(unmet_dependency_names)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -21,15 +21,19 @@ module Bundler
21
21
  @rubygems_sources = []
22
22
  @metadata_source = Source::Metadata.new
23
23
 
24
- @disable_multisource = true
24
+ @merged_gem_lockfile_sections = false
25
25
  end
26
26
 
27
- def disable_multisource?
28
- @disable_multisource
27
+ def merged_gem_lockfile_sections?
28
+ @merged_gem_lockfile_sections
29
29
  end
30
30
 
31
31
  def merged_gem_lockfile_sections!
32
- @disable_multisource = false
32
+ @merged_gem_lockfile_sections = true
33
+ end
34
+
35
+ def no_aggregate_global_source?
36
+ global_rubygems_source.remotes.size <= 1
33
37
  end
34
38
 
35
39
  def add_path_source(options = {})
@@ -70,7 +74,11 @@ module Bundler
70
74
  end
71
75
 
72
76
  def rubygems_sources
73
- @rubygems_sources + [global_rubygems_source]
77
+ non_global_rubygems_sources + [global_rubygems_source]
78
+ end
79
+
80
+ def non_global_rubygems_sources
81
+ @rubygems_sources
74
82
  end
75
83
 
76
84
  def rubygems_remotes
@@ -81,16 +89,27 @@ module Bundler
81
89
  path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
82
90
  end
83
91
 
92
+ def non_default_explicit_sources
93
+ all_sources - [default_source, metadata_source]
94
+ end
95
+
84
96
  def get(source)
85
97
  source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
86
98
  end
87
99
 
88
100
  def lock_sources
89
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
90
- if disable_multisource?
91
- lock_sources + rubygems_sources.sort_by(&:to_s).uniq
101
+ lock_other_sources + lock_rubygems_sources
102
+ end
103
+
104
+ def lock_other_sources
105
+ (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
106
+ end
107
+
108
+ def lock_rubygems_sources
109
+ if merged_gem_lockfile_sections?
110
+ [combine_rubygems_sources]
92
111
  else
93
- lock_sources << combine_rubygems_sources
112
+ rubygems_sources.sort_by(&:to_s).uniq
94
113
  end
95
114
  end
96
115
 
@@ -104,7 +123,7 @@ module Bundler
104
123
  end
105
124
  end
106
125
 
107
- replacement_rubygems = !disable_multisource? &&
126
+ replacement_rubygems = merged_gem_lockfile_sections? &&
108
127
  replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
109
128
  @global_rubygems_source = replacement_rubygems if replacement_rubygems
110
129
 
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class SourceMap
5
+ attr_reader :sources, :dependencies
6
+
7
+ def initialize(sources, dependencies)
8
+ @sources = sources
9
+ @dependencies = dependencies
10
+ end
11
+
12
+ def pinned_spec_names(skip = nil)
13
+ direct_requirements.reject {|_, source| source == skip }.keys
14
+ end
15
+
16
+ def all_requirements
17
+ requirements = direct_requirements.dup
18
+
19
+ unmet_deps = sources.non_default_explicit_sources.map do |source|
20
+ (source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
21
+ previous_source = requirements[indirect_dependency_name]
22
+ if previous_source.nil?
23
+ requirements[indirect_dependency_name] = source
24
+ else
25
+ no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode?
26
+
27
+ msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
28
+ msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
29
+ msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
30
+ msg = msg.join("\n")
31
+
32
+ raise SecurityError, msg if no_ambiguous_sources
33
+ Bundler.ui.warn "Warning: #{msg}"
34
+ end
35
+ end
36
+
37
+ source.unmet_deps
38
+ end
39
+
40
+ sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys)
41
+
42
+ requirements
43
+ end
44
+
45
+ def direct_requirements
46
+ @direct_requirements ||= begin
47
+ requirements = {}
48
+ default = sources.default_source
49
+ dependencies.each do |dep|
50
+ dep_source = dep.source || default
51
+ dep_source.add_dependency_names(dep.name)
52
+ requirements[dep.name] = dep_source
53
+ end
54
+ requirements
55
+ end
56
+ end
57
+ end
58
+ end
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  <%- if config[:mit] -%>
15
15
  spec.license = "MIT"
16
16
  <%- end -%>
17
- spec.required_ruby_version = Gem::Requirement.new(">= <%= config[:required_ruby_version] %>")
17
+ spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
18
18
 
19
19
  spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
20
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.17".freeze
4
+ VERSION = "2.2.18".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.17
4
+ version: 2.2.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -22,7 +22,7 @@ authors:
22
22
  autorequire:
23
23
  bindir: exe
24
24
  cert_chain: []
25
- date: 2021-05-05 00:00:00.000000000 Z
25
+ date: 2021-05-25 00:00:00.000000000 Z
26
26
  dependencies: []
27
27
  description: Bundler manages an application's dependencies through its entire life,
28
28
  across many machines, systematically and repeatably
@@ -32,7 +32,10 @@ executables:
32
32
  - bundle
33
33
  - bundler
34
34
  extensions: []
35
- extra_rdoc_files: []
35
+ extra_rdoc_files:
36
+ - CHANGELOG.md
37
+ - LICENSE.md
38
+ - README.md
36
39
  files:
37
40
  - CHANGELOG.md
38
41
  - LICENSE.md
@@ -202,7 +205,9 @@ files:
202
205
  - lib/bundler/source/path/installer.rb
203
206
  - lib/bundler/source/rubygems.rb
204
207
  - lib/bundler/source/rubygems/remote.rb
208
+ - lib/bundler/source/rubygems_aggregate.rb
205
209
  - lib/bundler/source_list.rb
210
+ - lib/bundler/source_map.rb
206
211
  - lib/bundler/spec_set.rb
207
212
  - lib/bundler/stub_specification.rb
208
213
  - lib/bundler/templates/.document
@@ -352,7 +357,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
357
  - !ruby/object:Gem::Version
353
358
  version: 2.5.2
354
359
  requirements: []
355
- rubygems_version: 3.2.17
360
+ rubygems_version: 3.2.18
356
361
  signing_key:
357
362
  specification_version: 4
358
363
  summary: The best way to manage your application's dependencies