java_requirement: port to Linux and refactor

Split the core requirement class into generic, Linux-specific,
and macOS-specific parts.

Additionally, the Linux version is now able to detect Java versions
(the previous Linuxbrew implementation was only able to detect
if Java was present at all.)
This commit is contained in:
Bob W. Hogg 2016-12-04 18:43:46 -08:00
parent 5a2a063802
commit 5a214de68d
6 changed files with 226 additions and 25 deletions

View File

@ -0,0 +1,19 @@
require "language/java"
class JavaRequirement < Requirement
default_formula "jdk"
env do
next unless @java_home
env_java_common
if (Pathname.new(@java_home)/"include").exist? # Oracle JVM
env_oracle_jdk
end
end
private
def oracle_java_os
:linux
end
end

View File

@ -0,0 +1,40 @@
class JavaRequirement
cask "java"
env do
env_java_common
java_home = Pathname.new(@java_home)
if (java_home/"include").exist? # Oracle JVM
env_oracle_jdk
else # Apple JVM
env_apple
end
end
private
def possible_javas
javas = []
javas << Pathname.new(ENV["JAVA_HOME"])/"bin/java" if ENV["JAVA_HOME"]
javas << java_home_cmd
javas << which("java")
javas
end
def java_home_cmd
return nil unless File.executable?("/usr/libexec/java_home")
args = %w[--failfast]
args << "--version" << @version.to_s if @version
java_home = Utils.popen_read("/usr/libexec/java_home", *args).chomp
return nil unless $?.success?
Pathname.new(java_home)/"bin/java"
end
def env_apple
ENV.append_to_cflags "-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/"
end
def oracle_java_os
:darwin
end
end

View File

@ -0,0 +1,7 @@
require "requirements/java_requirement"
if OS.mac?
require "extend/os/mac/requirements/java_requirement"
elsif OS.linux?
require "extend/os/linux/requirements/java_requirement"
end

View File

@ -2,28 +2,12 @@ require "language/java"
class JavaRequirement < Requirement class JavaRequirement < Requirement
fatal true fatal true
cask "java"
download "http://www.oracle.com/technetwork/java/javase/downloads/index.html" download "http://www.oracle.com/technetwork/java/javase/downloads/index.html"
satisfy build_env: false do satisfy build_env: false do
next false unless File.executable? "/usr/libexec/java_home" setup_java
next false unless @java
args = %w[--failfast] next true
args << "--version" << @version.to_s if @version
@java_home = Utils.popen_read("/usr/libexec/java_home", *args).chomp
$?.success?
end
env do
java_home = Pathname.new(@java_home)
ENV["JAVA_HOME"] = java_home
ENV.prepend_path "PATH", java_home/"bin"
if (java_home/"include").exist? # Oracle JVM
ENV.append_to_cflags "-I#{java_home}/include"
ENV.append_to_cflags "-I#{java_home}/include/darwin"
else # Apple JVM
ENV.append_to_cflags "-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/"
end
end end
def initialize(tags) def initialize(tags)
@ -45,16 +29,86 @@ class JavaRequirement < Requirement
def display_s def display_s
if @version if @version
if @version[-1] == "+" if exact_version?
op = ">="
version = @version[0, @version.length-1]
else
op = "=" op = "="
version = @version else
op = ">="
end end
"#{name} #{op} #{version}" "#{name} #{op} #{version_without_plus}"
else else
name name
end end
end end
private
def version_without_plus
if exact_version?
@version
else
@version[0, @version.length-1]
end
end
def exact_version?
@version && @version.to_s.chars.last != "+"
end
def setup_java
java = preferred_java
return unless java
@java = java
@java_home = java.parent.parent
end
def possible_javas
javas = []
javas << Pathname.new(ENV["JAVA_HOME"])/"bin/java" if ENV["JAVA_HOME"]
jdk = begin
Formula["jdk"]
rescue FormulaUnavailableError
nil
end
javas << jdk.bin/"java" if jdk && jdk.installed?
javas << which("java")
javas
end
def preferred_java
possible_javas.detect do |java|
next false unless java && java.executable?
next true unless @version
next true if satisfies_version(java)
end
end
def env_java_common
java_home = Pathname.new(@java_home)
ENV["JAVA_HOME"] = java_home
ENV.prepend_path "PATH", java_home/"bin"
end
def env_oracle_jdk
java_home = Pathname.new(@java_home)
ENV.append_to_cflags "-I#{java_home}/include"
ENV.append_to_cflags "-I#{java_home}/include/#{oracle_java_os}"
end
def oracle_java_os
nil
end
def satisfies_version(java)
java_version_s = Utils.popen_read("#{java} -version 2>&1")[/1.\d/]
return false unless java_version_s
java_version = Version.create(java_version_s)
needed_version = Version.create(version_without_plus)
if exact_version?
java_version == needed_version
else
java_version >= needed_version
end
end
end end
require "extend/os/requirements/java_requirement"

View File

@ -0,0 +1,50 @@
require "testing_env"
require "requirements/java_requirement"
class JavaRequirementTests < Homebrew::TestCase
def setup
super
ENV["JAVA_HOME"] = nil
end
def test_message
a = JavaRequirement.new([])
assert_match(/Java is required to install this formula./, a.message)
end
def test_inspect
a = JavaRequirement.new(%w[1.7+])
assert_equal a.inspect, '#<JavaRequirement: "java" [] version="1.7+">'
end
def test_display_s
x = JavaRequirement.new([])
assert_equal x.display_s, "java"
y = JavaRequirement.new(%w[1.8])
assert_equal y.display_s, "java = 1.8"
z = JavaRequirement.new(%w[1.8+])
assert_equal z.display_s, "java >= 1.8"
end
def test_satisfied?
a = JavaRequirement.new(%w[1.8])
File.stubs(:executable?).returns(false)
refute_predicate a, :satisfied?
b = JavaRequirement.new([])
b.stubs(:preferred_java).returns(Pathname.new("/usr/bin/java"))
assert_predicate b, :satisfied?
c = JavaRequirement.new(%w[1.7+])
c.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")])
Utils.stubs(:popen_read).returns('java version "1.6.0_5"')
refute_predicate c, :satisfied?
Utils.stubs(:popen_read).returns('java version "1.8.0_5"')
assert_predicate c, :satisfied?
d = JavaRequirement.new(%w[1.7])
d.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")])
Utils.stubs(:popen_read).returns('java version "1.8.0_5"')
refute_predicate d, :satisfied?
end
end

View File

@ -0,0 +1,31 @@
require "testing_env"
require "requirements/java_requirement"
require "fileutils"
class OSMacJavaRequirementTests < Homebrew::TestCase
def setup
super
@java_req = JavaRequirement.new(%w[1.8])
@tmp_java_home = mktmpdir
@tmp_pathname = Pathname.new(@tmp_java_home)
FileUtils.mkdir @tmp_pathname/"bin"
FileUtils.touch @tmp_pathname/"bin/java"
@java_req.stubs(:preferred_java).returns(@tmp_pathname/"bin/java")
@java_req.satisfied?
end
def test_java_env_apple
ENV.expects(:prepend_path)
ENV.expects(:append_to_cflags)
@java_req.modify_build_environment
assert_equal ENV["JAVA_HOME"], @tmp_java_home
end
def test_java_env_oracle
FileUtils.mkdir @tmp_pathname/"include"
ENV.expects(:prepend_path)
ENV.expects(:append_to_cflags).twice
@java_req.modify_build_environment
assert_equal ENV["JAVA_HOME"], @tmp_java_home
end
end