bundler 2.2.23 → 2.2.27

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/lib/bundler/build_metadata.rb +2 -2
  4. data/lib/bundler/cli/cache.rb +1 -1
  5. data/lib/bundler/cli/doctor.rb +1 -1
  6. data/lib/bundler/cli/exec.rb +1 -6
  7. data/lib/bundler/cli/gem.rb +3 -2
  8. data/lib/bundler/cli/install.rb +4 -17
  9. data/lib/bundler/cli/list.rb +7 -1
  10. data/lib/bundler/cli/open.rb +1 -2
  11. data/lib/bundler/cli/update.rb +1 -1
  12. data/lib/bundler/cli.rb +12 -9
  13. data/lib/bundler/definition.rb +38 -47
  14. data/lib/bundler/dsl.rb +40 -26
  15. data/lib/bundler/errors.rb +1 -1
  16. data/lib/bundler/installer/gem_installer.rb +3 -16
  17. data/lib/bundler/installer/standalone.rb +14 -9
  18. data/lib/bundler/installer.rb +0 -1
  19. data/lib/bundler/lockfile_parser.rb +1 -0
  20. data/lib/bundler/plugin/index.rb +4 -1
  21. data/lib/bundler/plugin/installer.rb +2 -0
  22. data/lib/bundler/plugin.rb +25 -6
  23. data/lib/bundler/resolver.rb +10 -17
  24. data/lib/bundler/rubygems_gem_installer.rb +5 -1
  25. data/lib/bundler/rubygems_integration.rb +2 -0
  26. data/lib/bundler/runtime.rb +16 -9
  27. data/lib/bundler/settings.rb +13 -1
  28. data/lib/bundler/setup.rb +2 -2
  29. data/lib/bundler/shared_helpers.rb +0 -7
  30. data/lib/bundler/source/git/git_proxy.rb +1 -2
  31. data/lib/bundler/source/rubygems.rb +23 -2
  32. data/lib/bundler/source/rubygems_aggregate.rb +4 -0
  33. data/lib/bundler/source.rb +4 -0
  34. data/lib/bundler/source_list.rb +16 -3
  35. data/lib/bundler/spec_set.rb +14 -37
  36. data/lib/bundler/templates/Executable.bundler +6 -6
  37. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +13 -2
  38. data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -1
  39. data/lib/bundler/version.rb +1 -1
  40. data/lib/bundler/worker.rb +17 -2
  41. data/lib/bundler.rb +11 -21
  42. metadata +3 -3
@@ -419,7 +419,15 @@ module Bundler
419
419
  elsif is_credential(key)
420
420
  "[REDACTED]"
421
421
  elsif is_userinfo(converted)
422
- converted.gsub(/:.*$/, ":[REDACTED]")
422
+ username, pass = converted.split(":", 2)
423
+
424
+ if pass == "x-oauth-basic"
425
+ username = "[REDACTED]"
426
+ else
427
+ pass = "[REDACTED]"
428
+ end
429
+
430
+ [username, pass].join(":")
423
431
  else
424
432
  converted
425
433
  end
@@ -428,6 +436,10 @@ module Bundler
428
436
  def global_config_file
429
437
  if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
430
438
  Pathname.new(ENV["BUNDLE_CONFIG"])
439
+ elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty?
440
+ Pathname.new(ENV["BUNDLE_USER_CONFIG"])
441
+ elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty?
442
+ Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config")
431
443
  elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
432
444
  Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
433
445
  end
data/lib/bundler/setup.rb CHANGED
@@ -9,10 +9,10 @@ if Bundler::SharedHelpers.in_bundle?
9
9
  begin
10
10
  Bundler.ui.silence { Bundler.setup }
11
11
  rescue Bundler::BundlerError => e
12
- Bundler.ui.warn "\e[31m#{e.message}\e[0m"
12
+ Bundler.ui.error e.message
13
13
  Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
14
14
  if e.is_a?(Bundler::GemNotFound)
15
- Bundler.ui.warn "\e[33mRun `bundle install` to install missing gems.\e[0m"
15
+ Bundler.ui.warn "Run `bundle install` to install missing gems."
16
16
  end
17
17
  exit e.status_code
18
18
  end
@@ -152,13 +152,6 @@ module Bundler
152
152
  Bundler.ui.warn message
153
153
  end
154
154
 
155
- def trap(signal, override = false, &block)
156
- prior = Signal.trap(signal) do
157
- block.call
158
- prior.call unless override
159
- end
160
- end
161
-
162
155
  def ensure_same_dependencies(spec, old_deps, new_deps)
163
156
  new_deps = new_deps.reject {|d| d.type == :development }
164
157
  old_deps = old_deps.reject {|d| d.type == :development }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class Source
7
5
  class Git
@@ -224,6 +222,7 @@ module Bundler
224
222
  end
225
223
 
226
224
  def check_allowed(command)
225
+ require "shellwords"
227
226
  command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
228
227
  raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
229
228
  command_with_no_credentials
@@ -29,6 +29,7 @@ module Bundler
29
29
  def local_only!
30
30
  @specs = nil
31
31
  @allow_local = true
32
+ @allow_cached = false
32
33
  @allow_remote = false
33
34
  end
34
35
 
@@ -50,6 +51,7 @@ module Bundler
50
51
  return if @allow_cached
51
52
 
52
53
  @specs = nil
54
+ @allow_local = true
53
55
  @allow_cached = true
54
56
  end
55
57
 
@@ -71,6 +73,10 @@ module Bundler
71
73
  @remotes.size > 1
72
74
  end
73
75
 
76
+ def no_remotes?
77
+ @remotes.size == 0
78
+ end
79
+
74
80
  def can_lock?(spec)
75
81
  return super unless multiple_remotes?
76
82
  include?(spec.source)
@@ -92,11 +98,22 @@ module Bundler
92
98
  out << " specs:\n"
93
99
  end
94
100
 
101
+ def to_err
102
+ if remotes.empty?
103
+ "locally installed gems"
104
+ elsif @allow_remote
105
+ "rubygems repository #{remote_names} or installed locally"
106
+ elsif @allow_cached
107
+ "cached gems from rubygems repository #{remote_names} or installed locally"
108
+ else
109
+ "locally installed gems"
110
+ end
111
+ end
112
+
95
113
  def to_s
96
114
  if remotes.empty?
97
115
  "locally installed gems"
98
116
  else
99
- remote_names = remotes.map(&:to_s).join(", ")
100
117
  "rubygems repository #{remote_names} or installed locally"
101
118
  end
102
119
  end
@@ -127,7 +144,7 @@ module Bundler
127
144
  end
128
145
  end
129
146
 
130
- if (installed?(spec) || Plugin.installed?(spec.name)) && !force
147
+ if installed?(spec) && !force
131
148
  print_using_message "Using #{version_message(spec)}"
132
149
  return nil # no post-install message
133
150
  end
@@ -315,6 +332,10 @@ module Bundler
315
332
 
316
333
  protected
317
334
 
335
+ def remote_names
336
+ remotes.map(&:to_s).join(", ")
337
+ end
338
+
318
339
  def credless_remotes
319
340
  remotes.map(&method(:suppress_configured_credentials))
320
341
  end
@@ -16,6 +16,10 @@ module Bundler
16
16
  @index
17
17
  end
18
18
 
19
+ def to_err
20
+ to_s
21
+ end
22
+
19
23
  def to_s
20
24
  "any of the sources"
21
25
  end
@@ -67,6 +67,10 @@ module Bundler
67
67
  "#<#{self.class}:0x#{object_id} #{self}>"
68
68
  end
69
69
 
70
+ def to_err
71
+ to_s
72
+ end
73
+
70
74
  def path?
71
75
  instance_of?(Bundler::Source::Path)
72
76
  end
@@ -37,6 +37,10 @@ module Bundler
37
37
  global_rubygems_source.multiple_remotes?
38
38
  end
39
39
 
40
+ def implicit_global_source?
41
+ global_rubygems_source.no_remotes?
42
+ end
43
+
40
44
  def add_path_source(options = {})
41
45
  if options["gemspec"]
42
46
  add_source_to_list Source::Gemspec.new(options), path_sources
@@ -117,7 +121,8 @@ module Bundler
117
121
  def replace_sources!(replacement_sources)
118
122
  return false if replacement_sources.empty?
119
123
 
120
- @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
124
+ @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
125
+ @global_rubygems_source = global_replacement_source(replacement_sources)
121
126
 
122
127
  different_sources?(lock_sources, replacement_sources)
123
128
  end
@@ -152,13 +157,21 @@ module Bundler
152
157
  end
153
158
 
154
159
  def map_sources(replacement_sources)
155
- [path_sources, git_sources, plugin_sources].map do |sources|
160
+ [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources|
156
161
  sources.map do |source|
157
162
  replacement_sources.find {|s| s == source } || source
158
163
  end
159
164
  end
160
165
  end
161
166
 
167
+ def global_replacement_source(replacement_sources)
168
+ replacement_source = replacement_sources.find {|s| s == global_rubygems_source }
169
+ return global_rubygems_source unless replacement_source
170
+
171
+ replacement_source.local!
172
+ replacement_source
173
+ end
174
+
162
175
  def different_sources?(lock_sources, replacement_sources)
163
176
  !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
164
177
  end
@@ -202,7 +215,7 @@ module Bundler
202
215
  end
203
216
 
204
217
  def equal_source?(source, other_source)
205
- return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems) && !merged_gem_lockfile_sections?
218
+ return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems)
206
219
 
207
220
  source == other_source
208
221
  end
@@ -11,21 +11,20 @@ module Bundler
11
11
  @specs = specs
12
12
  end
13
13
 
14
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
14
+ def for(dependencies, check = false, match_current_platform = false)
15
15
  handled = []
16
16
  deps = dependencies.dup
17
17
  specs = []
18
- skip += ["bundler"]
19
18
 
20
19
  loop do
21
20
  break unless dep = deps.shift
22
- next if handled.include?(dep) || skip.include?(dep.name)
21
+ next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
23
22
 
24
23
  handled << dep
25
24
 
26
25
  specs_for_dep = spec_for_dependency(dep, match_current_platform)
27
26
  if specs_for_dep.any?
28
- specs += specs_for_dep
27
+ match_current_platform ? specs += specs_for_dep : specs |= specs_for_dep
29
28
 
30
29
  specs_for_dep.first.dependencies.each do |d|
31
30
  next if d.type == :development
@@ -34,11 +33,6 @@ module Bundler
34
33
  end
35
34
  elsif check
36
35
  return false
37
- elsif raise_on_missing
38
- others = lookup[dep.name] if match_current_platform
39
- message = "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
40
- message += " Found #{others.join(", ")} that did not match the current platform." if others && !others.empty?
41
- raise GemNotFound, message
42
36
  end
43
37
  end
44
38
 
@@ -72,52 +66,35 @@ module Bundler
72
66
  lookup.dup
73
67
  end
74
68
 
75
- def materialize(deps, missing_specs = nil)
76
- materialized = self.for(deps, [], false, true, !missing_specs)
77
-
78
- materialized.group_by(&:source).each do |source, specs|
79
- next unless specs.any?{|s| s.is_a?(LazySpecification) }
80
-
81
- source.local!
82
- names = -> { specs.map(&:name).uniq }
83
- source.double_check_for(names)
84
- end
69
+ def materialize(deps)
70
+ materialized = self.for(deps, false, true)
85
71
 
86
72
  materialized.map! do |s|
87
73
  next s unless s.is_a?(LazySpecification)
88
- spec = s.__materialize__
89
- unless spec
90
- unless missing_specs
91
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
92
- end
93
- missing_specs << s
94
- end
95
- spec
74
+ s.source.local!
75
+ s.__materialize__ || s
96
76
  end
97
- SpecSet.new(missing_specs ? materialized.compact : materialized)
77
+ SpecSet.new(materialized)
98
78
  end
99
79
 
100
80
  # Materialize for all the specs in the spec set, regardless of what platform they're for
101
81
  # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
102
82
  # @return [Array<Gem::Specification>]
103
83
  def materialized_for_all_platforms
104
- @specs.group_by(&:source).each do |source, specs|
105
- next unless specs.any?{|s| s.is_a?(LazySpecification) }
106
-
107
- source.local!
108
- source.remote!
109
- names = -> { specs.map(&:name).uniq }
110
- source.double_check_for(names)
111
- end
112
-
113
84
  @specs.map do |s|
114
85
  next s unless s.is_a?(LazySpecification)
86
+ s.source.local!
87
+ s.source.remote!
115
88
  spec = s.__materialize__
116
89
  raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
117
90
  spec
118
91
  end
119
92
  end
120
93
 
94
+ def missing_specs
95
+ @specs.select {|s| s.is_a?(LazySpecification) }
96
+ end
97
+
121
98
  def merge(set)
122
99
  arr = sorted.dup
123
100
  set.each do |set_spec|
@@ -60,16 +60,16 @@ m = Module.new do
60
60
  Regexp.last_match(1)
61
61
  end
62
62
 
63
- def bundler_version
64
- @bundler_version ||=
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
65
  env_var_version || cli_arg_version ||
66
- lockfile_version
66
+ bundler_requirement_for(lockfile_version)
67
67
  end
68
68
 
69
- def bundler_requirement
70
- return "#{Gem::Requirement.default}.a" unless bundler_version
69
+ def bundler_requirement_for(version)
70
+ return "#{Gem::Requirement.default}.a" unless version
71
71
 
72
- bundler_gem_version = Gem::Version.new(bundler_version)
72
+ bundler_gem_version = Gem::Version.new(version)
73
73
 
74
74
  requirement = bundler_gem_version.approximate_recommendation
75
75
 
@@ -1,16 +1,27 @@
1
1
  name: Ruby
2
2
 
3
- on: [push,pull_request]
3
+ on:
4
+ push:
5
+ branches:
6
+ - <%= config[:git_default_branch] %>
7
+
8
+ pull_request:
4
9
 
5
10
  jobs:
6
11
  build:
7
12
  runs-on: ubuntu-latest
13
+
14
+ strategy:
15
+ matrix:
16
+ ruby:
17
+ - <%= RUBY_VERSION %>
18
+
8
19
  steps:
9
20
  - uses: actions/checkout@v2
10
21
  - name: Set up Ruby
11
22
  uses: ruby/setup-ruby@v1
12
23
  with:
13
- ruby-version: <%= RUBY_VERSION %>
24
+ ruby-version: ${{ matrix.ruby }}
14
25
  bundler-cache: true
15
26
  - name: Run the default task
16
27
  run: bundle exec rake
@@ -25,7 +25,9 @@ Gem::Specification.new do |spec|
25
25
  # Specify which files should be added to the gem when it is released.
26
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
27
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
30
+ end
29
31
  end
30
32
  spec.bindir = "exe"
31
33
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.23".freeze
4
+ VERSION = "2.2.27".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
@@ -26,7 +26,7 @@ module Bundler
26
26
  @func = func
27
27
  @size = size
28
28
  @threads = nil
29
- SharedHelpers.trap("INT") { abort_threads }
29
+ @previous_interrupt_handler = nil
30
30
  end
31
31
 
32
32
  # Enqueue a request to be executed in the worker pool
@@ -68,13 +68,16 @@ module Bundler
68
68
  # so as worker threads after retrieving it, shut themselves down
69
69
  def stop_threads
70
70
  return unless @threads
71
+
71
72
  @threads.each { @request_queue.enq POISON }
72
73
  @threads.each(&:join)
74
+
75
+ remove_interrupt_handler
76
+
73
77
  @threads = nil
74
78
  end
75
79
 
76
80
  def abort_threads
77
- return unless @threads
78
81
  Bundler.ui.debug("\n#{caller.join("\n")}")
79
82
  @threads.each(&:exit)
80
83
  exit 1
@@ -94,11 +97,23 @@ module Bundler
94
97
  end
95
98
  end.compact
96
99
 
100
+ add_interrupt_handler unless @threads.empty?
101
+
97
102
  return if creation_errors.empty?
98
103
 
99
104
  message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}"
100
105
  raise ThreadCreationError, message if @threads.empty?
101
106
  Bundler.ui.info message
102
107
  end
108
+
109
+ def add_interrupt_handler
110
+ @previous_interrupt_handler = trap("INT") { abort_threads }
111
+ end
112
+
113
+ def remove_interrupt_handler
114
+ return unless @previous_interrupt_handler
115
+
116
+ trap "INT", @previous_interrupt_handler
117
+ end
103
118
  end
104
119
  end