/* * Copyright (c) 2004, Chris Leung. All rights reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. You should have * received a copy of the license along with this library. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY. */ package fireant; import java.io.File; import java.io.StringReader; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Echo; import org.apache.tools.ant.taskdefs.Manifest; import org.apache.tools.ant.types.FileSet; import sf.blacksun.fireant.FireantBuilder; import sf.blacksun.fireant.FireantProject; import sf.blacksun.fireant.FireantTarget; import sf.blacksun.fireant.FireantTask; import sf.blacksun.fireant.datatype.FaFileSet; import sf.blacksun.fireant.taskdef.FaChmod; import sf.blacksun.fireant.taskdef.FaCopy; import sf.blacksun.fireant.taskdef.FaJar; import sf.blacksun.fireant.taskdef.FaJavac; import sf.blacksun.fireant.taskdef.FaMkdir; import sf.blacksun.fireant.util.FaFileUtil; import sf.blacksun.fireant.util.FaTextUtil; /** * Fireant builder for the fireant project. * This is more fancy than neccessary to showcase various constructs of a FireantBuilder. * * @author chrisl */ public class Builder extends FireantBuilder { //////////////////////////////////////////////////////////////////////// private static boolean VERBOSE = false; private static Map opts = new HashMap(); public static final String PROJECT = "fireant"; public static final String VERSION = "0.8.0"; final String RELEASE = "blacksun-fireant"; final String TODAY = String.format("%1$tY%1$tm%1$td", new Date()); final String XDEF = "**/CVS/ **/.svn/ **/.xvpic/ **/.xvpics/ **/trash/ **/*~ **/*.bak"; static final String ISRC = "**/*.java **/*.properties **/*.xml **/*.template"; File topDir = getBaseDir(); File workspace = topDir.getParentFile(); File extDir = new File(workspace, "ext"); // File srcDir = new File(topDir, "src"); File binDir = new File(topDir, "bin"); File testDir = new File(topDir, "test"); File docDir = new File(topDir, "doc"); File distDir = new File(topDir, "dist"); File trashDir = new File(topDir, "trash"); File fireantDir = new File(topDir, "fireant"); File fireantSrcDir = new File(fireantDir, "src"); // File jarFile = new File(distDir, RELEASE + ".jar"); File srcJarFile = new File(distDir, RELEASE + "-src.jar"); File distFile = new File(distDir, RELEASE + "-" + VERSION + ".jar"); FileSet distFiles = new FaFileSet( topDir, "src/ fireant/src/ doc/release/ LICENSE/ fireant.sh .project .classpath", XDEF); // String classPath = extDir + "/jakarta-oro-2.0.6.jar"; //////////////////////////////////////////////////////////////////////// public static void main(String[] args) { int index = 0; String target = "Usage"; for (; index < args.length; ++index) { String s = args[index]; if ("v".equals(s) || "verbose".equals(s)) { VERBOSE = true; continue; } if ("h".equals(s) || "help".equals(s)) index = args.length; break; } if (index < args.length) target = args[index]; new Builder(new File(System.getProperty("user.dir")), opts).build(target); } //////////////////////////////////////////////////////////////////////// /** * Constructor define the properties and build targets. */ public Builder(File basedir, Map options) { super(basedir, options); if (VERBOSE) setLogLevel(Project.MSG_VERBOSE); } //////////////////////////////////////////////////////////////////////// /** Print a sample command line that can be use to invoke this builder (with proper classpath). */ public class Usage extends FireantTarget { public void execute() { List classpath = FaFileUtil.getRelativePath(getClasspathFiles(), topDir, true); System.out.println( "java -classpath " + FaTextUtil.join(":", classpath) + " " + Builder.this.getClass().getName() + " \nTargets:" + sprintTargets("\n\t")); } } public class Build extends FireantTarget { public void execute() { binDir.mkdirs(); String classpath = FaTextUtil.join( ":", FaFileUtil.getRelativePath(getClasspathFiles(), topDir, true)); exec( new FaJavac(getProject(), binDir, fireantSrcDir, "**/*.java", XDEF, classpath) .debugInfo(true)); exec(new FaJavac(getProject(), binDir, srcDir, "**/*.java", XDEF, classpath).debugInfo(true)); } } public class Jar extends FireantTarget { public Jar(FireantProject project) { super(project); setDescription("Create binary and source jar files."); } public void execute() { jarFile.getParentFile().mkdirs(); FaJar jar = new FaJar( false, jarFile, new FileSet[] { new FaFileSet(binDir, "sf/ fireant/", XDEF), new FaFileSet(topDir, "LICENSE/", XDEF) }); try { Manifest mf = new Manifest( new StringReader( "Main-Class: sf.blacksun.fireant.BuildBuilder\n" + "Class-Path: oro-2.0.8.jar\n")); jar.addConfiguredManifest(mf); exec(jar); } catch (Exception e) { throw new BuildException(e); } exec(new FaChmod("a+r", jarFile)); srcJarFile.getParentFile().mkdirs(); exec( new FaJar( false, srcJarFile, new FileSet[] { new FaFileSet(srcDir, ISRC, XDEF), new FaFileSet(new File(fireantDir, "src"), "fireant/", XDEF), new FaFileSet(topDir, "LICENSE/", XDEF) })); echo("# Jar done."); } } /** * Example of executing ant tasks directly using Java code. * . Since constructor do not need to build the task list, default constructor can be used. * . Note that the task is instantiate when use and not added to the target. */ public class Install extends FireantTarget { public Install() { addDependency(Jar.class); setDescription("Install jar files to " + extDir); } public void execute() { // Update release doc sample. exec( new FaCopy( true, new File(fireantDir, "src/fireant/Builder.java"), new File(docDir, "release"))); exec(new FaCopy(true, true, jarFile, extDir)); exec(new FaCopy(true, true, srcJarFile, extDir)); echo("# Install done."); } } // EXAMPLE: Static target class. */ public static class Dist extends FireantTarget { public Dist(FireantProject project) { super(project); setDescription("Create distribution package."); Builder builder = (Builder)project.getBuilder(); addTask(new FaMkdir(builder.distDir)); addTask(new FaJar(false, builder.distFile, builder.distFiles)); } } /** * Exmaple of using task list, simulating standard ant. * * Constructor with the FireAntProject parameter is needed in order to * build the target/task structure in constructor. FireAntBuilder invoke * constructor with FireAntProject parameter if it found one. * * Note that Fireant task constructors do not automatically add itself to the target, * use addTask() to do so. */ public class Print extends FireantTarget { // EXAMPLE: Building a target from Ant tasks and custom tasks. public Print(FireantProject project) { super(project); addDependency(Print0.TARGET_NAME); addDependency(Print1.class); Echo echo = new Echo(); echo.setTaskName("echo"); echo.setMessage("The echo message"); addTask(echo); addTask(new Task1(this)); addTask( new FireantTask() { public void execute() { DirectoryScanner ds = new DirectoryScanner(); ds.setBasedir(topDir); ds.setIncludes( new String[] { "**LICENSE", "**Makefile", "**.project", "**.classpath", "**/src/" }); ds.setExcludes(new String[] { "**/CVS/, **/.svn/" }); ds.scan(); String[] distfiles = ds.getIncludedFiles(); System.out.println( "DistFiles=\n\t" + FaTextUtil.join("\n\t", distfiles)); } }); } private class Task1 extends FireantTask { public Task1(FireantTarget target) { super(target); } public void execute() throws BuildException { echo("This is printed by echo in Task1."); System.out.println("This is printed by System.out.println() in Task1."); } } } public class Print0 extends FireantTarget { public static final String TARGET_NAME = "print0"; // EXAMPLE: FireAntTarget by default use simple class name as target name. // However, it can be override with something else if neccessary. public Print0(FireantProject project) { super(project, TARGET_NAME); } public void execute() throws BuildException { // EXAMPLE: Setup and execute an Ant (not FireantTask) task directly (without adding to a target). Echo echo = new Echo(); echo.setMessage("# target print0: hello"); exec(echo); } } public class Print1 extends FireantTarget { // EXAMPLE: Excuting Java code directly. public void execute() { System.out.println("# target print1: hello"); } } //////////////////////////////////////////////////////////////////////// }