bundler 2.3.14 → 2.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64817a3760b34f35e53aea5e788049373a97d786d75921aa67fbd6a676eb5bcb
4
- data.tar.gz: 584ecd0d1b0a738a7de9e95f9cdbfef0ca3e8ac00f2a928fd5e23b4777b073e7
3
+ metadata.gz: 364d4bc2c2c1f342aa034417b9e30074317878931bf34e90ddf6c42d3ae539c2
4
+ data.tar.gz: dad782afd5246e703b67d004c7282a89132f0ebe699d8e8306387fb8db179193
5
5
  SHA512:
6
- metadata.gz: 5397e12203b667c6870f7ee605c7ad2b43c31af5716c45c2376577cc5a2a2be93b1e48ae36eab6e23f7b49e1942a21d9e8c3c04d2ea8d18606fd3e4ea2b4f1ac
7
- data.tar.gz: 1db7fcf817b82739a0b6867e532705fec37e82b571103b9e2b688374f208f4d5ce9e9daad3bdd0062abddfb9025190953535c100c3365c0b3109e993efdb1ea6
6
+ metadata.gz: 463cc7534f4164ae4d2e4c67d1ed57dcc9a40494c496f0b06e11ac8f2b3599ea0dbc74be8772a98abb2d09c119db2da8f1d85cde6bafe83319051de3e24a46f2
7
+ data.tar.gz: 61b997e77634dc3a7d812adb805f899bb8bbae48bd25aad2884906c818d21853e76fd0db8bfbd95ee79689c25567e346e9c468fbe1321768c2614518f0e78356
data/CHANGELOG.md CHANGED
@@ -1,3 +1,49 @@
1
+ # 2.3.17 (June 29, 2022)
2
+
3
+ ## Enhancements:
4
+
5
+ - Add support for platform `:x64_mingw` to correctly lookup "x64-mingw-ucrt" [#5649](https://github.com/rubygems/rubygems/pull/5649)
6
+ - Fix some errors being printed twice in `--verbose` mode [#5654](https://github.com/rubygems/rubygems/pull/5654)
7
+ - Fix extension paths in generated standalone script [#5632](https://github.com/rubygems/rubygems/pull/5632)
8
+
9
+ ## Bug fixes:
10
+
11
+ - Raise if ruby platform is forced and there are no ruby variants [#5495](https://github.com/rubygems/rubygems/pull/5495)
12
+ - Fix `bundle package --no-install` no longer skipping install [#5639](https://github.com/rubygems/rubygems/pull/5639)
13
+
14
+ ## Performance:
15
+
16
+ - Improve performance of `Bundler::SpecSet#for` by using hash lookup of handled deps [#5537](https://github.com/rubygems/rubygems/pull/5537)
17
+
18
+ ## Documentation:
19
+
20
+ - Fix formatting issue in `bundle add` man page [#5642](https://github.com/rubygems/rubygems/pull/5642)
21
+
22
+ # 2.3.16 (June 15, 2022)
23
+
24
+ ## Performance:
25
+
26
+ - Improve performance of installing gems from gem server sources [#5614](https://github.com/rubygems/rubygems/pull/5614)
27
+
28
+ # 2.3.15 (June 1, 2022)
29
+
30
+ ## Enhancements:
31
+
32
+ - Show better error when previous installation fails to be removed [#5564](https://github.com/rubygems/rubygems/pull/5564)
33
+ - Show exception cause in bug report template [#5563](https://github.com/rubygems/rubygems/pull/5563)
34
+
35
+ ## Bug fixes:
36
+
37
+ - Fix `bundle remove` by invalidating cached `Bundle.definition` [#5443](https://github.com/rubygems/rubygems/pull/5443)
38
+ - Fix generated standalone script when it includes default gems [#5586](https://github.com/rubygems/rubygems/pull/5586)
39
+ - Skip duplicated dependency warning for gemspec dev deps [#5587](https://github.com/rubygems/rubygems/pull/5587)
40
+ - Give better conflict resolution advice [#5581](https://github.com/rubygems/rubygems/pull/5581)
41
+ - Fix crash when commenting out a mirror in configuration [#5576](https://github.com/rubygems/rubygems/pull/5576)
42
+ - Fix crash when installing gems with symlinks [#5570](https://github.com/rubygems/rubygems/pull/5570)
43
+ - Ignore `Errno::EROFS` errors when creating `bundler.lock` [#5580](https://github.com/rubygems/rubygems/pull/5580)
44
+ - Ignore `Errno::EPERM` errors when creating `bundler.lock` [#5579](https://github.com/rubygems/rubygems/pull/5579)
45
+ - Fix crash when printing resolution conflicts on metadata requirements [#5562](https://github.com/rubygems/rubygems/pull/5562)
46
+
1
47
  # 2.3.14 (May 18, 2022)
2
48
 
3
49
  ## Bug fixes:
@@ -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 = "2022-05-18".freeze
8
- @git_commit_sha = "467ad58a7c".freeze
7
+ @built_at = "2022-06-29".freeze
8
+ @git_commit_sha = "539b20c172".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -78,7 +78,7 @@ module Bundler
78
78
  end
79
79
 
80
80
  def x64_mingw?
81
- Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
81
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os.start_with?("mingw") && Bundler.local_platform.cpu == "x64"
82
82
  end
83
83
 
84
84
  (KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
@@ -255,20 +255,18 @@ module Bundler
255
255
  #
256
256
  # @return [SpecSet] resolved dependencies
257
257
  def resolve
258
- @resolve ||= begin
259
- if Bundler.frozen_bundle?
260
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
261
- @locked_specs
262
- elsif !unlocking? && nothing_changed?
263
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
264
- SpecSet.new(filter_specs(@locked_specs, @dependencies.select {|dep| @locked_specs[dep].any? }))
265
- else
266
- last_resolve = converge_locked_specs
267
- # Run a resolve against the locally available gems
268
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
269
- expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
270
- Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
271
- end
258
+ @resolve ||= if Bundler.frozen_bundle?
259
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
260
+ @locked_specs
261
+ elsif !unlocking? && nothing_changed?
262
+ Bundler.ui.debug("Found no changes, using resolution from the lockfile")
263
+ SpecSet.new(filter_specs(@locked_specs, @dependencies.select {|dep| @locked_specs[dep].any? }))
264
+ else
265
+ last_resolve = converge_locked_specs
266
+ # Run a resolve against the locally available gems
267
+ Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
268
+ expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
269
+ Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
272
270
  end
273
271
  end
274
272
 
@@ -735,12 +733,10 @@ module Bundler
735
733
  end
736
734
 
737
735
  def metadata_dependencies
738
- @metadata_dependencies ||= begin
739
- [
740
- Dependency.new("Ruby\0", RubyVersion.system.gem_version),
741
- Dependency.new("RubyGems\0", Gem::VERSION),
742
- ]
743
- end
736
+ @metadata_dependencies ||= [
737
+ Dependency.new("Ruby\0", RubyVersion.system.gem_version),
738
+ Dependency.new("RubyGems\0", Gem::VERSION),
739
+ ]
744
740
  end
745
741
 
746
742
  def expand_dependencies(dependencies, remote = false)
@@ -9,6 +9,7 @@ module Bundler
9
9
  attr_reader :autorequire
10
10
  attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref
11
11
 
12
+ # rubocop:disable Naming/VariableNumber
12
13
  PLATFORM_MAP = {
13
14
  :ruby => Gem::Platform::RUBY,
14
15
  :ruby_18 => Gem::Platform::RUBY,
@@ -91,6 +92,7 @@ module Bundler
91
92
  :x64_mingw_30 => Gem::Platform::X64_MINGW,
92
93
  :x64_mingw_31 => Gem::Platform::X64_MINGW,
93
94
  }.freeze
95
+ # rubocop:enable Naming/VariableNumber
94
96
 
95
97
  def initialize(name, version, options = {}, &blk)
96
98
  type = options["type"] || :runtime
@@ -120,7 +122,7 @@ module Bundler
120
122
  end
121
123
 
122
124
  def expanded_platforms
123
- @expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq
125
+ @expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.flatten.uniq
124
126
  end
125
127
 
126
128
  def should_include?
data/lib/bundler/dsl.rb CHANGED
@@ -124,19 +124,17 @@ module Bundler
124
124
  raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
125
125
  "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
126
126
  "#{update_prompt}"
127
+ elsif current.source != dep.source
128
+ return if dep.type == :development
129
+ raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
130
+ "You specified that #{dep.name} (#{dep.requirement}) should come from " \
131
+ "#{current.source || "an unspecified source"} and #{dep.source}\n"
127
132
  else
128
133
  Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
129
134
  "You should probably keep only one of them.\n" \
130
135
  "Remove any duplicate entries and specify the gem only once.\n" \
131
136
  "While it's not a problem now, it could cause errors if you change the version of one of them later."
132
137
  end
133
-
134
- if current.source != dep.source
135
- return if dep.type == :development
136
- raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
137
- "You specified that #{dep.name} (#{dep.requirement}) should come from " \
138
- "#{current.source || "an unspecified source"} and #{dep.source}\n"
139
- end
140
138
  end
141
139
  end
142
140
 
@@ -513,9 +511,7 @@ module Bundler
513
511
  # be raised.
514
512
  #
515
513
  def contents
516
- @contents ||= begin
517
- dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
518
- end
514
+ @contents ||= dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
519
515
  end
520
516
 
521
517
  # The message of the exception reports the content of podspec for the
@@ -41,12 +41,14 @@ module Bundler
41
41
  class GemspecError < BundlerError; status_code(14); end
42
42
  class InvalidOption < BundlerError; status_code(15); end
43
43
  class ProductionError < BundlerError; status_code(16); end
44
+
44
45
  class HTTPError < BundlerError
45
46
  status_code(17)
46
47
  def filter_uri(uri)
47
48
  URICredentialsFilter.credential_filtered_uri(uri)
48
49
  end
49
50
  end
51
+
50
52
  class RubyVersionMismatch < BundlerError; status_code(18); end
51
53
  class SecurityError < BundlerError; status_code(19); end
52
54
  class LockfileError < BundlerError; status_code(20); end
@@ -79,10 +81,6 @@ module Bundler
79
81
  case @permission_type
80
82
  when :create
81
83
  "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
82
- when :delete
83
- permissions = "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
84
- permissions += ", and the same thing for all subdirectories inside #{@path}" if File.directory?(@path)
85
- permissions
86
84
  else
87
85
  "#{@permission_type} permissions for that path"
88
86
  end
@@ -172,4 +170,16 @@ module Bundler
172
170
 
173
171
  status_code(32)
174
172
  end
173
+
174
+ class DirectoryRemovalError < BundlerError
175
+ def initialize(orig_exception, msg)
176
+ full_message = "#{msg}.\n" \
177
+ "The underlying error was #{orig_exception.class}: #{orig_exception.message}, with backtrace:\n" \
178
+ " #{orig_exception.backtrace.join("\n ")}\n\n" \
179
+ "Bundler Error Backtrace:"
180
+ super(full_message)
181
+ end
182
+
183
+ status_code(36)
184
+ end
175
185
  end
@@ -19,14 +19,12 @@ module Bundler
19
19
  end
20
20
 
21
21
  def fetch_uri
22
- @fetch_uri ||= begin
23
- if remote_uri.host == "rubygems.org"
24
- uri = remote_uri.dup
25
- uri.host = "index.rubygems.org"
26
- uri
27
- else
28
- remote_uri
29
- end
22
+ @fetch_uri ||= if remote_uri.host == "rubygems.org"
23
+ uri = remote_uri.dup
24
+ uri.host = "index.rubygems.org"
25
+ uri
26
+ else
27
+ remote_uri
30
28
  end
31
29
  end
32
30
 
@@ -20,6 +20,7 @@ module Bundler
20
20
  class TooManyRequestsError < HTTPError; end
21
21
  # This error is raised if the API returns a 413 (only printed in verbose)
22
22
  class FallbackError < HTTPError; end
23
+
23
24
  # This is the error raised if OpenSSL fails the cert verification
24
25
  class CertificateFailureError < HTTPError
25
26
  def initialize(remote_uri)
@@ -33,6 +34,7 @@ module Bundler
33
34
  " sources and change 'https' to 'http'."
34
35
  end
35
36
  end
37
+
36
38
  # This is the error raised when a source is HTTPS and OpenSSL didn't load
37
39
  class SSLError < HTTPError
38
40
  def initialize(msg = nil)
@@ -42,6 +44,7 @@ module Bundler
42
44
  "using RVM are available at rvm.io/packages/openssl."
43
45
  end
44
46
  end
47
+
45
48
  # This error is raised if HTTP authentication is required, but not provided.
46
49
  class AuthenticationRequiredError < HTTPError
47
50
  def initialize(remote_uri)
@@ -52,6 +55,7 @@ module Bundler
52
55
  "or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable"
53
56
  end
54
57
  end
58
+
55
59
  # This error is raised if HTTP authentication is provided, but incorrect.
56
60
  class BadAuthenticationError < HTTPError
57
61
  def initialize(remote_uri)
@@ -29,8 +29,11 @@ module Bundler
29
29
  Bundler.ui.error error.message
30
30
  Bundler.ui.trace error.orig_exception
31
31
  when BundlerError
32
- Bundler.ui.error error.message, :wrap => true
33
- Bundler.ui.trace error
32
+ if Bundler.ui.debug?
33
+ Bundler.ui.trace error
34
+ else
35
+ Bundler.ui.error error.message, :wrap => true
36
+ end
34
37
  when Thor::Error
35
38
  Bundler.ui.error error.message
36
39
  when LoadError
@@ -65,8 +68,7 @@ module Bundler
65
68
  --- ERROR REPORT TEMPLATE -------------------------------------------------------
66
69
 
67
70
  ```
68
- #{e.class}: #{e.message}
69
- #{e.backtrace && e.backtrace.join("\n ").chomp}
71
+ #{exception_message(e)}
70
72
  ```
71
73
 
72
74
  #{Bundler::Env.report}
@@ -85,6 +87,21 @@ module Bundler
85
87
  EOS
86
88
  end
87
89
 
90
+ def exception_message(error)
91
+ message = serialized_exception_for(error)
92
+ cause = error.cause
93
+ return message unless cause
94
+
95
+ message + serialized_exception_for(cause)
96
+ end
97
+
98
+ def serialized_exception_for(e)
99
+ <<-EOS.gsub(/^ {8}/, "")
100
+ #{e.class}: #{e.message}
101
+ #{e.backtrace && e.backtrace.join("\n ").chomp}
102
+ EOS
103
+ end
104
+
88
105
  def issues_url(exception)
89
106
  message = exception.message.lines.first.tr(":", " ").chomp
90
107
  message = message.split("-").first if exception.is_a?(Errno)
@@ -10,6 +10,7 @@ module Bundler
10
10
  [Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
11
11
  [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
12
12
  [Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
13
+ [Gem::Platform.new("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")],
13
14
  [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
14
15
  ].freeze
15
16
 
data/lib/bundler/index.rb CHANGED
@@ -192,11 +192,7 @@ module Bundler
192
192
  specs += base if base
193
193
  found = specs.select do |spec|
194
194
  next true if spec.source.is_a?(Source::Gemspec)
195
- if base # allow all platforms when searching from a lockfile
196
- dependency.matches_spec?(spec)
197
- else
198
- dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
199
- end
195
+ dependency.matches_spec?(spec)
200
196
  end
201
197
 
202
198
  found
@@ -72,6 +72,10 @@ module Bundler
72
72
 
73
73
  deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
74
74
  end
75
+
76
+ # Invalidate the cached Bundler.definition.
77
+ # This prevents e.g. `bundle remove ...` from using outdated information.
78
+ Bundler.reset_paths!
75
79
  end
76
80
 
77
81
  private
@@ -38,12 +38,7 @@ def gemfile(install = false, options = {}, &gemfile)
38
38
  raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
39
39
 
40
40
  begin
41
- old_root = Bundler.method(:root)
42
- bundler_module = class << Bundler; self; end
43
- bundler_module.send(:remove_method, :root)
44
- def Bundler.root
45
- Bundler::SharedHelpers.pwd.expand_path
46
- end
41
+ Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir))
47
42
  old_gemfile = ENV["BUNDLE_GEMFILE"]
48
43
  Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
49
44
 
@@ -71,11 +66,6 @@ def gemfile(install = false, options = {}, &gemfile)
71
66
  runtime.setup.require
72
67
  end
73
68
  ensure
74
- if bundler_module
75
- bundler_module.send(:remove_method, :root)
76
- bundler_module.send(:define_method, :root, old_root)
77
- end
78
-
79
69
  if old_gemfile
80
70
  ENV["BUNDLE_GEMFILE"] = old_gemfile
81
71
  else
@@ -12,6 +12,7 @@ module Bundler
12
12
  end
13
13
  File.open File.join(bundler_path, "setup.rb"), "w" do |file|
14
14
  file.puts "require 'rbconfig'"
15
+ file.puts define_path_helpers
15
16
  file.puts reverse_rubygems_kernel_mixin
16
17
  paths.each do |path|
17
18
  if Pathname.new(path).absolute?
@@ -29,14 +30,20 @@ module Bundler
29
30
  @specs.map do |spec|
30
31
  next if spec.name == "bundler"
31
32
  Array(spec.require_paths).map do |path|
32
- gem_path(path, spec).sub(version_dir, '#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}')
33
+ gem_path(path, spec).
34
+ sub(version_dir, '#{RUBY_ENGINE}/#{Gem.ruby_api_version}').
35
+ sub(extensions_dir, 'extensions/\k<platform>/#{Gem.extension_api_version}')
33
36
  # This is a static string intentionally. It's interpolated at a later time.
34
37
  end
35
38
  end.flatten.compact
36
39
  end
37
40
 
38
41
  def version_dir
39
- "#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
42
+ "#{RUBY_ENGINE}/#{Gem.ruby_api_version}"
43
+ end
44
+
45
+ def extensions_dir
46
+ %r{extensions/(?<platform>[^/]+)/#{Regexp.escape(Gem.extension_api_version)}}
40
47
  end
41
48
 
42
49
  def bundler_path
@@ -55,6 +62,26 @@ module Bundler
55
62
  raise Gem::InvalidSpecificationException.new(error_message)
56
63
  end
57
64
 
65
+ def define_path_helpers
66
+ <<~'END'
67
+ unless defined?(Gem)
68
+ module Gem
69
+ def self.ruby_api_version
70
+ RbConfig::CONFIG["ruby_version"]
71
+ end
72
+
73
+ def self.extension_api_version
74
+ if 'no' == RbConfig::CONFIG['ENABLE_SHARED']
75
+ "#{ruby_api_version}-static"
76
+ else
77
+ ruby_api_version
78
+ end
79
+ end
80
+ end
81
+ end
82
+ END
83
+ end
84
+
58
85
  def reverse_rubygems_kernel_mixin
59
86
  <<~END
60
87
  kernel = (class << ::Kernel; self; end)
@@ -66,7 +66,7 @@ module Bundler
66
66
  # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
67
67
  # information.
68
68
  def run(options)
69
- create_bundle_path
69
+ Bundler.create_bundle_path
70
70
 
71
71
  ProcessLock.lock do
72
72
  if Bundler.frozen_bundle?
@@ -262,15 +262,6 @@ module Bundler
262
262
  end
263
263
  end
264
264
 
265
- def create_bundle_path
266
- SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
267
- Bundler.mkdir_p(p)
268
- end unless Bundler.bundle_path.exist?
269
- rescue Errno::EEXIST
270
- raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
271
- "because a file already exists at that path. Either remove or rename the file so the directory can be created."
272
- end
273
-
274
265
  # returns whether or not a re-resolve was needed
275
266
  def resolve_if_needed(options)
276
267
  if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
@@ -84,7 +84,7 @@ module Bundler
84
84
  else
85
85
  ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version)
86
86
  end
87
- platform_object = Gem::Platform.new(platform)
87
+ platform_object = ruby_platform_materializes_to_ruby_platform? ? Gem::Platform.new(platform) : Gem::Platform.local
88
88
  candidates = source.specs.search(search_object)
89
89
  same_platform_candidates = candidates.select do |spec|
90
90
  MatchPlatform.platforms_match?(spec.platform, platform_object)
@@ -152,7 +152,7 @@ module Bundler
152
152
  # explicitly add a more specific platform.
153
153
  #
154
154
  def ruby_platform_materializes_to_ruby_platform?
155
- !Bundler.most_specific_locked_platform?(Gem::Platform::RUBY) || Bundler.settings[:force_ruby_platform]
155
+ !Bundler.most_specific_locked_platform?(generic_local_platform) || Bundler.settings[:force_ruby_platform]
156
156
  end
157
157
  end
158
158
  end
@@ -41,7 +41,7 @@ Specify version requirements(s) for the added gem\.
41
41
  Specify the group(s) for the added gem\. Multiple groups should be separated by commas\.
42
42
  .
43
43
  .TP
44
- \fB\-\-source\fR, , \fB\-s\fR
44
+ \fB\-\-source\fR, \fB\-s\fR
45
45
  Specify the source for the added gem\.
46
46
  .
47
47
  .TP
@@ -27,7 +27,7 @@ bundle add rails --group "development, test"
27
27
  * `--group`, `-g`:
28
28
  Specify the group(s) for the added gem. Multiple groups should be separated by commas.
29
29
 
30
- * `--source`, , `-s`:
30
+ * `--source`, `-s`:
31
31
  Specify the source for the added gem.
32
32
 
33
33
  * `--require`, `-r`:
@@ -15,7 +15,6 @@ module Bundler
15
15
  return true if Gem::Platform::RUBY == gemspec_platform
16
16
  return true if local_platform == gemspec_platform
17
17
  gemspec_platform = Gem::Platform.new(gemspec_platform)
18
- return true if GemHelpers.generic(gemspec_platform) === local_platform
19
18
  return true if gemspec_platform === local_platform
20
19
 
21
20
  false
@@ -258,7 +258,7 @@ module Bundler
258
258
  @dependencies |= Array(names)
259
259
  end
260
260
 
261
- # Note: Do not override if you don't know what you are doing.
261
+ # NOTE: Do not override if you don't know what you are doing.
262
262
  def can_lock?(spec)
263
263
  spec.source == self
264
264
  end
@@ -285,7 +285,7 @@ module Bundler
285
285
  end
286
286
  alias_method :identifier, :to_s
287
287
 
288
- # Note: Do not override if you don't know what you are doing.
288
+ # NOTE: Do not override if you don't know what you are doing.
289
289
  def include?(other)
290
290
  other == self
291
291
  end
@@ -294,7 +294,7 @@ module Bundler
294
294
  SharedHelpers.digest(:SHA1).hexdigest(uri)
295
295
  end
296
296
 
297
- # Note: Do not override if you don't know what you are doing.
297
+ # NOTE: Do not override if you don't know what you are doing.
298
298
  def gem_install_dir
299
299
  Bundler.install_path
300
300
  end
@@ -12,7 +12,7 @@ module Bundler
12
12
  yield
13
13
  f.flock(File::LOCK_UN)
14
14
  end
15
- rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP
15
+ rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP, Errno::EPERM, Errno::EROFS
16
16
  # In the case the user does not have access to
17
17
  # create the lock file or is using NFS where
18
18
  # locks are not available we skip locking.
@@ -19,13 +19,15 @@ module Bundler
19
19
  # collection of gemspecs is returned. Otherwise, nil is returned.
20
20
  def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
21
21
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
22
- resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
+ metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
23
+ resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
23
24
  result = resolver.start(requirements)
24
- SpecSet.new(SpecSet.new(result).for(requirements.reject {|dep| dep.name.end_with?("\0") }))
25
+ SpecSet.new(SpecSet.new(result).for(regular_requirements))
25
26
  end
26
27
 
27
- def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
28
+ def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
28
29
  @source_requirements = source_requirements
30
+ @metadata_requirements = metadata_requirements
29
31
  @base = base
30
32
  @resolver = Molinillo::Resolver.new(self, self)
31
33
  @search_for = {}
@@ -231,19 +233,17 @@ module Bundler
231
233
  # before dependencies that are unconstrained
232
234
  def amount_constrained(dependency)
233
235
  @amount_constrained ||= {}
234
- @amount_constrained[dependency.name] ||= begin
235
- if (base = @base[dependency.name]) && !base.empty?
236
- dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
237
- else
238
- all = index_for(dependency).search(dependency.name).size
236
+ @amount_constrained[dependency.name] ||= if (base = @base[dependency.name]) && !base.empty?
237
+ dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
238
+ else
239
+ all = index_for(dependency).search(dependency.name).size
239
240
 
240
- if all <= 1
241
- all - 1_000_000
242
- else
243
- search = search_for(dependency)
244
- search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
245
- search - all
246
- end
241
+ if all <= 1
242
+ all - 1_000_000
243
+ else
244
+ search = search_for(dependency)
245
+ search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
246
+ search - all
247
247
  end
248
248
  end
249
249
  end
@@ -284,7 +284,7 @@ module Bundler
284
284
  if specs_matching_requirement.any?
285
285
  specs = specs_matching_requirement
286
286
  matching_part = requirement_label
287
- requirement_label = "#{requirement_label} #{requirement.__platform}"
287
+ requirement_label = "#{requirement_label}' with platform '#{requirement.__platform}"
288
288
  end
289
289
 
290
290
  message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")
@@ -344,8 +344,6 @@ module Bundler
344
344
  trees.sort_by! {|t| t.reverse.map(&:name) }
345
345
  end
346
346
 
347
- metadata_requirements = {}
348
-
349
347
  o << trees.map do |tree|
350
348
  t = "".dup
351
349
  depth = 2
@@ -354,7 +352,6 @@ module Bundler
354
352
  base_tree_name = base_tree.name
355
353
 
356
354
  if base_tree_name.end_with?("\0")
357
- metadata_requirements[base_tree_name] = base_tree
358
355
  t = nil
359
356
  else
360
357
  tree.each do |req|
@@ -393,10 +390,10 @@ module Bundler
393
390
  end
394
391
  end
395
392
  elsif name.end_with?("\0")
396
- o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(metadata_requirements[name])}\n\n)
393
+ o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n)
397
394
  elsif conflict.locked_requirement
398
395
  o << "\n"
399
- o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
396
+ o << %(Deleting your #{name_for_locking_dependency_source} file and running `bundle install` will rebuild your snapshot from scratch, using only\n)
400
397
  o << %(the gems in your Gemfile, which may resolve the conflict.\n)
401
398
  elsif !conflict.existing
402
399
  o << "\n"
@@ -216,11 +216,12 @@ module Gem
216
216
  require "rubygems/platform"
217
217
 
218
218
  class Platform
219
- JAVA = Gem::Platform.new("java") unless defined?(JAVA)
220
- MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
221
- MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
222
- MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
223
- X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
219
+ JAVA = Gem::Platform.new("java")
220
+ MSWIN = Gem::Platform.new("mswin32")
221
+ MSWIN64 = Gem::Platform.new("mswin64")
222
+ MINGW = Gem::Platform.new("x86-mingw32")
223
+ X64_MINGW = [Gem::Platform.new("x64-mingw32"),
224
+ Gem::Platform.new("x64-mingw-ucrt")].freeze
224
225
  end
225
226
 
226
227
  Platform.singleton_class.module_eval do
@@ -90,17 +90,20 @@ module Bundler
90
90
  end
91
91
  end
92
92
 
93
+ def spec
94
+ if Bundler.rubygems.provides?("< 3.3.12") # RubyGems implementation rescues and re-raises errors before 3.3.12 and we don't want that
95
+ @package.spec
96
+ else
97
+ super
98
+ end
99
+ end
100
+
93
101
  private
94
102
 
95
103
  def strict_rm_rf(dir)
96
- # FileUtils.rm_rf should probably rise in case of permission issues like
97
- # `rm -rf` does. However, it fails to delete the folder silently due to
98
- # https://github.com/ruby/fileutils/issues/57. It should probably be fixed
99
- # inside `fileutils` but for now I`m checking whether the folder was
100
- # removed after it completes, and raising otherwise.
101
- FileUtils.rm_rf dir
102
-
103
- raise PermissionError.new(dir, :delete) if File.directory?(dir)
104
+ Bundler.rm_rf dir
105
+ rescue Errno::ENOTEMPTY => e
106
+ raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`")
104
107
  end
105
108
 
106
109
  def validate_bundler_checksum(checksum)
@@ -203,20 +203,9 @@ module Bundler
203
203
  EXT_LOCK
204
204
  end
205
205
 
206
- def spec_from_gem(path, policy = nil)
207
- require "rubygems/security"
208
- require "psych"
209
- gem_from_path(path, security_policies[policy]).spec
210
- rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
211
- if e.is_a?(Gem::Security::Exception) ||
212
- e.message =~ /unknown trust policy|unsigned gem/i ||
213
- e.message =~ /couldn't verify (meta)?data signature/i
214
- raise SecurityError,
215
- "The gem #{File.basename(path, ".gem")} can't be installed because " \
216
- "the security policy didn't allow it, with the message: #{e.message}"
217
- else
218
- raise e
219
- end
206
+ def spec_from_gem(path)
207
+ require "rubygems/package"
208
+ Gem::Package.new(path).spec
220
209
  end
221
210
 
222
211
  def build_gem(gem_dir, spec)
@@ -514,13 +503,6 @@ module Bundler
514
503
  Gem::RemoteFetcher.new(proxy)
515
504
  end
516
505
 
517
- def gem_from_path(path, policy = nil)
518
- require "rubygems/package"
519
- p = Gem::Package.new(path)
520
- p.security_policy = policy if policy
521
- p
522
- end
523
-
524
506
  def build(spec, skip_validation = false)
525
507
  require "rubygems/package"
526
508
  Gem::Package.build(spec, skip_validation)
@@ -487,7 +487,7 @@ module Bundler
487
487
  /ix.freeze
488
488
 
489
489
  def self.key_for(key)
490
- key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
490
+ key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
491
491
  key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
492
492
  "BUNDLE_#{key}"
493
493
  end
@@ -219,13 +219,11 @@ module Bundler
219
219
  # across different projects, this cache will be shared.
220
220
  # When using local git repos, this is set to the local repo.
221
221
  def cache_path
222
- @cache_path ||= begin
223
- if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
224
- Bundler.user_cache
225
- else
226
- Bundler.bundle_path.join("cache", "bundler")
227
- end.join("git", git_scope)
228
- end
222
+ @cache_path ||= if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
223
+ Bundler.user_cache
224
+ else
225
+ Bundler.bundle_path.join("cache", "bundler")
226
+ end.join("git", git_scope)
229
227
  end
230
228
 
231
229
  def app_cache_dirname
@@ -139,13 +139,9 @@ module Bundler
139
139
  force = options[:force]
140
140
  ensure_builtin_gems_cached = options[:ensure_builtin_gems_cached]
141
141
 
142
- if ensure_builtin_gems_cached && spec.default_gem?
143
- if !cached_path(spec)
144
- cached_built_in_gem(spec) unless spec.remote
145
- force = true
146
- else
147
- spec.loaded_from = loaded_from(spec)
148
- end
142
+ if ensure_builtin_gems_cached && spec.default_gem? && !cached_path(spec)
143
+ cached_built_in_gem(spec) unless spec.remote
144
+ force = true
149
145
  end
150
146
 
151
147
  if installed?(spec) && !force
@@ -153,84 +149,92 @@ module Bundler
153
149
  return nil # no post-install message
154
150
  end
155
151
 
156
- # Download the gem to get the spec, because some specs that are returned
157
- # by rubygems.org are broken and wrong.
158
152
  if spec.remote
159
153
  # Check for this spec from other sources
160
- uris = [spec.remote.anonymized_uri]
161
- uris += remotes_for_spec(spec).map(&:anonymized_uri)
162
- uris.uniq!
154
+ uris = [spec.remote, *remotes_for_spec(spec)].map(&:anonymized_uri).uniq
163
155
  Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
164
156
 
165
157
  path = fetch_gem(spec, options[:previous_spec])
166
- begin
167
- s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
168
- spec.__swap__(s)
158
+ else
159
+ path = cached_gem(spec)
160
+ raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
161
+ end
162
+
163
+ return if Bundler.settings[:no_install]
164
+
165
+ if requires_sudo?
166
+ install_path = Bundler.tmp(spec.full_name)
167
+ bin_path = install_path.join("bin")
168
+ else
169
+ install_path = rubygems_dir
170
+ bin_path = Bundler.system_bindir
171
+ end
172
+
173
+ Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
174
+
175
+ require_relative "../rubygems_gem_installer"
176
+
177
+ installer = Bundler::RubyGemsGemInstaller.at(
178
+ path,
179
+ :security_policy => Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]],
180
+ :install_dir => install_path.to_s,
181
+ :bin_dir => bin_path.to_s,
182
+ :ignore_dependencies => true,
183
+ :wrappers => true,
184
+ :env_shebang => true,
185
+ :build_args => options[:build_args],
186
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
187
+ :bundler_extension_cache_path => extension_cache_path(spec)
188
+ )
189
+
190
+ if spec.remote
191
+ s = begin
192
+ installer.spec
169
193
  rescue Gem::Package::FormatError
170
194
  Bundler.rm_rf(path)
171
195
  raise
196
+ rescue Gem::Security::Exception => e
197
+ raise SecurityError,
198
+ "The gem #{File.basename(path, ".gem")} can't be installed because " \
199
+ "the security policy didn't allow it, with the message: #{e.message}"
172
200
  end
201
+
202
+ spec.__swap__(s)
173
203
  end
174
204
 
175
- unless Bundler.settings[:no_install]
176
- message = "Installing #{version_message(spec, options[:previous_spec])}"
177
- message += " with native extensions" if spec.extensions.any?
178
- Bundler.ui.confirm message
205
+ message = "Installing #{version_message(spec, options[:previous_spec])}"
206
+ message += " with native extensions" if spec.extensions.any?
207
+ Bundler.ui.confirm message
179
208
 
180
- path = cached_gem(spec)
181
- raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
182
- if requires_sudo?
183
- install_path = Bundler.tmp(spec.full_name)
184
- bin_path = install_path.join("bin")
185
- else
186
- install_path = rubygems_dir
187
- bin_path = Bundler.system_bindir
188
- end
209
+ installed_spec = installer.install
189
210
 
190
- Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
191
-
192
- require_relative "../rubygems_gem_installer"
193
-
194
- installed_spec = Bundler::RubyGemsGemInstaller.at(
195
- path,
196
- :install_dir => install_path.to_s,
197
- :bin_dir => bin_path.to_s,
198
- :ignore_dependencies => true,
199
- :wrappers => true,
200
- :env_shebang => true,
201
- :build_args => options[:build_args],
202
- :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
203
- :bundler_extension_cache_path => extension_cache_path(spec)
204
- ).install
205
- spec.full_gem_path = installed_spec.full_gem_path
206
-
207
- # SUDO HAX
208
- if requires_sudo?
209
- Bundler.rubygems.repository_subdirectories.each do |name|
210
- src = File.join(install_path, name, "*")
211
- dst = File.join(rubygems_dir, name)
212
- if name == "extensions" && Dir.glob(src).any?
213
- src = File.join(src, "*/*")
214
- ext_src = Dir.glob(src).first
215
- ext_src.gsub!(src[0..-6], "")
216
- dst = File.dirname(File.join(dst, ext_src))
217
- end
218
- SharedHelpers.filesystem_access(dst) do |p|
219
- Bundler.mkdir_p(p)
220
- end
221
- Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any?
211
+ spec.full_gem_path = installed_spec.full_gem_path
212
+ spec.loaded_from = installed_spec.loaded_from
213
+
214
+ # SUDO HAX
215
+ if requires_sudo?
216
+ Bundler.rubygems.repository_subdirectories.each do |name|
217
+ src = File.join(install_path, name, "*")
218
+ dst = File.join(rubygems_dir, name)
219
+ if name == "extensions" && Dir.glob(src).any?
220
+ src = File.join(src, "*/*")
221
+ ext_src = Dir.glob(src).first
222
+ ext_src.gsub!(src[0..-6], "")
223
+ dst = File.dirname(File.join(dst, ext_src))
222
224
  end
225
+ SharedHelpers.filesystem_access(dst) do |p|
226
+ Bundler.mkdir_p(p)
227
+ end
228
+ Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any?
229
+ end
223
230
 
224
- spec.executables.each do |exe|
225
- SharedHelpers.filesystem_access(Bundler.system_bindir) do |p|
226
- Bundler.mkdir_p(p)
227
- end
228
- Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/"
231
+ spec.executables.each do |exe|
232
+ SharedHelpers.filesystem_access(Bundler.system_bindir) do |p|
233
+ Bundler.mkdir_p(p)
229
234
  end
235
+ Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/"
230
236
  end
231
- installed_spec.loaded_from = loaded_from(spec)
232
237
  end
233
- spec.loaded_from = loaded_from(spec)
234
238
 
235
239
  spec.post_install_message
236
240
  ensure
@@ -348,10 +352,6 @@ module Bundler
348
352
  end
349
353
  end
350
354
 
351
- def loaded_from(spec)
352
- "#{rubygems_dir}/specifications/#{spec.full_name}.gemspec"
353
- end
354
-
355
355
  def cached_gem(spec)
356
356
  if spec.default_gem?
357
357
  cached_built_in_gem(spec)
@@ -364,10 +364,14 @@ module Bundler
364
364
  global_cache_path = download_cache_path(spec)
365
365
  @caches << global_cache_path if global_cache_path
366
366
 
367
- possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
367
+ possibilities = @caches.map {|p| package_path(p, spec) }
368
368
  possibilities.find {|p| File.exist?(p) }
369
369
  end
370
370
 
371
+ def package_path(cache_path, spec)
372
+ "#{cache_path}/#{spec.file_name}"
373
+ end
374
+
371
375
  def normalize_uri(uri)
372
376
  uri = uri.to_s
373
377
  uri = "#{uri}/" unless uri =~ %r{/$}
@@ -459,12 +463,11 @@ module Bundler
459
463
  end
460
464
 
461
465
  def fetch_gem(spec, previous_spec = nil)
462
- return false unless spec.remote
463
-
464
466
  spec.fetch_platform
465
467
 
466
468
  cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
467
- gem_path = "#{cache_path}/#{spec.file_name}"
469
+ gem_path = package_path(cache_path, spec)
470
+ return gem_path if File.exist?(gem_path)
468
471
 
469
472
  if requires_sudo?
470
473
  download_path = Bundler.tmp(spec.full_name)
@@ -482,7 +485,7 @@ module Bundler
482
485
  SharedHelpers.filesystem_access(cache_path) do |p|
483
486
  Bundler.mkdir_p(p)
484
487
  end
485
- Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}"
488
+ Bundler.sudo "mv #{package_path(download_cache_path, spec)} #{gem_path}"
486
489
  end
487
490
 
488
491
  gem_path
@@ -499,7 +502,7 @@ module Bundler
499
502
  end
500
503
 
501
504
  def rubygems_dir
502
- Bundler.rubygems.gem_dir
505
+ Bundler.bundle_path
503
506
  end
504
507
 
505
508
  def default_cache_path_for(dir)
@@ -12,17 +12,19 @@ module Bundler
12
12
  end
13
13
 
14
14
  def for(dependencies, check = false, match_current_platform = false)
15
- handled = []
15
+ # dep.name => [list, of, deps]
16
+ handled = Hash.new {|h, k| h[k] = [] }
16
17
  deps = dependencies.dup
17
18
  specs = []
18
19
 
19
20
  loop do
20
21
  break unless dep = deps.shift
21
- next if handled.any? {|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
22
+ next if handled[dep.name].any? {|d| match_current_platform || d.__platform == dep.__platform } || dep.name == "bundler"
22
23
 
23
- handled << dep
24
+ # use a hash here to ensure constant lookup time in the `any?` call above
25
+ handled[dep.name] << dep
24
26
 
25
- specs_for_dep = spec_for_dependency(dep, match_current_platform)
27
+ specs_for_dep = specs_for_dependency(dep, match_current_platform)
26
28
  if specs_for_dep.any?
27
29
  specs.concat(specs_for_dep)
28
30
 
@@ -171,12 +173,13 @@ module Bundler
171
173
  @specs.sort_by(&:name).each {|s| yield s }
172
174
  end
173
175
 
174
- def spec_for_dependency(dep, match_current_platform)
175
- specs_for_platforms = lookup[dep.name]
176
+ def specs_for_dependency(dep, match_current_platform)
177
+ specs_for_name = lookup[dep.name]
176
178
  if match_current_platform
177
- GemHelpers.select_best_platform_match(specs_for_platforms.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
179
+ GemHelpers.select_best_platform_match(specs_for_name.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
178
180
  else
179
- GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
181
+ specs_for_name_and_platform = GemHelpers.select_best_platform_match(specs_for_name, dep.__platform)
182
+ specs_for_name_and_platform.any? ? specs_for_name_and_platform : specs_for_name
180
183
  end
181
184
  end
182
185
 
@@ -64,9 +64,11 @@ module Bundler
64
64
  end
65
65
 
66
66
  def full_gem_path
67
- # deleted gems can have their stubs return nil, so in that case grab the
68
- # expired path from the full spec
69
- stub.full_gem_path || method_missing(:full_gem_path)
67
+ stub.full_gem_path
68
+ end
69
+
70
+ def full_gem_path=(path)
71
+ stub.full_gem_path = path
70
72
  end
71
73
 
72
74
  def full_require_paths
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.3.14".freeze
4
+ VERSION = "2.3.17".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
data/lib/bundler.rb CHANGED
@@ -97,6 +97,17 @@ module Bundler
97
97
  @bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root)
98
98
  end
99
99
 
100
+ def create_bundle_path
101
+ SharedHelpers.filesystem_access(bundle_path.to_s) do |p|
102
+ mkdir_p(p)
103
+ end unless bundle_path.exist?
104
+
105
+ @bundle_path = bundle_path.realpath
106
+ rescue Errno::EEXIST
107
+ raise PathError, "Could not install to path `#{bundle_path}` " \
108
+ "because a file already exists at that path. Either remove or rename the file so the directory can be created."
109
+ end
110
+
100
111
  def configured_bundle_path
101
112
  @configured_bundle_path ||= settings.path.tap(&:validate!)
102
113
  end
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.3.14
4
+ version: 2.3.17
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: 2022-05-18 00:00:00.000000000 Z
25
+ date: 2022-06-29 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
@@ -369,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
369
369
  - !ruby/object:Gem::Version
370
370
  version: 2.5.2
371
371
  requirements: []
372
- rubygems_version: 3.3.14
372
+ rubygems_version: 3.3.17
373
373
  signing_key:
374
374
  specification_version: 4
375
375
  summary: The best way to manage your application's dependencies