Skip to content

Commit d16e1af

Browse files
Fix type and gemfile not getting reported as invalid options
1 parent d484eff commit d16e1af

File tree

2 files changed

+104
-77
lines changed

2 files changed

+104
-77
lines changed

bundler/lib/bundler/dsl.rb

Lines changed: 82 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def self.evaluate(gemfile, lockfile, unlock)
1616
VALID_PLATFORMS = Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
1717

1818
VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
19-
platform platforms type source install_if gemfile force_ruby_platform].freeze
19+
platform platforms source install_if force_ruby_platform].freeze
2020

2121
GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
2222
GITLAB_MERGE_REQUEST_URL = %r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}
@@ -77,12 +77,12 @@ def gemspec(opts = nil)
7777

7878
@gemspecs << spec
7979

80-
gem spec.name, name: spec.name, path: path, glob: glob
80+
path path, "glob" => glob, "name" => spec.name do
81+
add_dependency spec.name
82+
end
8183

82-
group(development_group) do
83-
spec.development_dependencies.each do |dep|
84-
gem dep.name, *(dep.requirement.as_list + [type: :development])
85-
end
84+
spec.development_dependencies.each do |dep|
85+
add_dependency dep.name, dep.requirement.as_list, "type" => :development, "group" => development_group
8686
end
8787
when 0
8888
raise InvalidOption, "There are no gemspecs at #{expanded_path}"
@@ -94,79 +94,11 @@ def gemspec(opts = nil)
9494

9595
def gem(name, *args)
9696
options = args.last.is_a?(Hash) ? args.pop.dup : {}
97-
options["gemfile"] = @gemfile
9897
version = args || [">= 0"]
9998

10099
normalize_options(name, version, options)
101100

102-
dep = Dependency.new(name, version, options)
103-
104-
# if there's already a dependency with this name we try to prefer one
105-
if current = @dependencies.find {|d| d.name == dep.name }
106-
if current.requirement != dep.requirement
107-
current_requirement_open = current.requirements_list.include?(">= 0")
108-
109-
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
110-
if gemspec_dep
111-
gemfile_dep = [dep, current].find(&:runtime?)
112-
113-
if gemfile_dep && !current_requirement_open
114-
Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_dep.requirement}).\n" \
115-
"This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n"
116-
elsif gemfile_dep.nil?
117-
require_relative "vendor/pub_grub/lib/pub_grub/version_range"
118-
require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
119-
require_relative "vendor/pub_grub/lib/pub_grub/version_union"
120-
require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
121-
122-
current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
123-
next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
124-
125-
if current_gemspec_range.intersects?(next_gemspec_range)
126-
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
127-
else
128-
raise GemfileError, "Two gemspecs have conflicting requirements on the same gem: #{dep} and #{current}"
129-
end
130-
end
131-
else
132-
update_prompt = ""
133-
134-
if File.basename(@gemfile) == Injector::INJECTED_GEMS
135-
if dep.requirements_list.include?(">= 0") && !current_requirement_open
136-
update_prompt = ". Gem already added"
137-
else
138-
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
139-
140-
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
141-
end
142-
end
143-
144-
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
145-
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
146-
"#{update_prompt}"
147-
end
148-
end
149-
150-
unless current.gemspec_dev_dep? && dep.gemspec_dev_dep?
151-
# Always prefer the dependency from the Gemfile
152-
if current.gemspec_dev_dep?
153-
@dependencies.delete(current)
154-
elsif dep.gemspec_dev_dep?
155-
return
156-
elsif current.source != dep.source
157-
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
158-
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
159-
"#{current.source || "an unspecified source"} and #{dep.source}\n"
160-
else
161-
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
162-
"You should probably keep only one of them.\n" \
163-
"Remove any duplicate entries and specify the gem only once.\n" \
164-
"While it's not a problem now, it could cause errors if you change the version of one of them later."
165-
end
166-
end
167-
end
168-
169-
@dependencies << dep
101+
add_dependency(name, version, options)
170102
end
171103

172104
def source(source, *args, &blk)
@@ -301,6 +233,81 @@ def check_primary_source_safety
301233

302234
private
303235

236+
def add_dependency(name, version = nil, options = {})
237+
options["gemfile"] = @gemfile
238+
options["source"] ||= @source
239+
options["env"] ||= @env
240+
241+
dep = Dependency.new(name, version, options)
242+
243+
# if there's already a dependency with this name we try to prefer one
244+
if current = @dependencies.find {|d| d.name == dep.name }
245+
if current.requirement != dep.requirement
246+
current_requirement_open = current.requirements_list.include?(">= 0")
247+
248+
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
249+
if gemspec_dep
250+
gemfile_dep = [dep, current].find(&:runtime?)
251+
252+
if gemfile_dep && !current_requirement_open
253+
Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_dep.requirement}).\n" \
254+
"This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n"
255+
elsif gemfile_dep.nil?
256+
require_relative "vendor/pub_grub/lib/pub_grub/version_range"
257+
require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
258+
require_relative "vendor/pub_grub/lib/pub_grub/version_union"
259+
require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
260+
261+
current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
262+
next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
263+
264+
if current_gemspec_range.intersects?(next_gemspec_range)
265+
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
266+
else
267+
raise GemfileError, "Two gemspecs have conflicting requirements on the same gem: #{dep} and #{current}"
268+
end
269+
end
270+
else
271+
update_prompt = ""
272+
273+
if File.basename(@gemfile) == Injector::INJECTED_GEMS
274+
if dep.requirements_list.include?(">= 0") && !current_requirement_open
275+
update_prompt = ". Gem already added"
276+
else
277+
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
278+
279+
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
280+
end
281+
end
282+
283+
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
284+
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
285+
"#{update_prompt}"
286+
end
287+
end
288+
289+
unless current.gemspec_dev_dep? && dep.gemspec_dev_dep?
290+
# Always prefer the dependency from the Gemfile
291+
if current.gemspec_dev_dep?
292+
@dependencies.delete(current)
293+
elsif dep.gemspec_dev_dep?
294+
return
295+
elsif current.source != dep.source
296+
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
297+
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
298+
"#{current.source || "an unspecified source"} and #{dep.source}\n"
299+
else
300+
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
301+
"You should probably keep only one of them.\n" \
302+
"Remove any duplicate entries and specify the gem only once.\n" \
303+
"While it's not a problem now, it could cause errors if you change the version of one of them later."
304+
end
305+
end
306+
end
307+
308+
@dependencies << dep
309+
end
310+
304311
def with_gemfile(gemfile)
305312
expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile&.parent)
306313
original_gemfile = @gemfile
@@ -433,8 +440,6 @@ def normalize_options(name, version, opts)
433440
opts["source"] = source
434441
end
435442

436-
opts["source"] ||= @source
437-
opts["env"] ||= @env
438443
opts["platforms"] = platforms.dup
439444
opts["group"] = groups
440445
opts["should_include"] = install_if

bundler/spec/install/gemfile_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,28 @@
6464
expect(err).to match(/You passed :lib as an option for gem 'myrack', but it is invalid/)
6565
end
6666

67+
it "reports that type is an invalid option" do
68+
gemfile <<-G
69+
source "https://gem.repo1"
70+
71+
gem "myrack", :type => "development"
72+
G
73+
74+
bundle :install, raise_on_error: false
75+
expect(err).to match(/You passed :type as an option for gem 'myrack', but it is invalid/)
76+
end
77+
78+
it "reports that gemfile is an invalid option" do
79+
gemfile <<-G
80+
source "https://gem.repo1"
81+
82+
gem "myrack", :gemfile => "foo"
83+
G
84+
85+
bundle :install, raise_on_error: false
86+
expect(err).to match(/You passed :gemfile as an option for gem 'myrack', but it is invalid/)
87+
end
88+
6789
context "when an internal error happens" do
6890
let(:bundler_bug) do
6991
create_file("bundler_bug.rb", <<~RUBY)

0 commit comments

Comments
 (0)