compilers: support more fails_with uses on GCC.
This commit is contained in:
parent
c65a392d47
commit
3cebcd43b7
@ -19,7 +19,7 @@ end
|
||||
#
|
||||
# @api private
|
||||
class CompilerFailure
|
||||
attr_reader :name
|
||||
attr_reader :type
|
||||
|
||||
def version(val = nil)
|
||||
@version = Version.parse(val.to_s) if val
|
||||
@ -42,29 +42,51 @@ class CompilerFailure
|
||||
def self.create(spec, &block)
|
||||
# Non-Apple compilers are in the format fails_with compiler => version
|
||||
if spec.is_a?(Hash)
|
||||
_, major_version = spec.first
|
||||
name = "gcc-#{major_version}"
|
||||
compiler, major_version = spec.first
|
||||
raise ArgumentError, "The hash `fails_with` syntax only supports GCC" if compiler != :gcc
|
||||
|
||||
type = compiler
|
||||
# so fails_with :gcc => '7' simply marks all 7 releases incompatible
|
||||
version = "#{major_version}.999"
|
||||
exact_major_match = true
|
||||
else
|
||||
name = spec
|
||||
type = spec
|
||||
version = 9999
|
||||
exact_major_match = false
|
||||
end
|
||||
new(name, version, &block)
|
||||
end
|
||||
|
||||
def initialize(name, version, &block)
|
||||
@name = name
|
||||
@version = Version.parse(version.to_s)
|
||||
instance_eval(&block) if block
|
||||
new(type, version, exact_major_match: exact_major_match, &block)
|
||||
end
|
||||
|
||||
def fails_with?(compiler)
|
||||
name == compiler.name && version >= compiler.version
|
||||
version_matched = if type != :gcc
|
||||
version >= compiler.version
|
||||
elsif @exact_major_match
|
||||
gcc_major(version) == gcc_major(compiler.version) && version >= compiler.version
|
||||
else
|
||||
gcc_major(version) >= gcc_major(compiler.version)
|
||||
end
|
||||
type == compiler.type && version_matched
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{name} #{version}>"
|
||||
"#<#{self.class.name}: #{type} #{version}>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(type, version, exact_major_match:, &block)
|
||||
@type = type
|
||||
@version = Version.parse(version.to_s)
|
||||
@exact_major_match = exact_major_match
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
|
||||
def gcc_major(version)
|
||||
if version.major >= 5
|
||||
Version.new(version.major.to_s)
|
||||
else
|
||||
version.major_minor
|
||||
end
|
||||
end
|
||||
|
||||
COLLECTIONS = {
|
||||
@ -81,7 +103,7 @@ class CompilerSelector
|
||||
extend T::Sig
|
||||
include CompilerConstants
|
||||
|
||||
Compiler = Struct.new(:name, :version)
|
||||
Compiler = Struct.new(:type, :name, :version)
|
||||
|
||||
COMPILER_PRIORITY = {
|
||||
clang: [:clang, :gnu, :llvm_clang],
|
||||
@ -130,15 +152,15 @@ class CompilerSelector
|
||||
case compiler
|
||||
when :gnu
|
||||
gnu_gcc_versions.reverse_each do |v|
|
||||
name = "gcc-#{v}"
|
||||
version = compiler_version(name)
|
||||
yield Compiler.new(name, version) unless version.null?
|
||||
executable = "gcc-#{v}"
|
||||
version = compiler_version(executable)
|
||||
yield Compiler.new(:gcc, executable, version) unless version.null?
|
||||
end
|
||||
when :llvm
|
||||
next # no-op. DSL supported, compiler is not.
|
||||
else
|
||||
version = compiler_version(compiler)
|
||||
yield Compiler.new(compiler, version) unless version.null?
|
||||
yield Compiler.new(compiler, compiler, version) unless version.null?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -9,31 +9,31 @@ describe CompilerFailure do
|
||||
describe "::create" do
|
||||
it "creates a failure when given a symbol" do
|
||||
failure = described_class.create(:clang)
|
||||
expect(failure).to fail_with(double("Compiler", name: :clang, version: 600))
|
||||
expect(failure).to fail_with(double("Compiler", type: :clang, name: :clang, version: 600))
|
||||
end
|
||||
|
||||
it "can be given a build number in a block" do
|
||||
failure = described_class.create(:clang) { build 700 }
|
||||
expect(failure).to fail_with(double("Compiler", name: :clang, version: 700))
|
||||
expect(failure).to fail_with(double("Compiler", type: :clang, name: :clang, version: 700))
|
||||
end
|
||||
|
||||
it "can be given an empty block" do
|
||||
failure = described_class.create(:clang) {}
|
||||
expect(failure).to fail_with(double("Compiler", name: :clang, version: 600))
|
||||
expect(failure).to fail_with(double("Compiler", type: :clang, name: :clang, version: 600))
|
||||
end
|
||||
|
||||
it "creates a failure when given a hash" do
|
||||
failure = described_class.create(gcc: "7")
|
||||
expect(failure).to fail_with(double("Compiler", name: "gcc-7", version: "7"))
|
||||
expect(failure).to fail_with(double("Compiler", name: "gcc-7", version: "7.1"))
|
||||
expect(failure).not_to fail_with(double("Compiler", name: "gcc-6", version: "6.0"))
|
||||
expect(failure).to fail_with(double("Compiler", type: :gcc, name: "gcc-7", version: Version.new("7")))
|
||||
expect(failure).to fail_with(double("Compiler", type: :gcc, name: "gcc-7", version: Version.new("7.1")))
|
||||
expect(failure).not_to fail_with(double("Compiler", type: :gcc, name: "gcc-6", version: Version.new("6.0")))
|
||||
end
|
||||
|
||||
it "creates a failure when given a hash and a block with aversion" do
|
||||
failure = described_class.create(gcc: "7") { version "7.1" }
|
||||
expect(failure).to fail_with(double("Compiler", name: "gcc-7", version: "7"))
|
||||
expect(failure).to fail_with(double("Compiler", name: "gcc-7", version: "7.1"))
|
||||
expect(failure).not_to fail_with(double("Compiler", name: "gcc-7", version: "7.2"))
|
||||
expect(failure).to fail_with(double("Compiler", type: :gcc, name: "gcc-7", version: Version.new("7")))
|
||||
expect(failure).to fail_with(double("Compiler", type: :gcc, name: "gcc-7", version: Version.new("7.1")))
|
||||
expect(failure).not_to fail_with(double("Compiler", type: :gcc, name: "gcc-7", version: Version.new("7.2")))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -23,6 +23,7 @@ describe CompilerSelector do
|
||||
when "gcc-7" then Version.create("7.1")
|
||||
when "gcc-6" then Version.create("6.1")
|
||||
when "gcc-5" then Version.create("5.1")
|
||||
when "gcc-4.9" then Version.create("4.9.1")
|
||||
else Version::NULL
|
||||
end
|
||||
end
|
||||
@ -45,29 +46,56 @@ describe CompilerSelector do
|
||||
|
||||
it "returns gcc-6 if gcc formula offers gcc-6 on mac", :needs_macos do
|
||||
software_spec.fails_with(:clang)
|
||||
allow(Formulary).to receive(:factory).with("gcc").and_return(double(version: "6.0"))
|
||||
allow(Formulary).to receive(:factory).with("gcc").and_return(double(version: Version.new("6.0")))
|
||||
expect(selector.compiler).to eq("gcc-6")
|
||||
end
|
||||
|
||||
it "returns gcc-5 if gcc formula offers gcc-5 on linux", :needs_linux do
|
||||
software_spec.fails_with(:clang)
|
||||
allow(Formulary).to receive(:factory).with("gcc@5").and_return(double(version: "5.0"))
|
||||
allow(Formulary).to receive(:factory).with("gcc@5").and_return(double(version: Version.new("5.0")))
|
||||
expect(selector.compiler).to eq("gcc-5")
|
||||
end
|
||||
|
||||
it "returns gcc-6 if gcc formula offers gcc-6 and fails with gcc-5 and gcc-7 on linux", :needs_linux do
|
||||
it "returns gcc-6 if gcc formula offers gcc-5 and fails with gcc-5 and gcc-7 on linux", :needs_linux do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(gcc: "5")
|
||||
software_spec.fails_with(gcc: "7")
|
||||
allow(Formulary).to receive(:factory).with("gcc@5").and_return(double(version: "5.0"))
|
||||
allow(Formulary).to receive(:factory).with("gcc@5").and_return(double(version: Version.new("5.0")))
|
||||
expect(selector.compiler).to eq("gcc-6")
|
||||
end
|
||||
|
||||
it "raises an error when gcc or llvm is missing" do
|
||||
it "returns gcc-7 if gcc formula offers gcc-5 and fails with gcc <= 6 on linux", :needs_linux do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(:gcc) { version "6" }
|
||||
allow(Formulary).to receive(:factory).with("gcc@5").and_return(double(version: Version.new("5.0")))
|
||||
expect(selector.compiler).to eq("gcc-7")
|
||||
end
|
||||
|
||||
it "returns gcc-7 if gcc-7 is version 7.1 but spec fails with gcc-7 <= 7.0" do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(gcc: "7") { version "7.0" }
|
||||
expect(selector.compiler).to eq("gcc-7")
|
||||
end
|
||||
|
||||
it "returns gcc-6 if gcc-7 is version 7.1 but spec fails with gcc-7 <= 7.1" do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(gcc: "7") { version "7.1" }
|
||||
expect(selector.compiler).to eq("gcc-6")
|
||||
end
|
||||
|
||||
it "raises an error when gcc or llvm is missing (hash syntax)" do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(gcc: "7")
|
||||
software_spec.fails_with(gcc: "6")
|
||||
software_spec.fails_with(gcc: "5")
|
||||
software_spec.fails_with(gcc: "4.9")
|
||||
|
||||
expect { selector.compiler }.to raise_error(CompilerSelectionError)
|
||||
end
|
||||
|
||||
it "raises an error when gcc or llvm is missing (symbol syntax)" do
|
||||
software_spec.fails_with(:clang)
|
||||
software_spec.fails_with(:gcc)
|
||||
|
||||
expect { selector.compiler }.to raise_error(CompilerSelectionError)
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user