bundler 2.2.7 → 2.2.12

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/lib/bundler.rb +1 -1
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli.rb +1 -0
  6. data/lib/bundler/cli/gem.rb +12 -0
  7. data/lib/bundler/definition.rb +15 -25
  8. data/lib/bundler/index.rb +6 -5
  9. data/lib/bundler/installer.rb +2 -0
  10. data/lib/bundler/installer/standalone.rb +2 -1
  11. data/lib/bundler/lazy_specification.rb +8 -17
  12. data/lib/bundler/man/bundle-config.1 +4 -4
  13. data/lib/bundler/man/bundle-config.1.ronn +8 -7
  14. data/lib/bundler/resolver.rb +48 -29
  15. data/lib/bundler/resolver/spec_group.rb +53 -38
  16. data/lib/bundler/rubygems_gem_installer.rb +47 -0
  17. data/lib/bundler/shared_helpers.rb +2 -2
  18. data/lib/bundler/source_list.rb +2 -4
  19. data/lib/bundler/spec_set.rb +4 -3
  20. data/lib/bundler/stub_specification.rb +8 -0
  21. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  22. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -1
  23. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  24. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  25. data/lib/bundler/vendor/thor/lib/thor.rb +5 -6
  26. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  27. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  28. data/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  29. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  30. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  31. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  32. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  33. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  34. data/lib/bundler/version.rb +1 -1
  35. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f8e9970b2d4991ebf1dd972107e05ecd32951bdfa797ed6c36d6abf7a703ea1
4
- data.tar.gz: 0d0ecd48d724a845003397e3ecb2bd063a2ab666522e3c37806175ecfe6a02f3
3
+ metadata.gz: 6c743279657baa7fb86bcbe8b49fe758261f53161679c28c0d9d4251f7c32626
4
+ data.tar.gz: 127f8571d11fd6f22612ee988bb6abec9035cfa9df65949994255253b4c108b7
5
5
  SHA512:
6
- metadata.gz: 345c9fdec8f29fdc67469a1d8cda01428120c1dc87c5db079449c388d02f3779942403ee719737ec8b95b9cd2fd0d0a06a6f26b2aa2d5c354aacff97a6ba8baa
7
- data.tar.gz: 0aad39443512928b799c817eb78641e2bb7e0637937f26894ceda1bb250292fd5be44e0e61e714679bd07cac8ded827f6107934f90511ef00547837fa3292e8a
6
+ metadata.gz: 284b277cfa1bdd0d99da2eef27a8ea3ae97c2e4f0ca1b6622bb276fdf7f9de4e46c44f3aaffc94328569df7057c6cb1dd091702f35b5a2bb808764df708b9c14
7
+ data.tar.gz: 606a3cbbbb7186a5fdfc8a6c68f9f50cba4e8634506f8a7fba8ff4fbdbae0013f8e551a2f9d97980a20c781f79ef542c9d664cf84b6a029e3649349a27260422
data/CHANGELOG.md CHANGED
@@ -1,3 +1,56 @@
1
+ # 2.2.12 (March 1, 2021)
2
+
3
+ ## Bug fixes:
4
+
5
+ - Fix sporadic warnings about `nil` gemspec on install/update and make those faster [#4409](https://github.com/rubygems/rubygems/pull/4409)
6
+ - Fix deployment install with duplicate path gems added to Gemfile [#4410](https://github.com/rubygems/rubygems/pull/4410)
7
+
8
+ # 2.2.11 (February 17, 2021)
9
+
10
+ ## Bug fixes:
11
+
12
+ - Revert disable_multisource changes [#4385](https://github.com/rubygems/rubygems/pull/4385)
13
+
14
+ # 2.2.10 (February 15, 2021)
15
+
16
+ ## Security fixes:
17
+
18
+ - Fix source priority for transitive dependencies and split lockfile rubygems source sections [#3655](https://github.com/rubygems/rubygems/pull/3655)
19
+
20
+ ## Bug fixes:
21
+
22
+ - Fix adding platforms to lockfile sometimes conflicting on ruby requirements [#4371](https://github.com/rubygems/rubygems/pull/4371)
23
+ - Fix bundler sometimes choosing ruby variants over java ones [#4367](https://github.com/rubygems/rubygems/pull/4367)
24
+
25
+ ## Documentation:
26
+
27
+ - Update man pages to reflect to new default for bundle install jobs [#4188](https://github.com/rubygems/rubygems/pull/4188)
28
+
29
+ # 2.2.9 (February 8, 2021)
30
+
31
+ ## Enhancements:
32
+
33
+ - Stop removing existing platforms when force_ruby_platform is true [#4336](https://github.com/rubygems/rubygems/pull/4336)
34
+
35
+ ## Bug fixes:
36
+
37
+ - Don't install platform specific gems on truffleruby [#4333](https://github.com/rubygems/rubygems/pull/4333)
38
+
39
+ # 2.2.8 (February 2, 2021)
40
+
41
+ ## Enhancements:
42
+
43
+ - Add a CHANGELOG.md file to gems generated by `bundle gem` [#4093](https://github.com/rubygems/rubygems/pull/4093)
44
+ - Support gemified `set` [#4297](https://github.com/rubygems/rubygems/pull/4297)
45
+
46
+ ## Bug fixes:
47
+
48
+ - Fix standalone Kernel.require visibility [#4337](https://github.com/rubygems/rubygems/pull/4337)
49
+
50
+ ## Performance:
51
+
52
+ - Fix resolver edge cases and speed up bundler [#4277](https://github.com/rubygems/rubygems/pull/4277)
53
+
1
54
  # 2.2.7 (January 26, 2021)
2
55
 
3
56
  ## Enhancements:
data/lib/bundler.rb CHANGED
@@ -440,7 +440,7 @@ EOF
440
440
  end
441
441
 
442
442
  def local_platform
443
- return Gem::Platform::RUBY if settings[:force_ruby_platform]
443
+ return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY]
444
444
  Gem::Platform.local
445
445
  end
446
446
 
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2021-01-27".freeze
8
- @git_commit_sha = "7bc7ecb660".freeze
7
+ @built_at = "2021-03-01".freeze
8
+ @git_commit_sha = "1de3f8de73".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
data/lib/bundler/cli.rb CHANGED
@@ -586,6 +586,7 @@ module Bundler
586
586
  method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library."
587
587
  method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
588
588
  method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
589
+ method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
589
590
  method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library",
590
591
  :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)`."
591
592
  method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
@@ -142,6 +142,18 @@ module Bundler
142
142
  templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
143
143
  end
144
144
 
145
+ if ask_and_set(:changelog, "Do you want to include a changelog?",
146
+ "A changelog is a file which contains a curated, chronologically ordered list of notable " \
147
+ "changes for each version of a project. To make it easier for users and contributors to" \
148
+ " see precisely what notable changes have been made between each release (or version) of" \
149
+ " the project. Whether consumers or developers, the end users of software are" \
150
+ " human beings who care about what's in the software. When the software changes, people " \
151
+ "want to know why and how. see https://keepachangelog.com")
152
+ config[:changelog] = true
153
+ Bundler.ui.info "Changelog enabled in config"
154
+ templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
155
+ end
156
+
145
157
  if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
146
158
  "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
147
159
  "of the guidelines in the community style guide. " \
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "lockfile_parser"
4
- require "set"
5
4
 
6
5
  module Bundler
7
6
  class Definition
@@ -83,11 +82,7 @@ module Bundler
83
82
  @lockfile_contents = Bundler.read_file(lockfile)
84
83
  @locked_gems = LockfileParser.new(@lockfile_contents)
85
84
  @locked_platforms = @locked_gems.platforms
86
- if Bundler.settings[:force_ruby_platform]
87
- @platforms = [Gem::Platform::RUBY]
88
- else
89
- @platforms = @locked_platforms.dup
90
- end
85
+ @platforms = @locked_platforms.dup
91
86
  @locked_bundler_version = @locked_gems.bundler_version
92
87
  @locked_ruby_version = @locked_gems.ruby_version
93
88
 
@@ -259,23 +254,18 @@ module Bundler
259
254
  def resolve
260
255
  @resolve ||= begin
261
256
  last_resolve = converge_locked_specs
262
- resolve =
263
- if Bundler.frozen_bundle?
264
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
265
- last_resolve
266
- elsif !unlocking? && nothing_changed?
267
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
268
- last_resolve
269
- else
270
- # Run a resolve against the locally available gems
271
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
272
- expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
273
- last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
274
- end
275
-
276
- # filter out gems that _can_ be installed on multiple platforms, but don't need
277
- # to be
278
- resolve.for(expand_dependencies(dependencies, true), [], false, false, false)
257
+ if Bundler.frozen_bundle?
258
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
259
+ last_resolve
260
+ elsif !unlocking? && nothing_changed?
261
+ Bundler.ui.debug("Found no changes, using resolution from the lockfile")
262
+ last_resolve
263
+ else
264
+ # Run a resolve against the locally available gems
265
+ Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
266
+ expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
267
+ Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
268
+ end
279
269
  end
280
270
  end
281
271
 
@@ -604,7 +594,7 @@ module Bundler
604
594
  deps_for_source = @dependencies.select {|s| s.source == source }
605
595
  locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
606
596
 
607
- Set.new(deps_for_source) != Set.new(locked_deps_for_source)
597
+ deps_for_source.uniq.sort != locked_deps_for_source.sort
608
598
  end
609
599
 
610
600
  def specs_for_source_changed?(source)
@@ -884,7 +874,7 @@ module Bundler
884
874
  dependencies.each do |dep|
885
875
  dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
886
876
  next unless remote || dep.current_platform?
887
- target_platforms = dep.gem_platforms(remote ? Resolver.sort_platforms(@platforms) : [generic_local_platform])
877
+ target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
888
878
  deps += expand_dependency_with_platforms(dep, target_platforms)
889
879
  end
890
880
  deps
data/lib/bundler/index.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  module Bundler
6
4
  class Index
7
5
  include Enumerable
@@ -65,11 +63,14 @@ module Bundler
65
63
  def unsorted_search(query, base)
66
64
  results = local_search(query, base)
67
65
 
68
- seen = results.map(&:full_name).to_set unless @sources.empty?
66
+ seen = results.map(&:full_name).uniq unless @sources.empty?
69
67
 
70
68
  @sources.each do |source|
71
69
  source.unsorted_search(query, base).each do |spec|
72
- results << spec if seen.add?(spec.full_name)
70
+ next if seen.include?(spec.full_name)
71
+
72
+ seen << spec.full_name
73
+ results << spec
73
74
  end
74
75
  end
75
76
 
@@ -170,7 +171,7 @@ module Bundler
170
171
  def dependencies_eql?(spec, other_spec)
171
172
  deps = spec.dependencies.select {|d| d.type != :development }
172
173
  other_deps = other_spec.dependencies.select {|d| d.type != :development }
173
- Set.new(deps) == Set.new(other_deps)
174
+ deps.sort == other_deps.sort
174
175
  end
175
176
 
176
177
  def add_source(index)
@@ -89,6 +89,8 @@ module Bundler
89
89
  end
90
90
  install(options)
91
91
 
92
+ Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
93
+
92
94
  lock unless Bundler.frozen_bundle?
93
95
  Standalone.new(options[:standalone], @definition).generate if options[:standalone]
94
96
  end
@@ -55,9 +55,10 @@ module Bundler
55
55
  kernel = (class << ::Kernel; self; end)
56
56
  [kernel, ::Kernel].each do |k|
57
57
  if k.private_method_defined?(:gem_original_require)
58
+ private_require = k.private_method_defined?(:require)
58
59
  k.send(:remove_method, :require)
59
60
  k.send(:define_method, :require, k.instance_method(:gem_original_require))
60
- k.send(:private, :require)
61
+ k.send(:private, :require) if private_require
61
62
  end
62
63
  end
63
64
  END
@@ -4,22 +4,6 @@ require_relative "match_platform"
4
4
 
5
5
  module Bundler
6
6
  class LazySpecification
7
- Identifier = Struct.new(:name, :version, :platform)
8
- class Identifier
9
- include Comparable
10
- def <=>(other)
11
- return unless other.is_a?(Identifier)
12
- [name, version, platform_string] <=> [other.name, other.version, other.platform_string]
13
- end
14
-
15
- protected
16
-
17
- def platform_string
18
- platform_string = platform.to_s
19
- platform_string == Index::RUBY ? Index::NULL : platform_string
20
- end
21
- end
22
-
23
7
  include MatchPlatform
24
8
 
25
9
  attr_reader :name, :version, :dependencies, :platform
@@ -108,7 +92,7 @@ module Bundler
108
92
  end
109
93
 
110
94
  def identifier
111
- @__identifier ||= Identifier.new(name, version, platform)
95
+ @__identifier ||= [name, version, platform_string]
112
96
  end
113
97
 
114
98
  def git_version
@@ -116,6 +100,13 @@ module Bundler
116
100
  " #{source.revision[0..6]}"
117
101
  end
118
102
 
103
+ protected
104
+
105
+ def platform_string
106
+ platform_string = platform.to_s
107
+ platform_string == Index::RUBY ? Index::NULL : platform_string
108
+ end
109
+
119
110
  private
120
111
 
121
112
  def to_ary
@@ -211,10 +211,10 @@ The following is a list of all configuration keys and their purpose\. You can le
211
211
  \fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\.
212
212
  .
213
213
  .IP "\(bu" 4
214
- \fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR) Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
214
+ \fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
215
215
  .
216
216
  .IP "\(bu" 4
217
- \fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to 1\.
217
+ \fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to 1 on Windows, and to the the number of processors on other platforms\.
218
218
  .
219
219
  .IP "\(bu" 4
220
220
  \fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\.
@@ -241,7 +241,7 @@ The following is a list of all configuration keys and their purpose\. You can le
241
241
  \fBprefer_patch\fR (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
242
242
  .
243
243
  .IP "\(bu" 4
244
- \fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR) Print only version number from \fBbundler \-\-version\fR\.
244
+ \fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR): Print only version number from \fBbundler \-\-version\fR\.
245
245
  .
246
246
  .IP "\(bu" 4
247
247
  \fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\.
@@ -283,7 +283,7 @@ The following is a list of all configuration keys and their purpose\. You can le
283
283
  \fBunlock_source_unlocks_spec\fR (\fBBUNDLE_UNLOCK_SOURCE_UNLOCKS_SPEC\fR): Whether running \fBbundle update \-\-source NAME\fR unlocks a gem with the given name\. Defaults to \fBtrue\fR\.
284
284
  .
285
285
  .IP "\(bu" 4
286
- \fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR) Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
286
+ \fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
287
287
  .
288
288
  .IP "\(bu" 4
289
289
  \fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\.
@@ -206,13 +206,14 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
206
206
  * `global_gem_cache` (`BUNDLE_GLOBAL_GEM_CACHE`):
207
207
  Whether Bundler should cache all gems globally, rather than locally to the
208
208
  installing Ruby installation.
209
- * `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`): When set, no post install
210
- messages will be printed. To silence a single gem, use dot notation like
211
- `ignore_messages.httparty true`.
212
- * `init_gems_rb` (`BUNDLE_INIT_GEMS_RB`)
209
+ * `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`):
210
+ When set, no post install messages will be printed. To silence a single gem,
211
+ use dot notation like `ignore_messages.httparty true`.
212
+ * `init_gems_rb` (`BUNDLE_INIT_GEMS_RB`):
213
213
  Generate a `gems.rb` instead of a `Gemfile` when running `bundle init`.
214
214
  * `jobs` (`BUNDLE_JOBS`):
215
- The number of gems Bundler can install in parallel. Defaults to 1.
215
+ The number of gems Bundler can install in parallel. Defaults to 1 on Windows,
216
+ and to the the number of processors on other platforms.
216
217
  * `no_install` (`BUNDLE_NO_INSTALL`):
217
218
  Whether `bundle package` should skip installing gems.
218
219
  * `no_prune` (`BUNDLE_NO_PRUNE`):
@@ -233,7 +234,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
233
234
  Enable Bundler's experimental plugin system.
234
235
  * `prefer_patch` (BUNDLE_PREFER_PATCH):
235
236
  Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`.
236
- * `print_only_version_number` (`BUNDLE_PRINT_ONLY_VERSION_NUMBER`)
237
+ * `print_only_version_number` (`BUNDLE_PRINT_ONLY_VERSION_NUMBER`):
237
238
  Print only version number from `bundler --version`.
238
239
  * `redirect` (`BUNDLE_REDIRECT`):
239
240
  The number of redirects allowed for network requests. Defaults to `5`.
@@ -269,7 +270,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
269
270
  * `unlock_source_unlocks_spec` (`BUNDLE_UNLOCK_SOURCE_UNLOCKS_SPEC`):
270
271
  Whether running `bundle update --source NAME` unlocks a gem with the given
271
272
  name. Defaults to `true`.
272
- * `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`)
273
+ * `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`):
273
274
  Require passing `--all` to `bundle update` when everything should be updated,
274
275
  and disallow passing no options to `bundle update`.
275
276
  * `user_agent` (`BUNDLE_USER_AGENT`):
@@ -5,6 +5,8 @@ module Bundler
5
5
  require_relative "vendored_molinillo"
6
6
  require_relative "resolver/spec_group"
7
7
 
8
+ include GemHelpers
9
+
8
10
  # Figures out the best possible configuration of gems that satisfies
9
11
  # the list of passed dependencies and any child dependencies without
10
12
  # causing any gem activation errors.
@@ -16,7 +18,6 @@ module Bundler
16
18
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
17
19
  # collection of gemspecs is returned. Otherwise, nil is returned.
18
20
  def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
19
- platforms = Set.new(platforms) if platforms
20
21
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
21
22
  resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
23
  result = resolver.start(requirements)
@@ -35,10 +36,14 @@ module Bundler
35
36
  @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
36
37
  end
37
38
  additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
38
- @platforms = platforms
39
+ @platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
40
+ @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
39
41
  @gem_version_promoter = gem_version_promoter
40
42
  @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
41
43
  @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
44
+
45
+ @variant_specific_names = []
46
+ @generic_names = ["Ruby\0", "RubyGems\0"]
42
47
  end
43
48
 
44
49
  def start(requirements)
@@ -102,14 +107,24 @@ module Bundler
102
107
  include Molinillo::SpecificationProvider
103
108
 
104
109
  def dependencies_for(specification)
105
- specification.dependencies_for_activated_platforms
110
+ all_dependencies = specification.dependencies_for_activated_platforms
111
+
112
+ if @variant_specific_names.include?(specification.name)
113
+ @variant_specific_names |= all_dependencies.map(&:name) - @generic_names
114
+ else
115
+ generic_names, variant_specific_names = specification.partitioned_dependency_names_for_activated_platforms
116
+ @variant_specific_names |= variant_specific_names - @generic_names
117
+ @generic_names |= generic_names
118
+ end
119
+
120
+ all_dependencies
106
121
  end
107
122
 
108
123
  def search_for(dependency_proxy)
109
124
  platform = dependency_proxy.__platform
110
125
  dependency = dependency_proxy.dep
111
- @search_for[dependency_proxy] ||= begin
112
- name = dependency.name
126
+ name = dependency.name
127
+ search_result = @search_for[dependency_proxy] ||= begin
113
128
  index = index_for(dependency)
114
129
  results = index.search(dependency, @base[name])
115
130
 
@@ -136,37 +151,48 @@ module Bundler
136
151
  end
137
152
  nested.reduce([]) do |groups, (version, specs)|
138
153
  next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
139
- spec_group = SpecGroup.new(specs)
140
- groups << spec_group
154
+
155
+ specs_by_platform = Hash.new do |current_specs, current_platform|
156
+ current_specs[current_platform] = select_best_platform_match(specs, current_platform)
157
+ end
158
+
159
+ spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
160
+ groups << spec_group_ruby if spec_group_ruby
161
+
162
+ next groups if @resolving_only_for_ruby
163
+
164
+ spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
165
+ groups << spec_group if spec_group
166
+
167
+ groups
141
168
  end
142
169
  else
143
170
  []
144
171
  end
145
172
  # GVP handles major itself, but it's still a bit risky to trust it with it
146
173
  # until we get it settled with new behavior. For 2.x it can take over all cases.
147
- search = if !@use_gvp
174
+ if !@use_gvp
148
175
  spec_groups
149
176
  else
150
177
  @gem_version_promoter.sort_versions(dependency, spec_groups)
151
178
  end
152
- selected_sgs = []
153
- search.each do |sg|
154
- next unless sg.for?(platform)
155
- sg_all_platforms = sg.copy_for(self.class.sort_platforms(@platforms).reverse)
156
- next unless sg_all_platforms
157
-
158
- selected_sgs << sg_all_platforms
179
+ end
159
180
 
160
- next if sg_all_platforms.activated_platforms == [Gem::Platform::RUBY]
161
- # Add a spec group for "non platform specific spec" as the fallback
162
- # spec group.
163
- sg_ruby = sg.copy_for([Gem::Platform::RUBY])
164
- next unless sg_ruby
181
+ unless search_result.empty?
182
+ specific_dependency = @variant_specific_names.include?(name)
183
+ return search_result unless specific_dependency
165
184
 
166
- selected_sgs.insert(-2, sg_ruby)
185
+ search_result.each do |sg|
186
+ if @generic_names.include?(name)
187
+ @variant_specific_names -= [name]
188
+ sg.activate_all_platforms!
189
+ else
190
+ sg.activate_platform!(platform)
191
+ end
167
192
  end
168
- selected_sgs
169
193
  end
194
+
195
+ search_result
170
196
  end
171
197
 
172
198
  def index_for(dependency)
@@ -237,13 +263,6 @@ module Bundler
237
263
  end
238
264
  end
239
265
 
240
- # Sort platforms from most general to most specific
241
- def self.sort_platforms(platforms)
242
- platforms.sort_by do |platform|
243
- platform_sort_key(platform)
244
- end
245
- end
246
-
247
266
  def self.platform_sort_key(platform)
248
267
  # Prefer specific platform to not specific platform
249
268
  return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
@@ -3,27 +3,37 @@
3
3
  module Bundler
4
4
  class Resolver
5
5
  class SpecGroup
6
- include GemHelpers
7
-
8
6
  attr_accessor :name, :version, :source
9
7
  attr_accessor :activated_platforms
10
8
 
11
- def initialize(all_specs)
12
- @all_specs = all_specs
13
- raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
9
+ def self.create_for(specs, all_platforms, specific_platform)
10
+ specific_platform_specs = specs[specific_platform]
11
+ return unless specific_platform_specs.any?
12
+
13
+ platforms = all_platforms.select {|p| specs[p].any? }
14
+
15
+ new(specific_platform_specs.first, specs, platforms)
16
+ end
17
+
18
+ def initialize(exemplary_spec, specs, relevant_platforms)
19
+ @exemplary_spec = exemplary_spec
14
20
  @name = exemplary_spec.name
15
21
  @version = exemplary_spec.version
16
22
  @source = exemplary_spec.source
17
23
 
18
- @activated_platforms = []
19
- @dependencies = nil
20
- @specs = Hash.new do |specs, platform|
21
- specs[platform] = select_best_platform_match(all_specs, platform)
24
+ @all_platforms = relevant_platforms
25
+ @activated_platforms = relevant_platforms
26
+ @dependencies = Hash.new do |dependencies, platforms|
27
+ dependencies[platforms] = dependencies_for(platforms)
22
28
  end
29
+ @partitioned_dependency_names = Hash.new do |partitioned_dependency_names, platforms|
30
+ partitioned_dependency_names[platforms] = partitioned_dependency_names_for(platforms)
31
+ end
32
+ @specs = specs
23
33
  end
24
34
 
25
35
  def to_specs
26
- @activated_platforms.map do |p|
36
+ activated_platforms.map do |p|
27
37
  specs = @specs[p]
28
38
  next unless specs.any?
29
39
 
@@ -35,17 +45,12 @@ module Bundler
35
45
  end.flatten.compact.uniq
36
46
  end
37
47
 
38
- def copy_for(platforms)
39
- platforms.select! {|p| for?(p) }
40
- return unless platforms.any?
41
-
42
- copied_sg = self.class.new(@all_specs)
43
- copied_sg.activated_platforms = platforms
44
- copied_sg
48
+ def activate_platform!(platform)
49
+ self.activated_platforms = [platform]
45
50
  end
46
51
 
47
- def for?(platform)
48
- @specs[platform].any?
52
+ def activate_all_platforms!
53
+ self.activated_platforms = @all_platforms
49
54
  end
50
55
 
51
56
  def to_s
@@ -54,11 +59,11 @@ module Bundler
54
59
  end
55
60
 
56
61
  def dependencies_for_activated_platforms
57
- dependencies = @activated_platforms.map {|p| __dependencies[p] }
58
- metadata_dependencies = @activated_platforms.map do |platform|
59
- metadata_dependencies(@specs[platform].first, platform)
60
- end
61
- dependencies.concat(metadata_dependencies).flatten
62
+ @dependencies[activated_platforms]
63
+ end
64
+
65
+ def partitioned_dependency_names_for_activated_platforms
66
+ @partitioned_dependency_names[activated_platforms]
62
67
  end
63
68
 
64
69
  def ==(other)
@@ -84,27 +89,37 @@ module Bundler
84
89
  protected
85
90
 
86
91
  def sorted_activated_platforms
87
- @activated_platforms.sort_by(&:to_s)
92
+ activated_platforms.sort_by(&:to_s)
88
93
  end
89
94
 
90
95
  private
91
96
 
92
- def __dependencies
93
- @dependencies = Hash.new do |dependencies, platform|
94
- dependencies[platform] = []
95
- specs = @specs[platform]
96
- if spec = specs.first
97
- spec.dependencies.each do |dep|
98
- next if dep.type == :development
99
- dependencies[platform] << DepProxy.get_proxy(dep, platform)
100
- end
101
- end
102
- dependencies[platform]
97
+ def dependencies_for(platforms)
98
+ platforms.map do |platform|
99
+ __dependencies(platform) + metadata_dependencies(platform)
100
+ end.flatten
101
+ end
102
+
103
+ def partitioned_dependency_names_for(platforms)
104
+ return @dependencies[platforms].map(&:name), [] if platforms.size == 1
105
+
106
+ @dependencies[platforms].partition do |dep_proxy|
107
+ @dependencies[platforms].count {|dp| dp.dep == dep_proxy.dep } == platforms.size
108
+ end.map {|deps| deps.map(&:name) }
109
+ end
110
+
111
+ def __dependencies(platform)
112
+ dependencies = []
113
+ @specs[platform].first.dependencies.each do |dep|
114
+ next if dep.type == :development
115
+ dependencies << DepProxy.get_proxy(dep, platform)
103
116
  end
117
+ dependencies
104
118
  end
105
119
 
106
- def metadata_dependencies(spec, platform)
107
- return [] unless spec && spec.is_a?(Gem::Specification)
120
+ def metadata_dependencies(platform)
121
+ spec = @specs[platform].first
122
+ return [] unless spec.is_a?(Gem::Specification)
108
123
  dependencies = []
109
124
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
110
125
  dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
@@ -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
@@ -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
@@ -1,7 +1,5 @@
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,
@@ -99,7 +97,7 @@ module Bundler
99
97
  @rubygems_aggregate = replacement_rubygems if replacement_rubygems
100
98
 
101
99
  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
100
+ return true if replacement_rubygems && rubygems_remotes.sort_by(&:to_s) != replacement_rubygems.remotes.sort_by(&:to_s)
103
101
 
104
102
  false
105
103
  end
@@ -153,7 +151,7 @@ module Bundler
153
151
  end
154
152
 
155
153
  def equal_sources?(lock_sources, replacement_sources)
156
- lock_sources.to_set == replacement_sources.to_set
154
+ lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
157
155
  end
158
156
 
159
157
  def equal_source?(source, other_source)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "tsort"
4
- require "set"
5
4
 
6
5
  module Bundler
7
6
  class SpecSet
@@ -13,14 +12,16 @@ module Bundler
13
12
  end
14
13
 
15
14
  def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
16
- handled = Set.new
15
+ handled = []
17
16
  deps = dependencies.dup
18
17
  specs = []
19
18
  skip += ["bundler"]
20
19
 
21
20
  loop do
22
21
  break unless dep = deps.shift
23
- next if !handled.add?(dep) || skip.include?(dep.name)
22
+ next if handled.include?(dep) || skip.include?(dep.name)
23
+
24
+ handled << dep
24
25
 
25
26
  specs_for_dep = spec_for_dependency(dep, match_current_platform)
26
27
  if specs_for_dep.any?
@@ -26,11 +26,19 @@ module Bundler
26
26
 
27
27
  # @!group Stub Delegates
28
28
 
29
+ def manually_installed?
30
+ # This is for manually installed gems which are gems that were fixed in place after a
31
+ # failed installation. Once the issue was resolved, the user then manually created
32
+ # the gem specification using the instructions provided by `gem help install`
33
+ installed_by_version == Gem::Version.new(0)
34
+ end
35
+
29
36
  # This is defined directly to avoid having to loading the full spec
30
37
  def missing_extensions?
31
38
  return false if default_gem?
32
39
  return false if extensions.empty?
33
40
  return false if File.exist? gem_build_complete_path
41
+ return false if manually_installed?
34
42
 
35
43
  true
36
44
  end
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - <%= Time.now.strftime('%F') %>
4
+
5
+ - Initial release
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'tsort'
5
4
 
6
5
  require_relative 'dependency_graph/log'
@@ -59,7 +59,7 @@ module Bundler::Molinillo
59
59
  # @param [Set<Vertex>] vertices the set to add the predecessors to
60
60
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
61
61
  # {#descendent?}
62
- def _recursive_predecessors(vertices = Set.new)
62
+ def _recursive_predecessors(vertices = new_vertex_set)
63
63
  incoming_edges.each do |edge|
64
64
  vertex = edge.origin
65
65
  next unless vertices.add?(vertex)
@@ -85,7 +85,7 @@ module Bundler::Molinillo
85
85
  # @param [Set<Vertex>] vertices the set to add the successors to
86
86
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
87
87
  # {#ancestor?}
88
- def _recursive_successors(vertices = Set.new)
88
+ def _recursive_successors(vertices = new_vertex_set)
89
89
  outgoing_edges.each do |edge|
90
90
  vertex = edge.destination
91
91
  next unless vertices.add?(vertex)
@@ -128,7 +128,7 @@ module Bundler::Molinillo
128
128
 
129
129
  # Is there a path from `self` to `other` following edges in the
130
130
  # dependency graph?
131
- # @return true iff there is a path following edges within this {#graph}
131
+ # @return whether there is a path following edges within this {#graph}
132
132
  def path_to?(other)
133
133
  _path_to?(other)
134
134
  end
@@ -138,7 +138,7 @@ module Bundler::Molinillo
138
138
  # @param [Vertex] other the vertex to check if there's a path to
139
139
  # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
140
140
  # @return [Boolean] whether there is a path to `other` from `self`
141
- def _path_to?(other, visited = Set.new)
141
+ def _path_to?(other, visited = new_vertex_set)
142
142
  return false unless visited.add?(self)
143
143
  return true if equal?(other)
144
144
  successors.any? { |v| v._path_to?(other, visited) }
@@ -147,12 +147,18 @@ module Bundler::Molinillo
147
147
 
148
148
  # Is there a path from `other` to `self` following edges in the
149
149
  # dependency graph?
150
- # @return true iff there is a path following edges within this {#graph}
150
+ # @return whether there is a path following edges within this {#graph}
151
151
  def ancestor?(other)
152
152
  other.path_to?(self)
153
153
  end
154
154
 
155
155
  alias is_reachable_from? ancestor?
156
+
157
+ def new_vertex_set
158
+ require 'set'
159
+ Set.new
160
+ end
161
+ private :new_vertex_set
156
162
  end
157
163
  end
158
164
  end
@@ -34,7 +34,7 @@ module Bundler::Molinillo
34
34
 
35
35
  # An error caused by attempting to fulfil a dependency that was circular
36
36
  #
37
- # @note This exception will be thrown iff a {Vertex} is added to a
37
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
38
38
  # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
39
39
  # existing {DependencyGraph::Vertex}
40
40
  class CircularDependencyError < ResolverError
@@ -1,7 +1,7 @@
1
- require "set"
2
1
  require_relative "thor/base"
3
2
 
4
3
  class Bundler::Thor
4
+ $thor_runner ||= false
5
5
  class << self
6
6
  # Allows for custom "Command" package naming.
7
7
  #
@@ -323,7 +323,7 @@ class Bundler::Thor
323
323
  # ==== Parameters
324
324
  # Symbol ...:: A list of commands that should be affected.
325
325
  def stop_on_unknown_option!(*command_names)
326
- stop_on_unknown_option.merge(command_names)
326
+ @stop_on_unknown_option = stop_on_unknown_option | command_names
327
327
  end
328
328
 
329
329
  def stop_on_unknown_option?(command) #:nodoc:
@@ -337,7 +337,7 @@ class Bundler::Thor
337
337
  # ==== Parameters
338
338
  # Symbol ...:: A list of commands that should be affected.
339
339
  def disable_required_check!(*command_names)
340
- disable_required_check.merge(command_names)
340
+ @disable_required_check = disable_required_check | command_names
341
341
  end
342
342
 
343
343
  def disable_required_check?(command) #:nodoc:
@@ -347,12 +347,12 @@ class Bundler::Thor
347
347
  protected
348
348
 
349
349
  def stop_on_unknown_option #:nodoc:
350
- @stop_on_unknown_option ||= Set.new
350
+ @stop_on_unknown_option ||= []
351
351
  end
352
352
 
353
353
  # help command has the required check disabled by default.
354
354
  def disable_required_check #:nodoc:
355
- @disable_required_check ||= Set.new([:help])
355
+ @disable_required_check ||= [:help]
356
356
  end
357
357
 
358
358
  # The method responsible for dispatching given the args.
@@ -398,7 +398,6 @@ class Bundler::Thor
398
398
  # the namespace should be displayed as arguments.
399
399
  #
400
400
  def banner(command, namespace = nil, subcommand = false)
401
- $thor_runner ||= false
402
401
  command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage|
403
402
  "#{basename} #{formatted_usage}"
404
403
  end.join("\n")
@@ -219,7 +219,7 @@ class Bundler::Thor
219
219
 
220
220
  contents = if is_uri
221
221
  require "open-uri"
222
- open(path, "Accept" => "application/x-thor-template", &:read)
222
+ URI.open(path, "Accept" => "application/x-thor-template", &:read)
223
223
  else
224
224
  open(path, &:read)
225
225
  end
@@ -251,7 +251,8 @@ class Bundler::Thor
251
251
  # path<String>:: path of the file to be changed
252
252
  # flag<Regexp|String>:: the regexp or string to be replaced
253
253
  # replacement<String>:: the replacement, can be also given as a block
254
- # config<Hash>:: give :verbose => false to not log the status.
254
+ # config<Hash>:: give :verbose => false to not log the status, and
255
+ # :force => true, to force the replacement regardles of runner behavior.
255
256
  #
256
257
  # ==== Example
257
258
  #
@@ -262,9 +263,10 @@ class Bundler::Thor
262
263
  # end
263
264
  #
264
265
  def gsub_file(path, flag, *args, &block)
265
- return unless behavior == :invoke
266
266
  config = args.last.is_a?(Hash) ? args.pop : {}
267
267
 
268
+ return unless behavior == :invoke || config.fetch(:force, false)
269
+
268
270
  path = File.expand_path(path, destination_root)
269
271
  say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
270
272
 
@@ -1,5 +1,5 @@
1
1
  class Bundler::Thor
2
- Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable)
2
+ Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
3
3
  # In order to support versions of Ruby that don't have keyword
4
4
  # arguments, we need our own spell checker class that doesn't take key
5
5
  # words. Even though this code wouldn't be hit because of the check
@@ -30,7 +30,11 @@ class Bundler::Thor
30
30
 
31
31
  arguments.each do |argument|
32
32
  if !argument.default.nil?
33
- @assigns[argument.human_name] = argument.default
33
+ begin
34
+ @assigns[argument.human_name] = argument.default.dup
35
+ rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
36
+ @assigns[argument.human_name] = argument.default
37
+ end
34
38
  elsif argument.required?
35
39
  @non_assigned_required << argument
36
40
  end
@@ -133,15 +133,16 @@ class Bundler::Thor
133
133
 
134
134
  protected
135
135
 
136
- def assign_result!(option, result)
137
- if option.repeatable && option.type == :hash
138
- (@assigns[option.human_name] ||= {}).merge!(result)
139
- elsif option.repeatable
140
- (@assigns[option.human_name] ||= []) << result
141
- else
142
- @assigns[option.human_name] = result
136
+ def assign_result!(option, result)
137
+ if option.repeatable && option.type == :hash
138
+ (@assigns[option.human_name] ||= {}).merge!(result)
139
+ elsif option.repeatable
140
+ (@assigns[option.human_name] ||= []) << result
141
+ else
142
+ @assigns[option.human_name] = result
143
+ end
143
144
  end
144
- end
145
+
145
146
  # Check if the current value in peek is a registered switch.
146
147
  #
147
148
  # Two booleans are returned. The first is true if the current value
@@ -94,6 +94,8 @@ class Bundler::Thor
94
94
  # say("I know you knew that.")
95
95
  #
96
96
  def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
97
+ return if quiet?
98
+
97
99
  buffer = prepare_message(message, *color)
98
100
  buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
99
101
 
@@ -230,8 +232,9 @@ class Bundler::Thor
230
232
  paras = message.split("\n\n")
231
233
 
232
234
  paras.map! do |unwrapped|
233
- counter = 0
234
- unwrapped.split(" ").inject do |memo, word|
235
+ words = unwrapped.split(" ")
236
+ counter = words.first.length
237
+ words.inject do |memo, word|
235
238
  word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
236
239
  counter = 0 if word.include? "\n"
237
240
  if (counter + word.length + 1) < width
@@ -97,7 +97,11 @@ class Bundler::Thor
97
97
  protected
98
98
 
99
99
  def can_display_colors?
100
- stdout.tty? && !are_colors_disabled?
100
+ are_colors_supported? && !are_colors_disabled?
101
+ end
102
+
103
+ def are_colors_supported?
104
+ stdout.tty? && ENV["TERM"] != "dumb"
101
105
  end
102
106
 
103
107
  def are_colors_disabled?
@@ -1,3 +1,3 @@
1
1
  class Bundler::Thor
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.7".freeze
4
+ VERSION = "2.2.12".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.7
4
+ version: 2.2.12
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-01-27 00:00:00.000000000 Z
25
+ date: 2021-03-01 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
@@ -211,6 +211,7 @@ files:
211
211
  - lib/bundler/templates/Executable.standalone
212
212
  - lib/bundler/templates/Gemfile
213
213
  - lib/bundler/templates/gems.rb
214
+ - lib/bundler/templates/newgem/CHANGELOG.md.tt
214
215
  - lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
215
216
  - lib/bundler/templates/newgem/Gemfile.tt
216
217
  - lib/bundler/templates/newgem/LICENSE.txt.tt
@@ -351,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
352
  - !ruby/object:Gem::Version
352
353
  version: 2.5.2
353
354
  requirements: []
354
- rubygems_version: 3.2.7
355
+ rubygems_version: 3.2.12
355
356
  signing_key:
356
357
  specification_version: 4
357
358
  summary: The best way to manage your application's dependencies