diff options
author | Andre Arko <andre@arko.net> | 2015-05-17 12:39:34 -0700 |
---|---|---|
committer | Andre Arko <andre@arko.net> | 2015-05-17 13:13:43 -0700 |
commit | 7aaee7a002fd8a8d0ed03b839a6867f8d2083fb5 (patch) | |
tree | 0e54bd02178149537b307c07b6d04a11d50d86a4 | |
parent | 858afa5cfec914bd3c9d6242d1ae49cd6c227fa1 (diff) | |
download | bundler-7aaee7a002fd8a8d0ed03b839a6867f8d2083fb5.tar.gz |
RubyGems can only validate during chdir
Since it turns out that Specification#validate only works correctly if
the cwd is the directory that contains the gemspec, we now validate at
the same time as we load the gemspec. At least then we’ve already had
to chdir, so we can validate correctly.
-rw-r--r-- | lib/bundler.rb | 17 | ||||
-rw-r--r-- | lib/bundler/source/path.rb | 11 | ||||
-rw-r--r-- | spec/bundler/dsl_spec.rb | 13 | ||||
-rw-r--r-- | spec/install/gemfile/path_spec.rb | 23 | ||||
-rw-r--r-- | spec/support/builders.rb | 8 |
5 files changed, 40 insertions, 32 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index 197e88c222..bf06bea46c 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -341,27 +341,32 @@ module Bundler raise MarshalError, "#{e.class}: #{e.message}" end - def load_gemspec(file) + def load_gemspec(file, validate = false) @gemspec_cache ||= {} key = File.expand_path(file) - spec = ( @gemspec_cache[key] ||= load_gemspec_uncached(file) ) + @gemspec_cache[key] ||= load_gemspec_uncached(file, validate) # Protect against caching side-effected gemspecs by returning a # new instance each time. - spec.dup if spec + @gemspec_cache[key] if @gemspec_cache[key] end - def load_gemspec_uncached(file) + def load_gemspec_uncached(file, validate = false) path = Pathname.new(file) # Eval the gemspec from its parent directory, because some gemspecs # depend on "./" relative paths. SharedHelpers.chdir(path.dirname.to_s) do contents = path.read if contents[0..2] == "---" # YAML header - eval_yaml_gemspec(path, contents) + spec = eval_yaml_gemspec(path, contents) else - eval_gemspec(path, contents) + spec = eval_gemspec(path, contents) end + spec.validate if spec && validate + spec end + rescue Gem::InvalidSpecificationException => e + raise InvalidOption, "The gemspec at #{file} is not valid. " \ + "The validation error was '#{e.message}'" end def clear_gemspec_cache diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 6c2ed85881..e586c60bce 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -131,7 +131,7 @@ module Bundler if File.directory?(expanded_path) # We sort depth-first since `<<` will override the earlier-found specs Dir["#{expanded_path}/#{@glob}"].sort_by { |p| -p.split(File::SEPARATOR).size }.each do |file| - if spec = load_and_validate_gemspec(file) + if spec = Bundler.load_gemspec(file, :validate) spec.loaded_from = file.to_s spec.source = self index << spec @@ -219,15 +219,6 @@ module Bundler end end - def load_and_validate_gemspec(file) - spec = load_gemspec(file) - spec.validate - spec - rescue Gem::InvalidSpecificationException => e - raise InvalidOption, "The gemspec at #{file} is not valid. " \ - "The validation error was '#{e.message}'" - end - end end end diff --git a/spec/bundler/dsl_spec.rb b/spec/bundler/dsl_spec.rb index ca97d0c6ca..bb6388eb5c 100644 --- a/spec/bundler/dsl_spec.rb +++ b/spec/bundler/dsl_spec.rb @@ -188,17 +188,4 @@ describe Bundler::Dsl do end end - describe "#gemspec" do - it "errors on invalid specs" do - File.open(bundled_app("foo.gemspec"), "w") do |f| - f.write <<-G - Gem::Specification.new do |s| - s.name = "foo" - end - G - end - expect(Bundler).to receive(:default_gemfile).and_return(bundled_app("Gemfile")) - expect { subject.gemspec }.to raise_error(Bundler::InvalidOption).with_message(/missing value for attribute version/) - end - end end diff --git a/spec/install/gemfile/path_spec.rb b/spec/install/gemfile/path_spec.rb index 6ba4096457..d754674e89 100644 --- a/spec/install/gemfile/path_spec.rb +++ b/spec/install/gemfile/path_spec.rb @@ -126,6 +126,8 @@ describe "bundle install with explicit source paths" do Gem::Specification.new do |s| s.name = 'premailer' s.version = '1.0.0' + s.summary = 'Hi' + s.authors = 'Me' end G end @@ -139,6 +141,26 @@ describe "bundle install with explicit source paths" do should_be_installed "premailer 1.0.0" end + it "errors on invalid specs" do + build_lib "foo" + + gemspec = lib_path("foo-1.0").join("foo.gemspec").to_s + File.open(gemspec, "w") do |f| + f.write <<-G + Gem::Specification.new do |s| + s.name = "foo" + end + G + end + + install_gemfile <<-G, :expect_err => true + gem "foo", :path => "#{lib_path("foo-1.0")}" + G + + expect(out).to match(/missing value for attribute version/) + should_not_be_installed("foo 1.0") + end + it "supports gemspec syntax" do build_lib "foo", "1.0", :path => lib_path("foo") do |s| s.add_dependency "rack", "1.0" @@ -249,6 +271,7 @@ describe "bundle install with explicit source paths" do path "#{lib_path('foo-1.0')}" gem 'foo' G + should_be_installed "foo 1.0" bundle "exec foobar" expect(out).to eq("1.0") diff --git a/spec/support/builders.rb b/spec/support/builders.rb index 1a1c916779..4dbcb2982b 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -456,10 +456,12 @@ module Spec end def executables=(val) - Array(val).each do |file| - write "#{@spec.bindir}/#{file}", "require '#{@name}' ; puts #{@name.upcase}" - end @spec.executables = Array(val) + @spec.executables.each do |file| + executable = "#{@spec.bindir}/#{file}" + @spec.files << executable + write executable, "require '#{@name}' ; puts #{@name.upcase}" + end end def add_c_extension |