bundler 2.1.0 → 2.2.0.rc.1

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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +832 -738
  3. data/README.md +6 -8
  4. data/bundler.gemspec +3 -3
  5. data/exe/bundle +3 -0
  6. data/lib/bundler.rb +15 -4
  7. data/lib/bundler/build_metadata.rb +2 -2
  8. data/lib/bundler/cli.rb +32 -11
  9. data/lib/bundler/cli/console.rb +1 -1
  10. data/lib/bundler/cli/exec.rb +3 -12
  11. data/lib/bundler/cli/gem.rb +83 -10
  12. data/lib/bundler/cli/info.rb +13 -3
  13. data/lib/bundler/cli/init.rb +1 -1
  14. data/lib/bundler/cli/install.rb +8 -16
  15. data/lib/bundler/cli/issue.rb +2 -2
  16. data/lib/bundler/cli/list.rb +11 -9
  17. data/lib/bundler/cli/outdated.rb +88 -65
  18. data/lib/bundler/cli/plugin.rb +10 -0
  19. data/lib/bundler/cli/pristine.rb +5 -0
  20. data/lib/bundler/definition.rb +32 -32
  21. data/lib/bundler/dependency.rb +0 -9
  22. data/lib/bundler/dsl.rb +1 -5
  23. data/lib/bundler/environment_preserver.rb +26 -2
  24. data/lib/bundler/errors.rb +1 -0
  25. data/lib/bundler/feature_flag.rb +0 -2
  26. data/lib/bundler/fetcher.rb +1 -0
  27. data/lib/bundler/friendly_errors.rb +4 -10
  28. data/lib/bundler/gem_helper.rb +18 -12
  29. data/lib/bundler/gem_version_promoter.rb +1 -1
  30. data/lib/bundler/injector.rb +14 -3
  31. data/lib/bundler/inline.rb +2 -2
  32. data/lib/bundler/installer.rb +29 -28
  33. data/lib/bundler/installer/gem_installer.rb +2 -2
  34. data/lib/bundler/installer/parallel_installer.rb +9 -9
  35. data/lib/bundler/lazy_specification.rb +16 -3
  36. data/lib/bundler/plugin.rb +26 -0
  37. data/lib/bundler/plugin/index.rb +9 -0
  38. data/lib/bundler/psyched_yaml.rb +0 -15
  39. data/lib/bundler/remote_specification.rb +4 -1
  40. data/lib/bundler/resolver.rb +31 -8
  41. data/lib/bundler/resolver/spec_group.rb +26 -5
  42. data/lib/bundler/rubygems_ext.rb +7 -8
  43. data/lib/bundler/rubygems_gem_installer.rb +1 -7
  44. data/lib/bundler/rubygems_integration.rb +13 -48
  45. data/lib/bundler/runtime.rb +2 -12
  46. data/lib/bundler/settings.rb +0 -3
  47. data/lib/bundler/setup.rb +5 -0
  48. data/lib/bundler/shared_helpers.rb +1 -1
  49. data/lib/bundler/source/git.rb +4 -4
  50. data/lib/bundler/source/git/git_proxy.rb +53 -58
  51. data/lib/bundler/source/path.rb +5 -1
  52. data/lib/bundler/source/path/installer.rb +7 -9
  53. data/lib/bundler/source/rubygems.rb +11 -14
  54. data/lib/bundler/stub_specification.rb +16 -4
  55. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  56. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  57. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  58. data/lib/bundler/templates/newgem/bin/console.tt +2 -0
  59. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  60. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  61. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -0
  62. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  63. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +2 -0
  64. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  65. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -4
  66. data/lib/bundler/templates/newgem/rubocop.yml.tt +10 -0
  67. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  68. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -0
  69. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  70. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  71. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  72. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  73. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +72 -208
  74. data/lib/bundler/vendor/thor/lib/thor.rb +0 -7
  75. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  76. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  77. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  78. data/lib/bundler/version.rb +1 -1
  79. data/man/bundle-add.1 +1 -1
  80. data/man/bundle-add.1.txt +15 -15
  81. data/man/bundle-binstubs.1 +1 -1
  82. data/man/bundle-binstubs.1.txt +10 -10
  83. data/man/bundle-cache.1 +1 -1
  84. data/man/bundle-cache.1.txt +15 -15
  85. data/man/bundle-check.1 +1 -1
  86. data/man/bundle-check.1.txt +8 -8
  87. data/man/bundle-clean.1 +1 -1
  88. data/man/bundle-clean.1.txt +6 -6
  89. data/man/bundle-config.1 +3 -9
  90. data/man/bundle-config.1.txt +271 -272
  91. data/man/bundle-config.ronn +5 -9
  92. data/man/bundle-doctor.1 +1 -1
  93. data/man/bundle-doctor.1.txt +9 -9
  94. data/man/bundle-exec.1 +1 -1
  95. data/man/bundle-exec.1.txt +84 -81
  96. data/man/bundle-gem.1 +25 -3
  97. data/man/bundle-gem.1.txt +65 -39
  98. data/man/bundle-gem.ronn +30 -7
  99. data/man/bundle-info.1 +1 -1
  100. data/man/bundle-info.1.txt +2 -2
  101. data/man/bundle-init.1 +1 -1
  102. data/man/bundle-init.1.txt +9 -9
  103. data/man/bundle-inject.1 +1 -1
  104. data/man/bundle-inject.1.txt +4 -4
  105. data/man/bundle-install.1 +1 -1
  106. data/man/bundle-install.1.txt +169 -169
  107. data/man/bundle-list.1 +7 -7
  108. data/man/bundle-list.1.txt +12 -11
  109. data/man/bundle-list.ronn +6 -6
  110. data/man/bundle-lock.1 +1 -1
  111. data/man/bundle-lock.1.txt +28 -28
  112. data/man/bundle-open.1 +1 -1
  113. data/man/bundle-open.1.txt +3 -3
  114. data/man/bundle-outdated.1 +1 -1
  115. data/man/bundle-outdated.1.txt +34 -34
  116. data/man/bundle-platform.1 +1 -1
  117. data/man/bundle-platform.1.txt +16 -16
  118. data/man/bundle-pristine.1 +1 -1
  119. data/man/bundle-pristine.1.txt +8 -8
  120. data/man/bundle-remove.1 +1 -1
  121. data/man/bundle-remove.1.txt +9 -9
  122. data/man/bundle-show.1 +1 -1
  123. data/man/bundle-show.1.txt +8 -8
  124. data/man/bundle-update.1 +1 -1
  125. data/man/bundle-update.1.txt +149 -148
  126. data/man/bundle-viz.1 +1 -1
  127. data/man/bundle-viz.1.txt +11 -11
  128. data/man/bundle.1 +1 -1
  129. data/man/bundle.1.txt +31 -31
  130. data/man/gemfile.5 +1 -1
  131. data/man/gemfile.5.txt +218 -216
  132. metadata +14 -8
@@ -74,15 +74,6 @@ module Bundler
74
74
  :x64_mingw_26 => Gem::Platform::X64_MINGW,
75
75
  }.freeze
76
76
 
77
- REVERSE_PLATFORM_MAP = {}.tap do |reverse_platform_map|
78
- PLATFORM_MAP.each do |key, value|
79
- reverse_platform_map[value] ||= []
80
- reverse_platform_map[value] << key
81
- end
82
-
83
- reverse_platform_map.each {|_, platforms| platforms.freeze }
84
- end.freeze
85
-
86
77
  def initialize(name, version, options = {}, &blk)
87
78
  type = options["type"] || :runtime
88
79
  super(name, version, type)
@@ -75,8 +75,7 @@ module Bundler
75
75
 
76
76
  @gemspecs << spec
77
77
 
78
- gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
79
- gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
78
+ gem spec.name, :name => spec.name, :path => path, :glob => glob
80
79
 
81
80
  group(development_group) do
82
81
  spec.development_dependencies.each do |dep|
@@ -223,7 +222,6 @@ module Bundler
223
222
 
224
223
  def github(repo, options = {})
225
224
  raise ArgumentError, "GitHub sources require a block" unless block_given?
226
- raise DeprecatedError, "The #github method has been removed" if Bundler.feature_flag.skip_default_git_sources?
227
225
  github_uri = @git_sources["github"].call(repo)
228
226
  git_options = normalize_hash(options).merge("uri" => github_uri)
229
227
  git_source = @sources.add_git_source(git_options)
@@ -284,8 +282,6 @@ module Bundler
284
282
  private
285
283
 
286
284
  def add_git_sources
287
- return if Bundler.feature_flag.skip_default_git_sources?
288
-
289
285
  git_source(:github) do |repo_name|
290
286
  warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
291
287
  "https://github.com/#{repo_name}.git"
@@ -17,14 +17,38 @@ module Bundler
17
17
  ].map(&:freeze).freeze
18
18
  BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze
19
19
 
20
- # @param env [ENV]
20
+ def self.from_env
21
+ new(env_to_hash(ENV), BUNDLER_KEYS)
22
+ end
23
+
24
+ def self.env_to_hash(env)
25
+ to_hash = env.to_hash
26
+ return to_hash unless Gem.win_platform?
27
+
28
+ to_hash.each_with_object({}) {|(k,v), a| a[k.upcase] = v }
29
+ end
30
+
31
+ # @param env [Hash]
21
32
  # @param keys [Array<String>]
22
33
  def initialize(env, keys)
23
- @original = env.to_hash
34
+ @original = env
24
35
  @keys = keys
25
36
  @prefix = BUNDLER_PREFIX
26
37
  end
27
38
 
39
+ # Replaces `ENV` with the bundler environment variables backed up
40
+ def replace_with_backup
41
+ ENV.replace(backup) unless Gem.win_platform?
42
+
43
+ # Fallback logic for Windows below to workaround
44
+ # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all
45
+ # supported rubies include the fix for that.
46
+
47
+ ENV.clear
48
+
49
+ backup.each {|k, v| ENV[k] = v }
50
+ end
51
+
28
52
  # @return [Hash]
29
53
  def backup
30
54
  env = @original.clone
@@ -56,6 +56,7 @@ module Bundler
56
56
  class SudoNotPermittedError < BundlerError; status_code(30); end
57
57
  class ThreadCreationError < BundlerError; status_code(33); end
58
58
  class APIResponseMismatchError < BundlerError; status_code(34); end
59
+ class APIResponseInvalidDependenciesError < BundlerError; status_code(35); end
59
60
  class GemfileEvalError < GemfileError; end
60
61
  class MarshalError < StandardError; end
61
62
 
@@ -30,7 +30,6 @@ module Bundler
30
30
  settings_flag(:allow_bundler_dependency_conflicts) { bundler_3_mode? }
31
31
  settings_flag(:allow_offline_install) { bundler_3_mode? }
32
32
  settings_flag(:auto_clean_without_path) { bundler_3_mode? }
33
- settings_flag(:auto_config_jobs) { bundler_3_mode? }
34
33
  settings_flag(:cache_all) { bundler_3_mode? }
35
34
  settings_flag(:default_install_uses_path) { bundler_3_mode? }
36
35
  settings_flag(:deployment_means_frozen) { bundler_3_mode? }
@@ -42,7 +41,6 @@ module Bundler
42
41
  settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
43
42
  settings_flag(:print_only_version_number) { bundler_3_mode? }
44
43
  settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
45
- settings_flag(:skip_default_git_sources) { bundler_3_mode? }
46
44
  settings_flag(:specific_platform) { bundler_3_mode? }
47
45
  settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
48
46
  settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
@@ -229,6 +229,7 @@ module Bundler
229
229
  "BUILDBOX" => "buildbox",
230
230
  "GO_SERVER_URL" => "go",
231
231
  "SNAP_CI" => "snap",
232
+ "GITLAB_CI" => "gitlab",
232
233
  "CI_NAME" => ENV["CI_NAME"],
233
234
  "CI" => "ci",
234
235
  }
@@ -23,13 +23,7 @@ module Bundler
23
23
  Bundler.ui.error error.message
24
24
  when LoadError
25
25
  raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
26
- Bundler.ui.error "\nCould not load OpenSSL."
27
- Bundler.ui.warn <<-WARN, :wrap => true
28
- You must recompile Ruby with OpenSSL support or change the sources in your \
29
- Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL \
30
- using RVM are available at https://rvm.io/packages/openssl.
31
- WARN
32
- Bundler.ui.trace error
26
+ Bundler.ui.error "\nCould not load OpenSSL. #{error.class}: #{error}\n#{error.backtrace.join("\n ")}"
33
27
  when Interrupt
34
28
  Bundler.ui.error "\nQuitting..."
35
29
  Bundler.ui.trace error
@@ -82,7 +76,7 @@ module Bundler
82
76
 
83
77
  I tried...
84
78
 
85
- - **Have you read our issues document, https://github.com/bundler/bundler/blob/master/doc/contributing/ISSUES.md?**
79
+ - **Have you read our issues document, https://github.com/rubygems/rubygems/blob/master/bundler/doc/contributing/ISSUES.md?**
86
80
 
87
81
  ...
88
82
 
@@ -106,7 +100,7 @@ module Bundler
106
100
  #{issues_url(e)}
107
101
 
108
102
  If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
109
- https://github.com/bundler/bundler/issues/new
103
+ https://github.com/rubygems/rubygems/issues/new?labels=Bundler
110
104
  EOS
111
105
  end
112
106
 
@@ -114,7 +108,7 @@ module Bundler
114
108
  message = exception.message.lines.first.tr(":", " ").chomp
115
109
  message = message.split("-").first if exception.is_a?(Errno)
116
110
  require "cgi"
117
- "https://github.com/bundler/bundler/search?q=" \
111
+ "https://github.com/rubygems/rubygems/search?q=" \
118
112
  "#{CGI.escape(message)}&type=Issues"
119
113
  end
120
114
  end
@@ -15,6 +15,10 @@ module Bundler
15
15
  new(opts[:dir], opts[:name]).install
16
16
  end
17
17
 
18
+ def tag_prefix=(prefix)
19
+ instance.tag_prefix = prefix
20
+ end
21
+
18
22
  def gemspec(&block)
19
23
  gemspec = instance.gemspec
20
24
  block.call(gemspec) if block
@@ -24,12 +28,15 @@ module Bundler
24
28
 
25
29
  attr_reader :spec_path, :base, :gemspec
26
30
 
31
+ attr_writer :tag_prefix
32
+
27
33
  def initialize(base = nil, name = nil)
28
- @base = (base ||= SharedHelpers.pwd)
29
- gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
34
+ @base = File.expand_path(base || SharedHelpers.pwd)
35
+ gemspecs = name ? [File.join(@base, "#{name}.gemspec")] : Dir[File.join(@base, "{,*}.gemspec")]
30
36
  raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
31
37
  @spec_path = gemspecs.first
32
38
  @gemspec = Bundler.load_gemspec(@spec_path)
39
+ @tag_prefix = ""
33
40
  end
34
41
 
35
42
  def install
@@ -73,7 +80,7 @@ module Bundler
73
80
 
74
81
  def build_gem
75
82
  file_name = nil
76
- sh("#{gem_command} build -V #{spec_path}".shellsplit) do
83
+ sh([*gem_command, "build", "-V", spec_path]) do
77
84
  file_name = File.basename(built_gem_path)
78
85
  SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) }
79
86
  FileUtils.mv(built_gem_path, "pkg")
@@ -84,9 +91,9 @@ module Bundler
84
91
 
85
92
  def install_gem(built_gem_path = nil, local = false)
86
93
  built_gem_path ||= build_gem
87
- cmd = "#{gem_command} install #{built_gem_path}"
88
- cmd += " --local" if local
89
- _, status = sh_with_status(cmd.shellsplit)
94
+ cmd = [*gem_command, "install", built_gem_path.to_s]
95
+ cmd << "--local" if local
96
+ _, status = sh_with_status(cmd)
90
97
  unless status.success?
91
98
  raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output"
92
99
  end
@@ -96,11 +103,11 @@ module Bundler
96
103
  protected
97
104
 
98
105
  def rubygem_push(path)
99
- cmd = %W[#{gem_command} push #{path}]
106
+ cmd = [*gem_command, "push", path]
100
107
  cmd << "--key" << gem_key if gem_key
101
108
  cmd << "--host" << allowed_push_host if allowed_push_host
102
109
  unless allowed_push_host || Bundler.user_home.join(".gem/credentials").file?
103
- raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
110
+ raise "Your rubygems.org credentials aren't set. Run `gem signin` to set them."
104
111
  end
105
112
  sh_with_input(cmd)
106
113
  Bundler.ui.confirm "Pushed #{name} #{version} to #{gem_push_host}"
@@ -130,9 +137,8 @@ module Bundler
130
137
 
131
138
  def perform_git_push(options = "")
132
139
  cmd = "git push #{options}"
133
- out, status = sh_with_status(cmd)
140
+ out, status = sh_with_status(cmd.shellsplit)
134
141
  return if status.success?
135
- cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
136
142
  raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
137
143
  end
138
144
 
@@ -169,7 +175,7 @@ module Bundler
169
175
  end
170
176
 
171
177
  def version_tag
172
- "v#{version}"
178
+ "#{@tag_prefix}v#{version}"
173
179
  end
174
180
 
175
181
  def name
@@ -211,7 +217,7 @@ module Bundler
211
217
  end
212
218
 
213
219
  def gem_command
214
- ENV["GEM_COMMAND"] ? ENV["GEM_COMMAND"] : "gem"
220
+ ENV["GEM_COMMAND"]&.shellsplit || ["gem"]
215
221
  end
216
222
  end
217
223
  end
@@ -7,7 +7,7 @@ module Bundler
7
7
  # available dependency versions as found in its index, before returning it to
8
8
  # to the resolution engine to select the best version.
9
9
  class GemVersionPromoter
10
- DEBUG = ENV["DEBUG_RESOLVER"]
10
+ DEBUG = ENV["BUNDLER_DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER"]
11
11
 
12
12
  attr_reader :level, :locked_specs, :unlock_gems
13
13
 
@@ -180,10 +180,21 @@ module Bundler
180
180
  def remove_gems_from_gemfile(gems, gemfile_path)
181
181
  patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
182
182
 
183
- # remove lines which match the regex
184
- new_gemfile = IO.readlines(gemfile_path).reject {|line| line.match(patterns) }
183
+ new_gemfile = []
184
+ multiline_removal = false
185
+ IO.readlines(gemfile_path).each do |line|
186
+ if line.match(patterns)
187
+ multiline_removal = line.rstrip.end_with?(",")
188
+ # skip lines which match the regex
189
+ next
190
+ end
191
+
192
+ # skip followup lines until line does not end with ','
193
+ new_gemfile << line unless multiline_removal
194
+ multiline_removal = line.rstrip.end_with?(",") if multiline_removal
195
+ end
185
196
 
186
- # remove lone \n and append them with other strings
197
+ # remove line \n and append them with other strings
187
198
  new_gemfile.each_with_index do |_line, index|
188
199
  if new_gemfile[index + 1] == "\n"
189
200
  new_gemfile[index] += new_gemfile[index + 1]
@@ -58,7 +58,7 @@ def gemfile(install = false, options = {}, &gemfile)
58
58
 
59
59
  Bundler.ui = install ? ui : Bundler::UI::Silent.new
60
60
  if install || definition.missing_specs?
61
- Bundler.settings.temporary(:inline => true, :disable_platform_warnings => true) do
61
+ Bundler.settings.temporary(:inline => true) do
62
62
  installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
63
63
  installer.post_install_messages.each do |name, message|
64
64
  Bundler.ui.info "Post-install message from #{name}:\n#{message}"
@@ -78,7 +78,7 @@ def gemfile(install = false, options = {}, &gemfile)
78
78
  if old_gemfile
79
79
  ENV["BUNDLE_GEMFILE"] = old_gemfile
80
80
  else
81
- ENV.delete("BUNDLE_GEMFILE")
81
+ ENV["BUNDLE_GEMFILE"] = ""
82
82
  end
83
83
  end
84
84
  end
@@ -135,12 +135,17 @@ module Bundler
135
135
  next
136
136
  end
137
137
 
138
- File.open(binstub_path, "w", 0o777 & ~File.umask) do |f|
139
- if RUBY_VERSION >= "2.6"
140
- f.puts ERB.new(template, :trim_mode => "-").result(binding)
141
- else
142
- f.puts ERB.new(template, nil, "-").result(binding)
143
- end
138
+ mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
139
+ content = if RUBY_VERSION >= "2.6"
140
+ ERB.new(template, :trim_mode => "-").result(binding)
141
+ else
142
+ ERB.new(template, nil, "-").result(binding)
143
+ end
144
+
145
+ File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
146
+ if Bundler::WINDOWS
147
+ prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
148
+ File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
144
149
  end
145
150
  end
146
151
 
@@ -175,12 +180,18 @@ module Bundler
175
180
  next if executable == "bundle"
176
181
  executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
177
182
  executable_path = executable_path
178
- File.open "#{bin_path}/#{executable}", "w", 0o755 do |f|
179
- if RUBY_VERSION >= "2.6"
180
- f.puts ERB.new(template, :trim_mode => "-").result(binding)
181
- else
182
- f.puts ERB.new(template, nil, "-").result(binding)
183
- end
183
+
184
+ mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
185
+ content = if RUBY_VERSION >= "2.6"
186
+ ERB.new(template, :trim_mode => "-").result(binding)
187
+ else
188
+ ERB.new(template, nil, "-").result(binding)
189
+ end
190
+
191
+ File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
192
+ if Bundler::WINDOWS
193
+ prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
194
+ File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
184
195
  end
185
196
  end
186
197
  end
@@ -202,20 +213,14 @@ module Bundler
202
213
  return jobs
203
214
  end
204
215
 
205
- return 1 unless can_install_in_parallel?
206
-
207
- auto_config_jobs = Bundler.feature_flag.auto_config_jobs?
208
216
  if jobs = Bundler.settings[:jobs]
209
- if auto_config_jobs
210
- jobs
211
- else
212
- [jobs.pred, 1].max
213
- end
214
- elsif auto_config_jobs
215
- processor_count
216
- else
217
- 1
217
+ return jobs
218
218
  end
219
+
220
+ # Parallelization has some issues on Windows, so it's not yet the default
221
+ return 1 if Gem.win_platform?
222
+
223
+ processor_count
219
224
  end
220
225
 
221
226
  def processor_count
@@ -274,10 +279,6 @@ module Bundler
274
279
  end
275
280
  end
276
281
 
277
- def can_install_in_parallel?
278
- true
279
- end
280
-
281
282
  def install_in_parallel(size, standalone, force = false)
282
283
  spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
283
284
  spec_installations.each do |installation|
@@ -19,11 +19,11 @@ module Bundler
19
19
  Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
20
20
  generate_executable_stubs
21
21
  return true, post_install_message
22
- rescue Bundler::InstallHookError, Bundler::SecurityError, APIResponseMismatchError
22
+ rescue Bundler::InstallHookError, Bundler::SecurityError, Bundler::APIResponseMismatchError
23
23
  raise
24
24
  rescue Errno::ENOSPC
25
25
  return false, out_of_space_message
26
- rescue StandardError => e
26
+ rescue Bundler::BundlerError, Gem::InstallError, Bundler::APIResponseInvalidDependenciesError => e
27
27
  return false, specific_failure_message(e)
28
28
  end
29
29
 
@@ -99,7 +99,7 @@ module Bundler
99
99
  install_serially
100
100
  end
101
101
 
102
- handle_error if @specs.any?(&:failed?)
102
+ handle_error if failed_specs.any?
103
103
  @specs
104
104
  ensure
105
105
  worker_pool && worker_pool.stop
@@ -132,6 +132,10 @@ module Bundler
132
132
 
133
133
  private
134
134
 
135
+ def failed_specs
136
+ @specs.select(&:failed?)
137
+ end
138
+
135
139
  def install_with_worker
136
140
  enqueue_specs
137
141
  process_specs until finished_installing?
@@ -156,17 +160,13 @@ module Bundler
156
160
  gem_installer = Bundler::GemInstaller.new(
157
161
  spec_install.spec, @installer, @standalone, worker_num, @force
158
162
  )
159
- success, message = begin
160
- gem_installer.install_from_spec
161
- rescue RuntimeError => e
162
- raise e, "#{e}\n\n#{require_tree_for_spec(spec_install.spec)}"
163
- end
163
+ success, message = gem_installer.install_from_spec
164
164
  if success
165
165
  spec_install.state = :installed
166
166
  spec_install.post_install_message = message unless message.nil?
167
167
  else
168
- spec_install.state = :failed
169
168
  spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
169
+ spec_install.state = :failed
170
170
  end
171
171
  Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install)
172
172
  spec_install
@@ -190,11 +190,11 @@ module Bundler
190
190
  end
191
191
 
192
192
  def handle_error
193
- errors = @specs.select(&:failed?).map(&:error)
193
+ errors = failed_specs.map(&:error)
194
194
  if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
195
195
  raise exception
196
196
  end
197
- raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
197
+ raise Bundler::InstallError, errors.join("\n\n")
198
198
  end
199
199
 
200
200
  def require_tree_for_spec(spec)