blob: c1a7d5ce64cd103b2b09fa8203d808712eda42fd [file] [log] [blame]
# Used to map a name to a set of dependencies
class JavaGen < BaseGenerator
def build_classpath_(dep_name)
t = Rake::Task[dep_name.to_sym]
if t.nil?
puts "No match for #{dep_name}"
return []
end
classpath = []
deps = t.deps || []
deps += t.prerequisites
deps.each do |dep|
if Rake::Task.task_defined?(dep.to_sym) then
classpath += build_classpath_(dep)
else
classpath += FileList[dep]
end
end
FileList[dep_name].each do |match|
classpath.push match if match =~ /\.jar/
end
classpath.push t.out.to_s unless t.out.nil?
classpath.sort.uniq
end
def out_path_(args)
"build/#{args[:name]}.jar".to_sym
end
def jar(args)
if !jar?
puts "Unable to locate 'jar' command"
exit -1
end
if args[:srcs].nil?
puts "No srcs specified for #{args[:name]}"
end
out = out_path_(args)
create_deps_(out_path_(args), args)
t = Rake::Task[args[:name].to_sym]
t.deps = args[:deps]
t.out = out
file out do
# Build the classpath from the list of dependencies
classpath = build_classpath_(args[:name].to_sym)
temp = "#{out}_classes"
mkdir_p temp
puts "Building: #{args[:name]} as #{out}"
if args[:srcs]
# Remove anything that's not a JAR from the classpath
classpath = classpath.collect do |path|
path if path.to_s =~ /.jar$/
end
# avoid hitting Windows' command line argument limit by putting
# the source list in a file
src_file = "src.txt"
File.open(src_file, "w") do |file|
file << FileList[args[:srcs]].join(" ")
end
begin
# Compile
cmd = "javac -cp #{classpath.join(classpath_separator?)} -g -source 5 -target 5 -d #{temp} @#{src_file}"
sh cmd
ensure
# Delete the temporary file
File.delete src_file
end
end
# TODO(simon): make copy_resource_ handle this for us
# Copy resources over
resources = args[:resources] || []
resources.each do |res|
if (res.kind_of? Symbol)
res = Rake::Task[res].out
end
if (res.kind_of? Hash)
res.each do |from, to|
Dir["#{temp}/#{to}/**.svn"].each { |file| rm_rf file }
dir = to.gsub(/\/.*?$/, "")
mkdir_p "#{temp}/#{dir}"
begin
if File.directory? from
mkdir_p "#{temp}/#{to}"
end
cp_r find_file(from), "#{temp}/#{to}"
rescue
Dir["#{temp}/**/.svn"].each { |file| rm_rf file }
cp_r find_file(from), "#{temp}/#{to}"
end
end
else
target = res.gsub(/build\//, '')
copy_resource_(target, temp)
end
end
Dir["#{temp}/**/.svn"].each { |file| rm_rf file }
cmd = "cd #{temp} && jar cMf ../../#{out} *"
sh cmd
rm_rf temp
end
add_zip_task_(args)
end
def add_zip_task_(args)
# Now to add the implicit targets
out = out_path_(args)
zip_out = out.to_s.sub(".jar", ".zip")
task :"#{args[:name]}_zip" => FileList[zip_out]
file zip_out => out do
puts "Building: #{args[:name]}_zip as #{zip_out}"
classpath = build_classpath_(args[:name].to_sym)
temp = "#{zip_out}_temp"
mkdir_p temp
classpath.each do |f|
copy_resource_(f, temp) if f =~ /\.jar/
end
sh "cd #{temp} && jar cMf ../../#{zip_out} *"
rm_rf temp
end
end
def run_test_(args)
classpath = build_classpath_(args[:name])
main = args[:main] || "junit.textui.TestRunner"
test_string = 'java -Xmx128m -Xms128m '
test_string += '-cp "' + classpath.join(classpath_separator?) + '" ' if classpath.length > 1
if args[:system_properties] then
args[:system_properties].each do |prop|
test_string += "-D#{prop} "
end
end
if ENV['REMOTE_JAVA_DEBUG_PORT'] then
test_string += "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=#{ENV['REMOTE_JAVA_DEBUG_PORT']} "
end
test_string += main
test_string += ' ' + args[:args] if args[:args]
if args[:tests].length == 0
result = sh test_string
else
args[:tests].each do |test|
puts "Running: #{test}\n"
test_string += " #{test} "
result = sh test_string
end
end
result
end
def test(args)
jar(args)
out = out_path_(args)
file "#{args[:name]}_never_there" => [ "#{out}" ] do
if (args[:run].nil? || args[:run])
tests = `jar tvf #{out}`
tests = tests.split /\n/
tests.map! do |clazz|
clazz =~ /.*\s+(.*TestSuite\.class)/ ? $1.gsub("/", ".").gsub(/\.class\s*$/, "") : nil
end
tests.compact!
if (!args[:test_suite].nil?)
tests.reject! {|clazz| clazz !~ /#{args[:test_suite]}/}
end
args[:tests] = tests
run_test_ args
else
puts "Skipping tests for #{args[:name]}"
end
end
task "#{args[:name]}" => "#{args[:name]}_never_there"
end
def uberjar(args)
out = out_path_(args)
create_deps_(out_path_(args), args)
file out do
puts "Building uber-jar: #{args[:name]} as #{out}"
# Take each dependency, extract and then rezip
temp = "#{out}_temp"
mkdir_p temp
all = []
args[:deps].each do |d|
all += build_classpath_(d)
end
all = all.sort.uniq.collect
all.each do |dep|
next unless dep.to_s =~ /\.jar$/
next if (dep.to_s =~ /\lib\// or dep.to_s =~ /^third_party\//) and args[:no_libs] == true
sh "cd #{temp} && jar xf ../../#{dep}"
end
excludes = args[:exclude] || []
excludes.each do |to_exclude|
rm_rf FileList["#{temp}/#{to_exclude}"]
end
Dir["#{temp}/**/.svn"].each { |file| rm_rf file }
if args[:main]
# Read any MANIFEST.MF file into memory, ignoring the main class line
manifest = []
manifest.push "Main-Class: #{args[:main]}\n"
manifest_file = "#{temp}/META-INF/MANIFEST.MF"
if (!File.exists? manifest_file)
mkdir_p "#{temp}/META-INF"
touch(manifest_file)
end
File.open(manifest_file, "r") do |f|
while (line = f.gets)
manifest.push line unless line =~ /^Main-Class:/
end
end
File.open(manifest_file, "w") do |f| f.write(manifest.join("")) end
end
sh "cd #{temp} && jar cMf ../../#{out} *"
rm_rf temp
end
add_zip_task_(args)
t = Rake::Task[args[:name].to_sym]
t.deps = args[:deps]
t.out = out
end
def build_uberlist_(task_names, standalone)
all = []
tasks = task_names || []
tasks.each do |dep|
if Rake::Task.task_defined? dep.to_sym then
t = Rake::Task[dep.to_sym]
all.push t.out if t.out.to_s =~ /\.jar$/
all += build_uberlist_(t.deps, standalone)
all += build_uberlist_(t.prerequisites, standalone)
elsif standalone
all += FileList[dep]
end
end
all.uniq
end
def war(args)
out = "build/#{args[:name]}.war"
deps = args[:deps] || []
deps += args[:resources] || []
deps.each do |dep|
if (dep.is_a? Symbol)
task args[:name] => [dep]
elsif (dep.is_a? String)
task args[:name] => FileList[dep]
end
end
file out do
temp = "#{out}_temp"
mkdir_p "#{temp}/WEB-INF/lib"
# Copy the resources. They're easy
copy_resource_(args[:resources], temp) unless args[:resources].nil?
# Now the JARs we depend on
jars = build_classpath_(args[:name].to_sym).collect do |jar|
jar.to_s =~ /\.jar/ ? jar : nil
end
copy_resource_(jars, "#{temp}/WEB-INF/lib")
Dir["#{temp}/**/.svn"].each { |file| rm_rf file }
sh "cd #{temp} && jar cMf ../../#{out} *"
rm_rf temp
end
task args[:name] => out
t = Rake::Task[args[:name]]
t.out = out
t.deps = args[:deps]
end
end
def walk_war_deps_(dep, dest)
puts "Dep: #{dep} is a #{dep.class}"
if (dep.is_a? Symbol)
t = Rake::Task[dep]
copy_resource_(t.out, dest) if dep.to_s =~ /\.jar/
walk_war_deps_(t.deps, dest)
walk_war_deps_(t.prerequisites, dest)
elsif dep.is_a? String
copy_resource_(dep, dest) if dep.to_s =~ /\.jar/
elsif dep.is_a? Array
dep.each do |child|
walk_war_deps_(child, dest)
end
end
end
def java_jar(args)
JavaGen.new().jar(args)
end
def java_test(args)
JavaGen.new().test(args)
end
def java_uberjar(args)
JavaGen.new().uberjar(args)
end
def java_war(args)
JavaGen.new().war(args)
end