diff options
author | Samuel Giddins <segiddins@segiddins.me> | 2016-02-01 11:23:24 -0600 |
---|---|---|
committer | Samuel Giddins <segiddins@segiddins.me> | 2016-02-01 15:45:25 -0600 |
commit | c323e2e555d0c6eefca9bc1648ae2806356370c4 (patch) | |
tree | 211c51c954974de839b21065bfd1ef9185319cba | |
parent | 8a0ca9d711dae8dce92b5bdca2e29cbe106794ba (diff) | |
download | bundler-c323e2e555d0c6eefca9bc1648ae2806356370c4.tar.gz |
[RubyVersion] Support compound requirements
-rw-r--r-- | lib/bundler/ruby_dsl.rb | 4 | ||||
-rw-r--r-- | lib/bundler/ruby_version.rb | 53 | ||||
-rw-r--r-- | spec/bundler/ruby_dsl_spec.rb | 24 | ||||
-rw-r--r-- | spec/bundler/ruby_version_spec.rb | 24 |
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 |