module Buildr module Java module Packaging MANIFEST_HEADER = "Manifest-Version: 1.0\nCreated-By: Ruby Build System" class JarTask < ZipTask attr_accessor :manifest def initialize(*args) super @manifest = true end def []=(key, value) if key.to_sym == :manifest self.manifest = value else super key, value end value end protected def create(zip) if manifest zip.mkdir "META-INF" zip.file.open("META-INF/MANIFEST.MF", "w") do |output| output.write MANIFEST_HEADER case manifest when Hash output.write manifest.map { |pair| pair.join(": ") }.join("\n") when Array manifest.each do |section| output.write "\n" output.write section.map { |pair| pair.join(": ") }.join("\n") end when Proc, Method output.write manifest.call when String output.write File.read(manifest) when true # Default behavior end output.write "\n" end end super zip end end class WarTask < JarTask def []=(key, value) case key.to_sym when :libs self.include value, :path=>"WEB-INF/lib" when :classes self.include value, :path=>"WEB-INF/classes" else super key, value end value end end end end # Create a JAR from all the pre-requisites. # # For example: # jar "lib-1.0.jar"=>["target/classes", "MANIFEST,MF"] def jar(file) Packaging::JarTask.define_task(file) end # Global task packages all projects. desc "Package all projects" LocalDirectoryTask.define_task "package" desc "Install packages created by this project" LocalDirectoryTask.define_task "install" desc "Uninstall packages created by this project" LocalDirectoryTask.define_task "uninstall" desc "Deploy packages created by this project" LocalDirectoryTask.define_task "deploy" class Project # Group used for packaging. Inherited from parent project. inherited_attr :group # Version used for packaging. Inherited from parent project. inherited_attr :version inherited_attr :webapp_src_dir do File.join(src_dir, "main", "webapp") end def package(*args) if Hash === args.last options = args.pop.clone else options = {} end options[:type] = args.shift if Symbol === args.first fail "No packaging type specified" unless options[:type] options[:group] ||= self.group options[:version] ||= self.version options[:id] ||= self.id if String === args.first file = args.shift else file = options.delete(:file) || path_to(:target_dir, Artifact.hash_to_file_name(options)) end fail "One argument too many; expecting at most type, file name, and hash of options" unless args.empty? packager = method("package_as_#{options[:type]}") rescue fail("Do not know how to create a package of type #{options[:type]}") package = packager.call(file, options) or fail("Do not know how to create a package of type #{options[:type]}") task("package").enhance [package] package.enhance [task("build")] task "install"=>[ file_create(File.dirname(repositories.locate(package))) { |task| mkpath task.name, :verbose=>false }, file(repositories.locate(package)=>package) { |task| cp package.name, task.name }, package.pom ] task "uninstall" do |task| verbose(Rake.application.options.trace) do rm repositories.locate(package) rm repositories.locate(package.pom) end end task("deploy") { deploy(package, package.pom) } packages << package Artifact.register package package end def packages() @packages ||= [] end protected def package_as_jar(file, options) returning(Java::Packaging::JarTask.define_task(file)) do |task| package_extend task, options task.include path_to(:java_target_dir, "*") task.include options[:include] if options[:include] task.manifest = options[:manifest] if options[:manifest] end end def package_as_war(file, options) # Add anything we find in webapp sources directory. returning(Java::Packaging::WarTask.define_task(file)) do |task| package_extend task, options task.include path_to(:webapp_src_dir, "*") task.include options[:include] if options[:include] # Add libraries in WEB-INF lib, and classes in WEB-INF classes task.with :libs=>options[:libs].collect if options[:libs] task.with :classes=>(options[:classes] || path_to(:java_target_dir, "**")) unless options[:classes] == false end end def package_as_zip(file, options) returning(ZipTask.define_task(file)) do |task| package_extend task, options task.include path_to(:java_target_dir, "*") task.include options[:include] if options[:include] end end def package_extend(task, spec) task.extend ActsAsArtifact task.apply_spec spec task.pom.enhance do |task| mkpath File.dirname(task.name), :verbose=>false File.open(task.name, "w") do |file| xml = Builder::XmlMarkup.new(:target=>file, :indent=>2) xml.instruct! xml.project do xml.modelVersion "4.0.0." xml.groupId spec[:group] xml.artifactId spec[:id] xml.version spec[:version] xml.classifier spec[:classifier] if spec[:classifier] end end end end end Project.on_create do |project| # Recursive tasks must be defined in before_create. desc "Create packages in this project" project.recursive_task "package"=>"build" desc "Install packages created by this project" project.recursive_task "install"=>"package" desc "Uninstall packages created by this project" project.recursive_task "uninstall" desc "Deploy packages created by this project" project.recursive_task "deploy"=>"package" end end