diff --git a/proposal/anteater/source/main/org/apache/ant/Ant.java b/proposal/anteater/source/main/org/apache/ant/Ant.java deleted file mode 100644 index 68abecd53..000000000 --- a/proposal/anteater/source/main/org/apache/ant/Ant.java +++ /dev/null @@ -1,201 +0,0 @@ -// ------------------------------------------------------------------------------- -// Copyright (c)2000 Apache Software Foundation -// ------------------------------------------------------------------------------- - -package org.apache.ant; - -import java.io.*; -import java.util.*; -import java.util.zip.*; - -/** - * Central class of Ant. This is the core 'kernel' of ant. Interfaces into - * ant talk to Ant through this class. - * - * @author James Duncan Davidson (duncan@apache.org) - */ -public class Ant { - - // ----------------------------------------------------------------- - // PRIVATE DATA MEMBERS - // ----------------------------------------------------------------- - - /** - * - */ - private File buildfile; - - /** - * The front end running this. - */ - private AntFrontEnd frontEnd; - - /** - * Manager of tasks. - */ - private TaskManager taskManager = new TaskManager(); - - /** - * - */ - private Project project; - - // ----------------------------------------------------------------- - // CONSTRUCTORS - // ----------------------------------------------------------------- - - /** - * Constructs a new Ant instance. - */ - public Ant(AntFrontEnd frontEnd) { - this.frontEnd = frontEnd; - setUpTaskPath(); - } - - // ----------------------------------------------------------------- - // PUBLIC METHODS - // ----------------------------------------------------------------- - - /** - * Sets additional path nodes onto the task lookup path. - */ - public void addTaskPathNode(File node) { - taskManager.addTaskPathNode(node); - } - - /** - * Builds a target. - */ - public void buildTarget(String targetName) throws AntException { - - // notify FrontEnd that we are starting a build on a project - frontEnd.notifyProjectStart(project); - - Target target = project.getTarget(targetName); - - frontEnd.notifyTargetStart(target); - - // XXX don't forget to execute dependancies first! - - Enumeration enum = target.getTasks().elements(); - while (enum.hasMoreElements()) { - Task task = (Task)enum.nextElement(); - frontEnd.notifyTaskStart(task); - AbstractTask aTask = taskManager.getTaskInstance(task.getType()); - try { - aTask.setProject(project); - aTask.setAttributes(task.getAttributes()); - boolean b = aTask.execute(); - if (!b) { - throw new AntException("STOP: Task " + task + - " did not succeed"); - } - } catch (Exception e) { - // XXX yes yes yes, this shouldn't be a catch all... - throw new AntException("ERR: " + e); - } - frontEnd.notifyTaskEnd(task); - } - - // notify frontEnd that we are done - frontEnd.notifyTargetEnd(target); - frontEnd.notifyProjectEnd(project); - } - - /** - * - */ - public Project getProject() { - return project; - } - - /** - * Sets the buildfile to be used. This action triggers a parse of - * the build file and assembles a Project object from it. - */ - public void setBuildfile(File file) throws AntException { - buildfile = file; - ProjectBuilder builder = new ProjectBuilder(); - project = builder.buildFromFile(file); - project.setAnt(this); - System.out.println("Loaded Project: " + project.getName()); - - // XXX remove the dump after comfort level is reached - - System.out.println("Dump of Project:"); - Enumeration enum = project.getTargets(); - while (enum.hasMoreElements()) { - Target target = (Target)enum.nextElement(); - System.out.println(" Target: " + target.getName()); - Enumeration enum2 = target.getTasks().elements(); - while (enum2.hasMoreElements()) { - Task task = (Task)enum2.nextElement(); - System.out.println(" Task: " + task.getType()); - Enumeration enum3 = task.getAttributeNames(); - while (enum3.hasMoreElements()) { - String atName = (String)enum3.nextElement(); - String atValue = task.getAttribute(atName); - System.out.println(" Att: " + atName + " = " + - atValue); - } - } - } - } - - // ----------------------------------------------------------------- - // PRIVATE METHODS - // ----------------------------------------------------------------- - - /** - * Sets up the taskpath based on the currently running operating - * system. In general, the ordering of the taskpath is: user directory, - * system directory, and then installation. This allows users or - * system admins to override or add tasks. - */ - private void setUpTaskPath() { - - // 1st, add user's home dir. - - File f; - - String userHome = System.getProperty("user.home"); - - // generic unix - f = new File(userHome + ".ant", "tasks"); - if (f.exists() && f.isDirectory()) { - taskManager.addTaskPathNode(f); - } - - // macos x - f = new File(userHome + "/Library/Ant", "Tasks"); - if (f.exists() && f.isDirectory()) { - taskManager.addTaskPathNode(f); - } - - // windows -- todo - - // 2nd, add system local dir. - - // generic unix - f = new File("/usr/local/ant/tasks"); - if (f.exists() && f.isDirectory()) { - taskManager.addTaskPathNode(f); - } - - // macos x - f = new File("/Library/Ant/Tasks"); - if (f.exists() && f.isDirectory()) { - taskManager.addTaskPathNode(f); - } - - // windows -- todo - - // 3rd, add installation local dir. - - //System.out.println("BASE: " + this.getClass().getResource("/")); - - // XXX ---- not really sure how the best way of getting this info is... - // hafta think about it. - } - -} \ No newline at end of file diff --git a/proposal/anteater/source/main/org/apache/ant/Project.java b/proposal/anteater/source/main/org/apache/ant/Project.java index 92feddc81..0b8108c01 100644 --- a/proposal/anteater/source/main/org/apache/ant/Project.java +++ b/proposal/anteater/source/main/org/apache/ant/Project.java @@ -22,12 +22,33 @@ public class Project { /** * */ - private Ant ant; + //private Ant ant; + + /** + * Base directory of this project. Usually this value is the directory + * where the project file was found, but can be different. + */ + private File baseDir; /** * */ - private PrintStream out; + private String defaultTargetName; + + /** + * Short description of the project. + */ + private String description; + + /** + * Front end that this project communicates to. + */ + private FrontEnd frontEnd; + + /** + * Properties of this project. + */ + private Properties properties = new Properties(); /** * Parent project to this project, if one exists. @@ -46,13 +67,18 @@ public class Project { * as the value. */ private Hashtable targets = new Hashtable(); + + /** + * TaskManager for this project. + */ + private TaskManager taskManager = new TaskManager(this); // ----------------------------------------------------------------- - // PUBLIC ACCESSOR METHODS + // PUBLIC METHODS // ----------------------------------------------------------------- /** - * + * Adds a target to this project. */ public void addTarget(Target target) { // XXX check out for name, if null, reject! @@ -60,11 +86,33 @@ public class Project { } /** - * + * Returns the base directory of this project. + */ + public File getBaseDir() { + return baseDir; + } + + /** + * Returns the default target for this project, if there is one. Otherwise + * it returns null. */ - public PrintStream getOutput() { - // XXX check if null!!!!???? - return out; + public String getDefaultTargetName() { + return defaultTargetName; + } + + /** + * Returns a short description of this project, if any. If not, returns + * null. + */ + public String getDescription() { + return description; + } + + /** + * Gets the front end that is running this project. + */ + public FrontEnd getFrontEnd() { + return frontEnd; } /** @@ -85,42 +133,140 @@ public class Project { } /** - * + * Gets an exumeration of all the targets that are part of this project. */ public Enumeration getTargets() { return targets.elements(); } /** - * + * Gets the name of this project. */ public String getName() { return name; } /** - * + * Returns the value of a property. Returns null if the property does + * not exist. */ - public void setAnt(Ant ant) { - this.ant = ant; + public String getProperty(String propertyName) { + return properties.getProperty(propertyName); } /** * */ - public void setOutput(PrintStream out) { - this.out = out; + //public void setAnt(Ant ant) { + // this.ant = ant; + //} + + /** + * Sets the base dir for this project. + */ + public void setBaseDir(File dir) { + // XXX should check this to make sure it's a dir! + baseDir = dir; } /** - * + * Sets the default target for this project. + */ + public void setDefaultTargetName(String targetName) { + defaultTargetName = targetName; + } + + /** + * Sets the description for this project. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Sets the front end for this project. + */ + public void setFrontEnd(FrontEnd frontEnd) { + this.frontEnd = frontEnd; + } + + /** + * Sets the name of this project. */ public void setName(String name) { this.name = name; } + + /** + * Sets a property on this project. If the property is already + * set, this method will override it. + */ + public void setProperty(String propertyName, String propertyValue) { + properties.put(propertyName, propertyValue); + } /** - * + * Starts a build of this project using the default target if one + * is set. + */ + public void startBuild() throws AntException { + // XXX need to do something if the default target isn't set.. + // maybe look for target name 'default', then bail? + startBuild(defaultTargetName); + } + + /** + * Starts a build of this project with the entry point at the given + * target. + */ + public void startBuild(String targetName) throws AntException { + + // notify FrontEnd that we are starting a build on a project + frontEnd.notifyProjectStart(this); + + Target target = getTarget(targetName); + //TaskManager taskManager = ant.getTaskManager(); + + frontEnd.notifyTargetStart(target); + + // XXX don't forget to execute dependancies first! + + Enumeration enum = target.getTasks().elements(); + while (enum.hasMoreElements()) { + Task task = (Task)enum.nextElement(); + frontEnd.notifyTaskStart(task); + try { + AbstractTask aTask = taskManager.getTaskInstance(task.getType()); + aTask.setProject(this); + aTask.setAttributes(task.getAttributes()); + boolean b = aTask.execute(); + if (!b) { + String msg = "Task " + task.getType() + " failed"; + AntException ae = new AntException(msg); + throw ae; + } + } catch (Exception e) { + AntException ae; + if (!(e instanceof AntException)) { + ae = new AntException(e); + } else { + ae = (AntException)e; + } + ae.setProject(this); + ae.setTarget(target); + ae.setTask(task); + throw ae; + } + frontEnd.notifyTaskEnd(task); + } + + // notify frontEnd that we are done + frontEnd.notifyTargetEnd(target); + frontEnd.notifyProjectEnd(this); + } + + /** + * Givens a string representation of this object. Useful for debugging. */ public String toString() { return "Project name=" + name; diff --git a/proposal/anteater/source/main/org/apache/ant/ProjectBuilder.java b/proposal/anteater/source/main/org/apache/ant/ProjectBuilder.java index ad9e50d8d..1ce8ff53a 100644 --- a/proposal/anteater/source/main/org/apache/ant/ProjectBuilder.java +++ b/proposal/anteater/source/main/org/apache/ant/ProjectBuilder.java @@ -5,6 +5,7 @@ package org.apache.ant; import java.io.*; +import java.util.*; import javax.xml.parsers.*; import org.xml.sax.*; @@ -16,46 +17,86 @@ import org.xml.sax.*; * * @author James Duncan Davidson (duncan@apache.org) */ -class ProjectBuilder { - +public class ProjectBuilder { + + // ----------------------------------------------------------------- + // PRIVATE MEMBERS + // ----------------------------------------------------------------- + + /** + * + */ + //private Ant ant; + + /** + * + */ + private FrontEnd frontEnd; + + /** + * + */ private SAXParserFactory parserFactory; // ----------------------------------------------------------------- // CONSTRUCTORS // ----------------------------------------------------------------- - ProjectBuilder() { + + /** + * Creates a new project builder that will build projects for the given + * Ant. + */ + public ProjectBuilder(FrontEnd frontEnd) { + this.frontEnd = frontEnd; parserFactory = SAXParserFactory.newInstance(); parserFactory.setValidating(false); } - Project buildFromFile(File file) throws AntException { + /** + * Builds a project from the given file. + */ + public Project buildFromFile(File file) throws AntException { try { SAXParser parser = parserFactory.newSAXParser(); BuilderHandlerBase bhb = new BuilderHandlerBase(); + bhb.setProjectFileLocation(file); parser.parse(file, bhb); - return bhb.getProject(); + Project project = bhb.getProject(); + project.setFrontEnd(frontEnd); + return project; } catch (ParserConfigurationException pce) { - throw new AntException(pce.getMessage()); + throw new AntException(pce); } catch (SAXException se) { - System.out.println(se); - System.out.println(se.getMessage()); - throw new AntException(se.getMessage()); + Exception e = se.getException(); + if (e != null && e instanceof AntException) { + // it's one of our own thrown from inside the parser to stop it + throw (AntException)e; + } + throw new AntException(se); } catch (IOException ioe) { - throw new AntException(ioe.getMessage()); + throw new AntException(ioe); } } + /** + * Inner class that implements the needed SAX methods to get all the + * data needed out of a build file. + */ class BuilderHandlerBase extends HandlerBase { private static final int STATE_START = 0; private static final int STATE_PROJECT = 1; private static final int STATE_TARGET = 2; private static final int STATE_TASK = 3; + private static final int STATE_DESCRIPTION = 4; + private static final int STATE_PROPERTY = 5; private static final int STATE_FINISHED = 99; private int state = STATE_START; + private Vector tagCharDataStack = new Vector(); + private Target currentTarget; private Task currentTask; @@ -65,42 +106,98 @@ class ProjectBuilder { return project; } + void setProjectFileLocation(File file) { + project.setBaseDir(file.getParentFile()); + } + public void startElement(String name, AttributeList atts) throws SAXException { - //System.out.println("element: " + name); + + StringBuffer tagCharData = new StringBuffer(); + tagCharDataStack.insertElementAt(tagCharData, 0); switch (state) { + case STATE_START: if (name.equals("project")) { state = STATE_PROJECT; String projectName = atts.getValue("name"); - if (projectName == null) { - System.out.println("Projects *must* have names"); - // XXX exception out + if (projectName != null) { + project.setName(projectName); + } else { + String msg = "Project element doesn't contain a name attribute"; + AntException ae = new AntException(msg); + throw new SAXException(ae); + } + String defaultTarget = atts.getValue("default"); + if (defaultTarget != null) { + project.setDefaultTargetName(defaultTarget); + } + String baseDirName = atts.getValue("basedir"); + if (baseDirName != null) { + // XXX need to check to see if base dir exists + project.setBaseDir(new File(baseDirName)); } - project.setName(projectName); } else { - System.out.println("Expecting project, got: " + name); - // XXX exception out + String msg = "Project file doesn't contain a project element as " + + "its root node"; + AntException ae = new AntException(msg); + throw new SAXException(ae); } break; + case STATE_PROJECT: - if (name.equals("target")) { + + // valid tags in a project object are: description, property, and target + + if (name.equals("description")) { + state = STATE_DESCRIPTION; + } else if (name.equals("property")) { + state = STATE_PROPERTY; + String propertyName = atts.getValue("name"); + String propertyValue = atts.getValue("value"); + if (propertyName == null) { + String msg = "Name attribute must be present on property"; + AntException ae = new AntException(msg); + throw new SAXException(ae); + } else if (propertyValue == null) { + String msg = "Value attribute must be present on property"; + AntException ae = new AntException(msg); + throw new SAXException(ae); + } else { + project.setProperty(propertyName, propertyValue); + } + } else if (name.equals("target")) { state = STATE_TARGET; String targetName = atts.getValue("name"); - if (targetName == null) { - System.out.println("Targets *must* have names"); - // XXX exception out + if (targetName != null) { + currentTarget = new Target(targetName); + project.addTarget(currentTarget); + } else { + // XXX figure out which target we're talking about! + // Like a location + String msg = "Target element doesn't contain a name attribute"; + AntException ae = new AntException(msg); + throw new SAXException(ae); + } + String depends = atts.getValue("depends"); + if (depends != null) { + StringTokenizer tok = new StringTokenizer(depends, ",", false); + while(tok.hasMoreTokens()) { + currentTarget.addDependancy(tok.nextToken().trim()); + } } - currentTarget = new Target(targetName); - project.addTarget(currentTarget); - + // XXX add dependency checks } else { System.out.println("Expecting target, got: " + name); // XXX exception out } break; + case STATE_TARGET: + + // Valid tags inside target: task + state = STATE_TASK; //System.out.println("Getting task: " + name + " for target " + // currentTarget); @@ -114,6 +211,16 @@ class ProjectBuilder { currentTask.addAttribute(atName, atValue); } break; + + case STATE_TASK: + + // data in here needs to be reflected into tasks + + System.out.println("Not yet supporting tags inside of tasks!"); + System.out.println("The project build will probably bust right here"); + + break; + default: System.out.println("I'm not sure, but we're off base here: " + name); // XXX exception out @@ -121,14 +228,21 @@ class ProjectBuilder { } public void characters(char ch[], int start, int length) throws SAXException { + StringBuffer buf = (StringBuffer)tagCharDataStack.elementAt(0); + buf.append(ch, start, length); } public void endElement(String name) throws SAXException { - // System.out.println("end: " + name); + + StringBuffer elementData = (StringBuffer)tagCharDataStack.elementAt(0); + tagCharDataStack.removeElementAt(0); + switch (state) { + case STATE_TASK: state = STATE_TARGET; break; + case STATE_TARGET: if (name.equals("target")) { state = STATE_PROJECT; @@ -137,6 +251,27 @@ class ProjectBuilder { // XXX exception out. } break; + + case STATE_DESCRIPTION: + if (name.equals("description")) { + state = STATE_PROJECT; + project.setDescription(elementData.toString().trim()); + } else { + System.out.println("Expecting to get an end of description, got: " + + name); + // XXX exception out. + } + break; + + case STATE_PROPERTY: + if (name.equals("property")) { + state = STATE_PROJECT; + } else { + System.out.println("Expecting to get end of property, got: " + name); + // XXX exception out + } + break; + case STATE_PROJECT: if (name.equals("project")) { state = STATE_FINISHED; @@ -145,6 +280,7 @@ class ProjectBuilder { // XXX exception out; } break; + default: System.out.println("I'm not sure what we are ending here: " + name); // XXX exception out; diff --git a/proposal/anteater/source/main/org/apache/ant/Target.java b/proposal/anteater/source/main/org/apache/ant/Target.java index 41b5260c5..4d5c98afc 100644 --- a/proposal/anteater/source/main/org/apache/ant/Target.java +++ b/proposal/anteater/source/main/org/apache/ant/Target.java @@ -22,6 +22,12 @@ public class Target { */ private String name; + /** + * Vector containing the names of the targets that this target + * depends on. + */ + private Vector dependsList = new Vector(); + /** * Vector containing the tasks that are part of this target. */ @@ -42,6 +48,13 @@ public class Target { // PUBLIC ACCESSOR METHODS // ----------------------------------------------------------------- + /** + * Adds a dependancy to this task. + */ + public void addDependancy(String targetName) { + dependsList.addElement(targetName); + } + /** * */ diff --git a/proposal/anteater/source/main/org/apache/ant/TaskManager.java b/proposal/anteater/source/main/org/apache/ant/TaskManager.java index 1c328677c..70dfac25e 100644 --- a/proposal/anteater/source/main/org/apache/ant/TaskManager.java +++ b/proposal/anteater/source/main/org/apache/ant/TaskManager.java @@ -23,6 +23,16 @@ class TaskManager { // PRIVATE DATA MEMBERS // ----------------------------------------------------------------- + /** + * Reference to Ant that holds this TaskManager + */ + //private Ant ant; + + /** + * Project to which this task manger belongs. + */ + private Project project; + /** * Data structure where all the Class definition for all known tasks are * held. @@ -41,7 +51,8 @@ class TaskManager { /** * Creates a new TaskManager. */ - TaskManager() { + TaskManager(Project project) { + this.project = project; } // ----------------------------------------------------------------- @@ -59,16 +70,15 @@ class TaskManager { /** * */ - AbstractTask getTaskInstance(String taskName) { + AbstractTask getTaskInstance(String taskName) throws AntException { Class clazz = (Class)taskClasses.get(taskName); try { return (AbstractTask)clazz.newInstance(); - } catch (Exception e) { - System.out.println("Can't instantiate task: " + taskName); - System.out.println(e); - // XXX error out and stop + } catch (Exception e) { + String msg = "Can't instantiate task: " + taskName; + AntException ae = new AntException(msg, e); + throw ae; } - return null; } // ----------------------------------------------------------------- @@ -94,7 +104,8 @@ class TaskManager { * Processes a directory to get class defintions from it */ private void processDir(File dir) { - System.out.println("Scanning " + dir + " for tasks"); + project.getFrontEnd().writeMessage("Scanning " + dir + " for tasks", + FrontEnd.MSG_LEVEL_LOW); File file = new File(dir, "taskdef.properties"); if (file.exists()) { try { @@ -110,7 +121,8 @@ class TaskManager { URLClassLoader loader = new URLClassLoader(new URL[] {dir.toURL()}); try { Class clazz = loader.loadClass(taskClass); - System.out.println("Got task: " + taskName + " " + clazz); + project.getFrontEnd().writeMessage("Got Task: " + taskName + + clazz, FrontEnd.MSG_LEVEL_LOW); taskClasses.put(taskName, clazz); } catch (ClassNotFoundException cnfe) { System.out.println("Couldn't load task: " + taskName); @@ -130,7 +142,8 @@ class TaskManager { * Processes a jar file to get class definitions from it */ private void processJar(File file) { - System.out.println("Scanning " + file + " for tasks"); + project.getFrontEnd().writeMessage("Scanning " + file + " for tasks", + FrontEnd.MSG_LEVEL_LOW); try { ZipFile zipFile = new ZipFile(file); ZipEntry zipEntry = zipFile.getEntry("taskdef.properties"); @@ -147,7 +160,8 @@ class TaskManager { URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()}); try { Class clazz = loader.loadClass(taskClass); - System.out.println("Got Task: " + taskName + " " + clazz); + project.getFrontEnd().writeMessage("Got Task: " + taskName + + clazz, FrontEnd.MSG_LEVEL_LOW); taskClasses.put(taskName, clazz); } catch (ClassNotFoundException cnfe) { System.out.println("Couldn't load task: " + taskName); diff --git a/proposal/anteater/source/main/org/apache/ant/cli/CLIFrontEnd.java b/proposal/anteater/source/main/org/apache/ant/cli/CLIFrontEnd.java index e8ee0ad73..6fa991848 100644 --- a/proposal/anteater/source/main/org/apache/ant/cli/CLIFrontEnd.java +++ b/proposal/anteater/source/main/org/apache/ant/cli/CLIFrontEnd.java @@ -14,7 +14,7 @@ import org.apache.ant.*; * * @author James Duncan Davidson (duncan@apache.org) */ -public class CLIFrontEnd extends AntFrontEnd { +public class CLIFrontEnd extends FrontEnd { // ----------------------------------------------------------------- // PRIVATE MEMBERS @@ -23,22 +23,28 @@ public class CLIFrontEnd extends AntFrontEnd { /** * */ - private Ant ant; + //private Ant ant; /** * */ - private int msgLevel = MSG_LEVEL_MED; + private String[] args; + + /** + * + */ + private int msgLevelFilter = MSG_LEVEL_MED; // ----------------------------------------------------------------- // CONSTRUCTORS // ----------------------------------------------------------------- /** - * + * Creates a new CLIFrontEnd that can drive an Ant build from the Command + * Line. */ public CLIFrontEnd() { - ant = new Ant(this); + //ant = new Ant(this); } // ----------------------------------------------------------------- @@ -98,74 +104,84 @@ public class CLIFrontEnd extends AntFrontEnd { writeMessage("Task End: " + task.getType(), MSG_LEVEL_LOW); } - /** - * Prints help to System.out - */ - private void printHelp() { - String ls = System.getProperty("line.separator"); - String msg = "Usage: ant [args] [target]" + ls + - " Arguments can be any of the following:" + ls + - " -help" + ls + - " -taskpath [path]" + ls + - " -buildfile [file]" +ls + - " -verbose" + ls + - " -quiet" + ls + ls + - " Note that if no buildfile argument is given, Ant will"+ls+ - " try to find one in the current directory. If there are"+ls+ - " two or more buildfiles in the current directory, it" +ls+ - " will bail."; - writeMessage(msg); - } - /** * */ public void run(String[] args) { + this.args = args; String target = ""; + File buildFile = null; writeMessage("Ant(Eater) -- Proposed Ant 2.0"); - // flip through args and set things accordingly - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - // scan through -- all -aaa args come first. - if (arg.startsWith("-")) { - if (arg.equals("-help")) { - printHelp(); - return; - } else if (arg.equals("-taskpath")) { - // XXX - // need to seperate on pathsep, but not today - ant.addTaskPathNode(new File(args[++i])); - } else if (arg.equals("-buildfile")) { - // XXX - // need to check file to make sure it exists! - try { - ant.setBuildfile(new File(args[++i])); - } catch (AntException ae) { - writeMessage("ICK: " + ae); - writeMessage(ae.getMessage()); - return; - } - } + // process through the args set + + if (isArg("help")) { + printHelp(); + return; + } + + if (isArg("quiet")) { + msgLevelFilter = MSG_LEVEL_HIGH; + } + + if (isArg("verbose")) { + msgLevelFilter = MSG_LEVEL_LOW; + } + + String argTaskpath = getArgValue("taskpath"); + if (argTaskpath != null) { + if (argTaskpath.equals("")) { + writeMessage("Must give a value for -taskpath"); + return; } else { - target = arg; + // XXX need to separate on path seps so that real paths can be taken + // ant.addTaskPathNode(new File(argTaskpath)); } } + String argBuildfile = getArgValue("buildfile"); + if (argBuildfile != null) { + if (argBuildfile.equals("")) { + writeMessage("Must give a value for -buildfile"); + return; + } else { + //try { + buildFile = new File(argBuildfile); + //ant.setBuildfile(new File(argBuildfile)); + //} catch (AntException ae) { + // writeMessage("Can't set buildfile"); + // writeMessage(ae.toString()); + // return; + //} + } + } + + target = getTargetArg(); + // XXX do something if we dont' have a buildfile set! // XXX really should check to make sure that the target is set to something - - // set our listeners on the project - - Project project = ant.getProject(); - project.setOutput(System.out); + // like get the default... try { - ant.buildTarget(target); - } catch (AntException ae) { - writeMessage("Problem while building: " + ae); + ProjectBuilder projectBuilder = new ProjectBuilder(this); + Project project = projectBuilder.buildFromFile(buildFile); + //Project project = ant.getProject(); + + // XXX + // get taskmanager from project and set taskpath nodes on it! + + project.setFrontEnd(this); + project.startBuild(target); + } catch (AntException ae) { + writeMessage("Build Stopped"); + writeMessage(" Project: " + ae.getProject().getName()); + writeMessage(" Target: " + ae.getTarget().getName()); + writeMessage(" Task Type: " + ae.getTask().getType()); + writeMessage("Details Follow"); + writeMessage(""); writeMessage(ae.getMessage()); + ae.printStackTrace(System.out); } } @@ -173,10 +189,100 @@ public class CLIFrontEnd extends AntFrontEnd { * Writes a message to the front end. */ public void writeMessage(String message, int level) { - if (level >= msgLevel) { + if (level >= msgLevelFilter) { System.out.println(message); } } - - + + // ----------------------------------------------------------------- + // PRIVATE METHODS + // ----------------------------------------------------------------- + + /** + * Returns the value for a given argument name, null if the argument + * name isn't in the argument set, or "" if the argument doesn't have + * a value. + */ + private String getArgValue(String argName) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-" + argName)) { + if (i != args.length - 1) { + return args[i + 1]; + } else { + return ""; + } + } + } + return null; + } + + /** + * Returns the target that was requested to be built, if any. If no + * target is determined, returns null. + */ + public String getTargetArg() { + String possibleTarget = getArgValue("target"); + if (possibleTarget != null) { + if (possibleTarget.equals("")) { + writeMessage("Must give a value for -target"); + } else { + return possibleTarget; + } + } + + possibleTarget = args[args.length - 1]; + if (possibleTarget.startsWith("-")) { + return null; + } + if (args[args.length - 2].startsWith("-")) { + // our possible target might be an arg value instead of a target + // XXX ugh -- there has to be a better way here. We need to hold + // a list of all args that don't have values somewhere. + if (args[args.length - 2].equals("-help") || + args[args.length - 2].equals("-verbose") || + args[args.length - 2].equals("-quiet")) { + // we're ok, the arg before the possible target doesn't have a value + return possibleTarget; + } else { + return null; + } + } else { + return possibleTarget; + } + } + + /** + * Indicates whether or not a given argument name exists in the argument + * set. + */ + private boolean isArg(String argName) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-" + argName)) { + return true; + } + } + return false; + } + + /** + * Prints help to System.out + */ + private void printHelp() { + + // XXX resource bundle this. + + String ls = System.getProperty("line.separator"); + String msg = "Usage: ant [args] [target]" + ls + + " Arguments can be any of the following:" + ls + + " -help" + ls + + " -taskpath [path]" + ls + + " -buildfile [file]" +ls + + " -verbose" + ls + + " -quiet" + ls + ls + + " Note that if no buildfile argument is given, Ant will"+ls+ + " try to find one in the current directory. If there are"+ls+ + " two or more buildfiles in the current directory, it" +ls+ + " will bail."; + writeMessage(msg); + } } \ No newline at end of file diff --git a/proposal/anteater/source/main/org/apache/ant/cli/Main.java b/proposal/anteater/source/main/org/apache/ant/cli/Main.java index 844d04e8b..7a81b89b2 100644 Binary files a/proposal/anteater/source/main/org/apache/ant/cli/Main.java and b/proposal/anteater/source/main/org/apache/ant/cli/Main.java differ