summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2016-02-01 11:23:24 -0600
committerSamuel Giddins <segiddins@segiddins.me>2016-02-01 15:45:25 -0600
commitc323e2e555d0c6eefca9bc1648ae2806356370c4 (patch)
tree211c51c954974de839b21065bfd1ef9185319cba
parent8a0ca9d711dae8dce92b5bdca2e29cbe106794ba (diff)
downloadbundler-c323e2e555d0c6eefca9bc1648ae2806356370c4.tar.gz
[RubyVersion] Support compound requirements
-rw-r--r--lib/bundler/ruby_dsl.rb4
-rw-r--r--lib/bundler/ruby_version.rb53
-rw-r--r--spec/bundler/ruby_dsl_spec.rb24
-rw-r--r--spec/bundler/ruby_version_spec.rb24
4 files changed, 68 insertions, 37 deletions
diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb
index 47f2bcc337..e1b9c3c3a1 100644
--- a/lib/bundler/ruby_dsl.rb
+++ b/lib/bundler/ruby_dsl.rb
@@ -1,7 +1,9 @@
# frozen_string_literal: true
module Bundler
module RubyDsl
- def ruby(ruby_version, options = {})
+ def ruby(*ruby_version)
+ options = ruby_version.last.is_a?(Hash) ? ruby_version.pop : {}
+ ruby_version.flatten!
raise GemfileError, "Please define :engine_version" if options[:engine] && options[:engine_version].nil?
raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil?
diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb
index 77ab442e19..8ca15ceff5 100644
--- a/lib/bundler/ruby_version.rb
+++ b/lib/bundler/ruby_version.rb
@@ -1,9 +1,14 @@
# frozen_string_literal: true
module Bundler
class RubyVersion
- attr_reader :version, :patchlevel, :engine, :engine_version, :gem_version
+ attr_reader :versions,
+ :patchlevel,
+ :engine,
+ :engine_versions,
+ :gem_version,
+ :engine_gem_version
- def initialize(version, patchlevel, engine, engine_version)
+ def initialize(versions, patchlevel, engine, engine_version)
# The parameters to this method must satisfy the
# following constraints, which are verified in
# the DSL:
@@ -16,18 +21,19 @@ module Bundler
# must not be specified, or the engine version
# specified must match the version.
- @version = version
- @gem_version = Gem::Requirement.create(version).requirements.first.last
- @input_engine = engine
- @engine = engine || "ruby"
- @engine_version = engine_version || version
- @patchlevel = patchlevel
+ @versions = Array(versions)
+ @gem_version = Gem::Requirement.create(@versions.first).requirements.first.last
+ @input_engine = engine
+ @engine = engine || "ruby"
+ @engine_versions = (engine_version && Array(engine_version)) || @versions
+ @engine_gem_version = Gem::Requirement.create(@engine_versions.first).requirements.first.last
+ @patchlevel = patchlevel
end
- def to_s(version = self.version)
- output = String.new("ruby #{version}")
+ def to_s(versions = self.versions)
+ output = String.new("ruby #{versions_string(versions)}")
output << "p#{patchlevel}" if patchlevel
- output << " (#{engine} #{engine_version})" unless engine == "ruby"
+ output << " (#{engine} #{versions_string(engine_versions)})" unless engine == "ruby"
output
end
@@ -37,9 +43,9 @@ module Bundler
end
def ==(other)
- version == other.version &&
+ versions == other.versions &&
engine == other.engine &&
- engine_version == other.engine_version &&
+ engine_versions == other.engine_versions &&
patchlevel == other.patchlevel
end
@@ -58,17 +64,22 @@ module Bundler
# 2. ruby_version
# 3. engine_version
def diff(other)
+ raise ArgumentError, "Can only diff with a RubyVersion" unless other.is_a?(RubyVersion)
if engine != other.engine && @input_engine
[:engine, engine, other.engine]
- elsif !version || !matches?(version, other.version)
- [:version, version, other.version]
- elsif @input_engine && !matches?(engine_version, other.engine_version)
- [:engine_version, engine_version, other.engine_version]
+ elsif versions.empty? || !matches?(versions, other.gem_version)
+ [:version, versions_string(versions), versions_string(other.versions)]
+ elsif @input_engine && !matches?(engine_versions, other.engine_gem_version)
+ [:engine_version, versions_string(engine_versions), versions_string(other.engine_versions)]
elsif patchlevel && (!patchlevel.is_a?(String) || !other.patchlevel.is_a?(String) || !matches?(patchlevel, other.patchlevel))
[:patchlevel, patchlevel, other.patchlevel]
end
end
+ def versions_string(versions)
+ Array(versions).join(", ")
+ end
+
def self.system
ruby_engine = if defined?(RUBY_ENGINE) && !RUBY_ENGINE.nil?
RUBY_ENGINE.dup
@@ -85,14 +96,16 @@ module Bundler
JRUBY_VERSION.dup
else
raise BundlerError, "RUBY_ENGINE value #{RUBY_ENGINE} is not recognized"
- end
+ end
@ruby_version ||= RubyVersion.new(RUBY_VERSION.dup, RUBY_PATCHLEVEL.to_s, ruby_engine, ruby_engine_version)
end
private
- def matches?(requirement, version)
- Gem::Requirement.create(requirement).satisfied_by?(Gem::Version.new(version))
+ def matches?(requirements, version)
+ Array(requirements).all? do |requirement|
+ Gem::Requirement.create(requirement).satisfied_by?(Gem::Version.create(version))
+ end
end
end
end
diff --git a/spec/bundler/ruby_dsl_spec.rb b/spec/bundler/ruby_dsl_spec.rb
index c692160cc3..cb6650eca2 100644
--- a/spec/bundler/ruby_dsl_spec.rb
+++ b/spec/bundler/ruby_dsl_spec.rb
@@ -22,7 +22,7 @@ describe Bundler::RubyDsl do
let(:invoke) do
proc do
- dsl.ruby(ruby_version, options)
+ dsl.ruby(*ruby_version, options)
end
end
@@ -34,13 +34,13 @@ describe Bundler::RubyDsl do
describe "#ruby_version" do
shared_examples_for "it stores the ruby version" do
it "stores the version" do
- expect(subject.version).to eq(ruby_version)
+ expect(subject.versions).to eq(Array(ruby_version))
expect(subject.gem_version.version).to eq(version)
end
it "stores the engine details" do
expect(subject.engine).to eq(engine)
- expect(subject.engine_version).to eq(engine_version)
+ expect(subject.engine_versions).to eq(Array(engine_version))
end
it "stores the patchlevel" do
@@ -57,13 +57,23 @@ describe Bundler::RubyDsl do
it_behaves_like "it stores the ruby version"
end
- context "with two requirements" do
+ context "with two requirements in the same string" do
let(:ruby_version) { ">= 2.0.0, < 3.0" }
it "raises an error" do
expect { subject }.to raise_error(ArgumentError)
end
end
+ context "with two requirements" do
+ let(:ruby_version) { ["~> 2.0.0", "> 2.0.1"] }
+ it_behaves_like "it stores the ruby version"
+ end
+
+ context "with multiple engine versions" do
+ let(:engine_version) { ["> 200", "< 300"] }
+ it_behaves_like "it stores the ruby version"
+ end
+
context "with no options hash" do
let(:invoke) { proc { dsl.ruby(ruby_version) } }
@@ -72,6 +82,12 @@ describe Bundler::RubyDsl do
let(:engine_version) { version }
it_behaves_like "it stores the ruby version"
+
+ context "and with multiple requirements" do
+ let(:ruby_version) { ["~> 2.0.0", "> 2.0.1"] }
+ let(:engine_version) { ruby_version }
+ it_behaves_like "it stores the ruby version"
+ end
end
end
end
diff --git a/spec/bundler/ruby_version_spec.rb b/spec/bundler/ruby_version_spec.rb
index e8d308a2c8..eeaf0bf294 100644
--- a/spec/bundler/ruby_version_spec.rb
+++ b/spec/bundler/ruby_version_spec.rb
@@ -31,7 +31,7 @@ describe "Bundler::RubyVersion and its subclasses" do
let(:engine_version) { nil }
it "should set engine version as the passed version" do
- expect(subject.engine_version).to eq("2.0.0")
+ expect(subject.engine_versions).to eq(["2.0.0"])
end
end
end
@@ -144,13 +144,13 @@ describe "Bundler::RubyVersion and its subclasses" do
shared_examples_for "there is a difference in the versions" do
it "should return a tuple with :version and the two different versions" do
- expect(ruby_version.diff(other_ruby_version)).to eq([:version, version, other_version])
+ expect(ruby_version.diff(other_ruby_version)).to eq([:version, Array(version).join(", "), Array(other_version).join(", ")])
end
end
shared_examples_for "there is a difference in the engine versions" do
it "should return a tuple with :engine_version and the two different engine versions" do
- expect(ruby_version.diff(other_ruby_version)).to eq([:engine_version, engine_version, other_engine_version])
+ expect(ruby_version.diff(other_ruby_version)).to eq([:engine_version, Array(engine_version).join(", "), Array(other_engine_version).join(", ")])
end
end
@@ -273,8 +273,8 @@ describe "Bundler::RubyVersion and its subclasses" do
describe "#version" do
it "should return a copy of the value of RUBY_VERSION" do
- expect(subject.version).to eq(RUBY_VERSION)
- expect(subject.version).to_not be(RUBY_VERSION)
+ expect(subject.versions).to eq([RUBY_VERSION])
+ expect(subject.versions.first).to_not be(RUBY_VERSION)
end
end
@@ -306,8 +306,8 @@ describe "Bundler::RubyVersion and its subclasses" do
end
it "should return a copy of the value of RUBY_VERSION" do
- expect(bundler_system_ruby_version.engine_version).to eq("2.2.4")
- expect(bundler_system_ruby_version.engine_version).to_not be(RUBY_VERSION)
+ expect(bundler_system_ruby_version.engine_versions).to eq(["2.2.4"])
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_VERSION)
end
end
@@ -318,8 +318,8 @@ describe "Bundler::RubyVersion and its subclasses" do
end
it "should return a copy of the value of Rubinius::VERSION" do
- expect(bundler_system_ruby_version.engine_version).to eq("2.0.0")
- expect(bundler_system_ruby_version.engine_version).to_not be(Rubinius::VERSION)
+ expect(bundler_system_ruby_version.engine_versions).to eq(["2.0.0"])
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(Rubinius::VERSION)
end
end
@@ -330,8 +330,8 @@ describe "Bundler::RubyVersion and its subclasses" do
end
it "should return a copy of the value of JRUBY_VERSION" do
- expect(subject.engine_version).to eq("2.1.1")
- expect(bundler_system_ruby_version.engine_version).to_not be(JRUBY_VERSION)
+ expect(subject.engine_versions).to eq(["2.1.1"])
+ expect(bundler_system_ruby_version.engine_versions.first).to_not be(JRUBY_VERSION)
end
end
@@ -342,7 +342,7 @@ describe "Bundler::RubyVersion and its subclasses" do
end
it "should raise a BundlerError with a 'not recognized' message" do
- expect { bundler_system_ruby_version.engine_version }.to raise_error(Bundler::BundlerError, "RUBY_ENGINE value not_supported_ruby_engine is not recognized")
+ expect { bundler_system_ruby_version.engine_versions }.to raise_error(Bundler::BundlerError, "RUBY_ENGINE value not_supported_ruby_engine is not recognized")
end
end
end