bundler 2.2.23 → 2.2.27
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +68 -0
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/cache.rb +1 -1
- data/lib/bundler/cli/doctor.rb +1 -1
- data/lib/bundler/cli/exec.rb +1 -6
- data/lib/bundler/cli/gem.rb +3 -2
- data/lib/bundler/cli/install.rb +4 -17
- data/lib/bundler/cli/list.rb +7 -1
- data/lib/bundler/cli/open.rb +1 -2
- data/lib/bundler/cli/update.rb +1 -1
- data/lib/bundler/cli.rb +12 -9
- data/lib/bundler/definition.rb +38 -47
- data/lib/bundler/dsl.rb +40 -26
- data/lib/bundler/errors.rb +1 -1
- data/lib/bundler/installer/gem_installer.rb +3 -16
- data/lib/bundler/installer/standalone.rb +14 -9
- data/lib/bundler/installer.rb +0 -1
- data/lib/bundler/lockfile_parser.rb +1 -0
- data/lib/bundler/plugin/index.rb +4 -1
- data/lib/bundler/plugin/installer.rb +2 -0
- data/lib/bundler/plugin.rb +25 -6
- data/lib/bundler/resolver.rb +10 -17
- data/lib/bundler/rubygems_gem_installer.rb +5 -1
- data/lib/bundler/rubygems_integration.rb +2 -0
- data/lib/bundler/runtime.rb +16 -9
- data/lib/bundler/settings.rb +13 -1
- data/lib/bundler/setup.rb +2 -2
- data/lib/bundler/shared_helpers.rb +0 -7
- data/lib/bundler/source/git/git_proxy.rb +1 -2
- data/lib/bundler/source/rubygems.rb +23 -2
- data/lib/bundler/source/rubygems_aggregate.rb +4 -0
- data/lib/bundler/source.rb +4 -0
- data/lib/bundler/source_list.rb +16 -3
- data/lib/bundler/spec_set.rb +14 -37
- data/lib/bundler/templates/Executable.bundler +6 -6
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +13 -2
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -1
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +17 -2
- data/lib/bundler.rb +11 -21
- metadata +3 -3
data/lib/bundler/dsl.rb
CHANGED
@@ -102,38 +102,39 @@ module Bundler
|
|
102
102
|
# if there's already a dependency with this name we try to prefer one
|
103
103
|
if current = @dependencies.find {|d| d.name == dep.name }
|
104
104
|
deleted_dep = @dependencies.delete(current) if current.type == :development
|
105
|
-
return if deleted_dep
|
106
105
|
|
107
|
-
|
108
|
-
|
106
|
+
unless deleted_dep
|
107
|
+
if current.requirement != dep.requirement
|
108
|
+
return if dep.type == :development
|
109
109
|
|
110
|
-
|
110
|
+
update_prompt = ""
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
if File.basename(@gemfile) == Injector::INJECTED_GEMS
|
113
|
+
if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
|
114
|
+
update_prompt = ". Gem already added"
|
115
|
+
else
|
116
|
+
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
|
117
117
|
|
118
|
-
|
118
|
+
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
|
119
|
+
end
|
119
120
|
end
|
120
|
-
end
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
122
|
+
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
|
123
|
+
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
|
124
|
+
"#{update_prompt}"
|
125
|
+
else
|
126
|
+
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
|
127
|
+
"You should probably keep only one of them.\n" \
|
128
|
+
"Remove any duplicate entries and specify the gem only once.\n" \
|
129
|
+
"While it's not a problem now, it could cause errors if you change the version of one of them later."
|
130
|
+
end
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
132
|
+
if current.source != dep.source
|
133
|
+
return if dep.type == :development
|
134
|
+
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
135
|
+
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
|
136
|
+
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
137
|
+
end
|
137
138
|
end
|
138
139
|
end
|
139
140
|
|
@@ -446,8 +447,21 @@ repo_name ||= user_name
|
|
446
447
|
end
|
447
448
|
|
448
449
|
def check_rubygems_source_safety
|
449
|
-
|
450
|
+
if @sources.implicit_global_source?
|
451
|
+
implicit_global_source_warning
|
452
|
+
elsif @sources.aggregate_global_source?
|
453
|
+
multiple_global_source_warning
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
def implicit_global_source_warning
|
458
|
+
Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
|
459
|
+
"Not using an explicit global source may result in a different lockfile being generated depending on " \
|
460
|
+
"the gems you have installed locally before bundler is run. " \
|
461
|
+
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
|
462
|
+
end
|
450
463
|
|
464
|
+
def multiple_global_source_warning
|
451
465
|
if Bundler.feature_flag.bundler_3_mode?
|
452
466
|
msg = "This Gemfile contains multiple primary sources. " \
|
453
467
|
"Each source after the first must include a block to indicate which gems " \
|
data/lib/bundler/errors.rb
CHANGED
@@ -122,7 +122,7 @@ module Bundler
|
|
122
122
|
|
123
123
|
class VirtualProtocolError < BundlerError
|
124
124
|
def message
|
125
|
-
"There was an error relating to virtualization and file access." \
|
125
|
+
"There was an error relating to virtualization and file access. " \
|
126
126
|
"It is likely that you need to grant access to or mount some file system correctly."
|
127
127
|
end
|
128
128
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "shellwords"
|
4
|
-
|
5
3
|
module Bundler
|
6
4
|
class GemInstaller
|
7
5
|
attr_reader :spec, :standalone, :worker, :force, :installer
|
@@ -31,34 +29,23 @@ module Bundler
|
|
31
29
|
|
32
30
|
def specific_failure_message(e)
|
33
31
|
message = "#{e.class}: #{e.message}\n"
|
34
|
-
message += " " + e.backtrace.join("\n ") + "\n\n"
|
32
|
+
message += " " + e.backtrace.join("\n ") + "\n\n"
|
35
33
|
message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear)
|
36
34
|
message + Bundler.ui.add_color(failure_message, :red)
|
37
35
|
end
|
38
36
|
|
39
37
|
def failure_message
|
40
|
-
|
41
|
-
"#{install_error_message}\n#{gem_install_message}"
|
38
|
+
install_error_message
|
42
39
|
end
|
43
40
|
|
44
41
|
def install_error_message
|
45
42
|
"An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
|
46
43
|
end
|
47
44
|
|
48
|
-
def gem_install_message
|
49
|
-
source = spec.source
|
50
|
-
return unless source.respond_to?(:remotes)
|
51
|
-
|
52
|
-
if source.remotes.size == 1
|
53
|
-
"Make sure that `gem install #{spec.name} -v '#{spec.version}' --source '#{source.remotes.first}'` succeeds before bundling."
|
54
|
-
else
|
55
|
-
"Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
45
|
def spec_settings
|
60
46
|
# Fetch the build settings, if there are any
|
61
47
|
if settings = Bundler.settings["build.#{spec.name}"]
|
48
|
+
require "shellwords"
|
62
49
|
Shellwords.shellsplit(settings)
|
63
50
|
end
|
64
51
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Bundler
|
4
4
|
class Standalone
|
5
5
|
def initialize(groups, definition)
|
6
|
-
@specs =
|
6
|
+
@specs = definition.specs_for(groups)
|
7
7
|
end
|
8
8
|
|
9
9
|
def generate
|
@@ -12,12 +12,13 @@ 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 "ruby_engine = RUBY_ENGINE"
|
16
|
-
file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
|
17
|
-
file.puts "path = File.expand_path('..', __FILE__)"
|
18
15
|
file.puts reverse_rubygems_kernel_mixin
|
19
16
|
paths.each do |path|
|
20
|
-
|
17
|
+
if Pathname.new(path).absolute?
|
18
|
+
file.puts %($:.unshift "#{path}")
|
19
|
+
else
|
20
|
+
file.puts %($:.unshift File.expand_path("\#{__dir__}/#{path}"))
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -28,14 +29,14 @@ module Bundler
|
|
28
29
|
@specs.map do |spec|
|
29
30
|
next if spec.name == "bundler"
|
30
31
|
Array(spec.require_paths).map do |path|
|
31
|
-
gem_path(path, spec).sub(version_dir, '#{
|
32
|
+
gem_path(path, spec).sub(version_dir, '#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}')
|
32
33
|
# This is a static string intentionally. It's interpolated at a later time.
|
33
34
|
end
|
34
|
-
end.flatten
|
35
|
+
end.flatten.compact
|
35
36
|
end
|
36
37
|
|
37
38
|
def version_dir
|
38
|
-
"#{
|
39
|
+
"#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
|
39
40
|
end
|
40
41
|
|
41
42
|
def bundler_path
|
@@ -44,7 +45,11 @@ module Bundler
|
|
44
45
|
|
45
46
|
def gem_path(path, spec)
|
46
47
|
full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
|
47
|
-
|
48
|
+
if spec.source.instance_of?(Source::Path)
|
49
|
+
full_path
|
50
|
+
else
|
51
|
+
Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
|
52
|
+
end
|
48
53
|
rescue TypeError
|
49
54
|
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
|
50
55
|
raise Gem::InvalidSpecificationException.new(error_message)
|
data/lib/bundler/installer.rb
CHANGED
@@ -195,6 +195,7 @@ module Bundler
|
|
195
195
|
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
|
196
196
|
@current_spec = LazySpecification.new(name, version, platform)
|
197
197
|
@current_spec.source = @current_source
|
198
|
+
@current_source.add_dependency_names(name)
|
198
199
|
|
199
200
|
@specs[@current_spec.identifier] = @current_spec
|
200
201
|
elsif spaces.size == 6
|
data/lib/bundler/plugin/index.rb
CHANGED
@@ -74,7 +74,10 @@ module Bundler
|
|
74
74
|
def unregister_plugin(name)
|
75
75
|
@commands.delete_if {|_, v| v == name }
|
76
76
|
@sources.delete_if {|_, v| v == name }
|
77
|
-
@hooks.each
|
77
|
+
@hooks.each do |hook, names|
|
78
|
+
names.delete(name)
|
79
|
+
@hooks.delete(hook) if names.empty?
|
80
|
+
end
|
78
81
|
@plugin_paths.delete(name)
|
79
82
|
@load_paths.delete(name)
|
80
83
|
save_index
|
data/lib/bundler/plugin.rb
CHANGED
@@ -13,6 +13,7 @@ module Bundler
|
|
13
13
|
class MalformattedPlugin < PluginError; end
|
14
14
|
class UndefinedCommandError < PluginError; end
|
15
15
|
class UnknownSourceError < PluginError; end
|
16
|
+
class PluginInstallError < PluginError; end
|
16
17
|
|
17
18
|
PLUGIN_FILE_NAME = "plugins.rb".freeze
|
18
19
|
|
@@ -38,12 +39,11 @@ module Bundler
|
|
38
39
|
specs = Installer.new.install(names, options)
|
39
40
|
|
40
41
|
save_plugins names, specs
|
41
|
-
rescue PluginError
|
42
|
+
rescue PluginError
|
42
43
|
specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
|
43
44
|
specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
|
44
45
|
|
45
|
-
|
46
|
-
Bundler.ui.error "Failed to install the following plugins: #{names_list}. The underlying error was: #{e.message}.\n #{e.backtrace.join("\n ")}"
|
46
|
+
raise
|
47
47
|
end
|
48
48
|
|
49
49
|
# Uninstalls plugins by the given names
|
@@ -245,10 +245,11 @@ module Bundler
|
|
245
245
|
# @param [Array<String>] names of inferred source plugins that can be ignored
|
246
246
|
def save_plugins(plugins, specs, optional_plugins = [])
|
247
247
|
plugins.each do |name|
|
248
|
+
next if index.installed?(name)
|
249
|
+
|
248
250
|
spec = specs[name]
|
249
|
-
|
250
|
-
|
251
|
-
Bundler.ui.info "Installed plugin #{name}" if installed
|
251
|
+
|
252
|
+
save_plugin(name, spec, optional_plugins.include?(name))
|
252
253
|
end
|
253
254
|
end
|
254
255
|
|
@@ -263,6 +264,22 @@ module Bundler
|
|
263
264
|
raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file?
|
264
265
|
end
|
265
266
|
|
267
|
+
# Validates and registers a plugin.
|
268
|
+
#
|
269
|
+
# @param [String] name the name of the plugin
|
270
|
+
# @param [Specification] spec of installed plugin
|
271
|
+
# @param [Boolean] optional_plugin, removed if there is conflict with any
|
272
|
+
# other plugin (used for default source plugins)
|
273
|
+
#
|
274
|
+
# @raise [PluginInstallError] if validation or registration raises any error
|
275
|
+
def save_plugin(name, spec, optional_plugin = false)
|
276
|
+
validate_plugin! Pathname.new(spec.full_gem_path)
|
277
|
+
installed = register_plugin(name, spec, optional_plugin)
|
278
|
+
Bundler.ui.info "Installed plugin #{name}" if installed
|
279
|
+
rescue PluginError => e
|
280
|
+
raise PluginInstallError, "Failed to install plugin `#{spec.name}`, due to #{e.class} (#{e.message})"
|
281
|
+
end
|
282
|
+
|
266
283
|
# Runs the plugins.rb file in an isolated namespace, records the plugin
|
267
284
|
# actions it registers for and then passes the data to index to be stored.
|
268
285
|
#
|
@@ -309,6 +326,8 @@ module Bundler
|
|
309
326
|
#
|
310
327
|
# @param [String] name of the plugin
|
311
328
|
def load_plugin(name)
|
329
|
+
return unless name && !name.empty?
|
330
|
+
|
312
331
|
# Need to ensure before this that plugin root where the rest of gems
|
313
332
|
# are installed to be on load path to support plugin deps. Currently not
|
314
333
|
# done to avoid conflicts
|
data/lib/bundler/resolver.rb
CHANGED
@@ -255,12 +255,6 @@ module Bundler
|
|
255
255
|
next if name == "bundler"
|
256
256
|
next unless search_for(requirement).empty?
|
257
257
|
|
258
|
-
cache_message = begin
|
259
|
-
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
260
|
-
rescue GemfileNotFound
|
261
|
-
nil
|
262
|
-
end
|
263
|
-
|
264
258
|
if (base = @base[name]) && !base.empty?
|
265
259
|
version = base.first.version
|
266
260
|
message = "You have requested:\n" \
|
@@ -269,18 +263,17 @@ module Bundler
|
|
269
263
|
"Try running `bundle update #{name}`\n\n" \
|
270
264
|
"If you are updating multiple gems in your Gemfile at once,\n" \
|
271
265
|
"try passing them all to `bundle update`"
|
272
|
-
|
266
|
+
else
|
267
|
+
source = source_for(name)
|
273
268
|
specs = source.specs.search(name)
|
274
269
|
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
|
283
|
-
"listed in your Gemfile#{cache_message}."
|
270
|
+
cache_message = begin
|
271
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
272
|
+
rescue GemfileNotFound
|
273
|
+
nil
|
274
|
+
end
|
275
|
+
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source.to_err}#{cache_message}.\n")
|
276
|
+
message << "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}" if versions_with_platforms.any?
|
284
277
|
end
|
285
278
|
raise GemNotFound, message
|
286
279
|
end
|
@@ -378,7 +371,7 @@ module Bundler
|
|
378
371
|
o << if metadata_requirement
|
379
372
|
"is not available in #{relevant_source}"
|
380
373
|
else
|
381
|
-
"in #{relevant_source}.\n"
|
374
|
+
"in #{relevant_source.to_err}.\n"
|
382
375
|
end
|
383
376
|
end
|
384
377
|
end,
|
@@ -61,7 +61,10 @@ module Bundler
|
|
61
61
|
|
62
62
|
def build_extensions
|
63
63
|
extension_cache_path = options[:bundler_extension_cache_path]
|
64
|
-
|
64
|
+
unless extension_cache_path && extension_dir = spec.extension_dir
|
65
|
+
require "shellwords" # compensate missing require in rubygems before version 3.2.25
|
66
|
+
return super
|
67
|
+
end
|
65
68
|
|
66
69
|
extension_dir = Pathname.new(extension_dir)
|
67
70
|
build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
|
@@ -71,6 +74,7 @@ module Bundler
|
|
71
74
|
FileUtils.cp_r extension_cache_path, spec.extension_dir
|
72
75
|
end
|
73
76
|
else
|
77
|
+
require "shellwords" # compensate missing require in rubygems before version 3.2.25
|
74
78
|
super
|
75
79
|
if extension_dir.directory? # not made for gems without extensions
|
76
80
|
SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
|
data/lib/bundler/runtime.rb
CHANGED
@@ -12,22 +12,16 @@ module Bundler
|
|
12
12
|
def setup(*groups)
|
13
13
|
@definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
|
14
14
|
|
15
|
-
groups.map!(&:to_sym)
|
16
|
-
|
17
15
|
# Has to happen first
|
18
16
|
clean_load_path
|
19
17
|
|
20
|
-
specs =
|
18
|
+
specs = @definition.specs_for(groups)
|
21
19
|
|
22
20
|
SharedHelpers.set_bundle_environment
|
23
21
|
Bundler.rubygems.replace_entrypoints(specs)
|
24
22
|
|
25
23
|
# Activate the specs
|
26
24
|
load_paths = specs.map do |spec|
|
27
|
-
unless spec.loaded_from
|
28
|
-
raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
|
29
|
-
end
|
30
|
-
|
31
25
|
check_for_activated_spec!(spec)
|
32
26
|
|
33
27
|
Bundler.rubygems.mark_loaded(spec)
|
@@ -106,7 +100,7 @@ module Bundler
|
|
106
100
|
|
107
101
|
alias_method :gems, :specs
|
108
102
|
|
109
|
-
def cache(custom_path = nil)
|
103
|
+
def cache(custom_path = nil, local = false)
|
110
104
|
cache_path = Bundler.app_cache(custom_path)
|
111
105
|
SharedHelpers.filesystem_access(cache_path) do |p|
|
112
106
|
FileUtils.mkdir_p(p)
|
@@ -114,7 +108,20 @@ module Bundler
|
|
114
108
|
|
115
109
|
Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
|
116
110
|
|
117
|
-
specs_to_cache = Bundler.settings[:cache_all_platforms]
|
111
|
+
specs_to_cache = if Bundler.settings[:cache_all_platforms]
|
112
|
+
@definition.resolve.materialized_for_all_platforms
|
113
|
+
else
|
114
|
+
begin
|
115
|
+
specs
|
116
|
+
rescue GemNotFound
|
117
|
+
if local
|
118
|
+
Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
|
119
|
+
end
|
120
|
+
|
121
|
+
raise
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
118
125
|
specs_to_cache.each do |spec|
|
119
126
|
next if spec.name == "bundler"
|
120
127
|
next if spec.source.is_a?(Source::Gemspec)
|