summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Arko <andre@arko.net>2015-05-17 12:39:34 -0700
committerAndre Arko <andre@arko.net>2015-05-17 13:13:43 -0700
commit7aaee7a002fd8a8d0ed03b839a6867f8d2083fb5 (patch)
tree0e54bd02178149537b307c07b6d04a11d50d86a4
parent858afa5cfec914bd3c9d6242d1ae49cd6c227fa1 (diff)
downloadbundler-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.rb17
-rw-r--r--lib/bundler/source/path.rb11
-rw-r--r--spec/bundler/dsl_spec.rb13
-rw-r--r--spec/install/gemfile/path_spec.rb23
-rw-r--r--spec/support/builders.rb8
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