package fr.jayasoft.ivy.ant; | |
import java.io.File; | |
import java.io.InputStream; | |
import java.io.PrintStream; | |
import java.util.Vector; | |
import junit.framework.TestCase; | |
import org.apache.tools.ant.BuildException; | |
import org.apache.tools.ant.BuildLogger; | |
import org.apache.tools.ant.DefaultLogger; | |
import org.apache.tools.ant.DemuxInputStream; | |
import org.apache.tools.ant.DemuxOutputStream; | |
import org.apache.tools.ant.Main; | |
import org.apache.tools.ant.Project; | |
import org.apache.tools.ant.ProjectHelper; | |
import org.apache.tools.ant.input.DefaultInputHandler; | |
import org.apache.tools.ant.input.InputHandler; | |
import fr.jayasoft.ivy.util.FileUtil; | |
public class AntCallTriggerTest extends TestCase { | |
public void test() throws Exception { | |
assertFalse(new File("test/triggers/ant-call/A/out/foo.txt").exists()); | |
runAnt(new File("test/triggers/ant-call/A/build.xml"), "resolve"); | |
// should have unzipped foo.zip | |
assertTrue(new File("test/triggers/ant-call/A/out/foo.txt").exists()); | |
} | |
protected void tearDown() throws Exception { | |
FileUtil.forceDelete(new File("test/triggers/ant-call/A/out")); | |
FileUtil.forceDelete(new File("test/triggers/ant-call/cache")); | |
} | |
private void runAnt(File buildFile, String target) throws BuildException { | |
runAnt(buildFile, target, Project.MSG_INFO); | |
} | |
private void runAnt(File buildFile, String target, int messageLevel) throws BuildException { | |
Vector targets = new Vector(); | |
targets.add(target); | |
runAnt(buildFile, targets, messageLevel); | |
} | |
private void runAnt(File buildFile, Vector targets, int messageLevel) throws BuildException { | |
runBuild(buildFile, targets, messageLevel); | |
// this exits the jvm at the end of the call | |
// Main.main(new String[] {"-f", buildFile.getAbsolutePath(), target}); | |
// this does not set the good message level | |
// Ant ant = new Ant(); | |
// Project project = new Project(); | |
// project.setBaseDir(buildFile.getParentFile()); | |
// project.init(); | |
// | |
// ant.setProject(project); | |
// ant.setTaskName("ant"); | |
// | |
// ant.setAntfile(buildFile.getAbsolutePath()); | |
// ant.setInheritAll(false); | |
// if (target != null) { | |
// ant.setTarget(target); | |
// } | |
// ant.execute(); | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
// miserable copy (updated to simple test cases) from ant Main class: | |
// the only available way I found to easily run ant exits jvm at the end | |
private void runBuild(File buildFile, Vector targets, int messageLevel) throws BuildException { | |
final Project project = new Project(); | |
project.setCoreLoader(null); | |
Throwable error = null; | |
try { | |
addBuildListeners(project, messageLevel); | |
addInputHandler(project, null); | |
PrintStream err = System.err; | |
PrintStream out = System.out; | |
InputStream in = System.in; | |
// use a system manager that prevents from System.exit() | |
SecurityManager oldsm = null; | |
oldsm = System.getSecurityManager(); | |
//SecurityManager can not be installed here for backwards | |
//compatibility reasons (PD). Needs to be loaded prior to | |
//ant class if we are going to implement it. | |
//System.setSecurityManager(new NoExitSecurityManager()); | |
try { | |
project.setDefaultInputStream(System.in); | |
System.setIn(new DemuxInputStream(project)); | |
System.setOut(new PrintStream(new DemuxOutputStream(project, false))); | |
System.setErr(new PrintStream(new DemuxOutputStream(project, true))); | |
project.fireBuildStarted(); | |
project.init(); | |
project.setUserProperty("ant.version", Main.getAntVersion()); | |
project.setUserProperty("ant.file", | |
buildFile.getAbsolutePath()); | |
ProjectHelper.configureProject(project, buildFile); | |
// make sure that we have a target to execute | |
if (targets.size() == 0) { | |
if (project.getDefaultTarget() != null) { | |
targets.addElement(project.getDefaultTarget()); | |
} | |
} | |
project.executeTargets(targets); | |
} finally { | |
// put back the original security manager | |
//The following will never eval to true. (PD) | |
if (oldsm != null) { | |
System.setSecurityManager(oldsm); | |
} | |
System.setOut(out); | |
System.setErr(err); | |
System.setIn(in); | |
} | |
} catch (RuntimeException exc) { | |
error = exc; | |
throw exc; | |
} catch (Error err) { | |
error = err; | |
throw err; | |
} finally { | |
project.fireBuildFinished(error); | |
} | |
} | |
/** | |
* Adds the listeners specified in the command line arguments, | |
* along with the default listener, to the specified project. | |
* | |
* @param project The project to add listeners to. | |
* Must not be <code>null</code>. | |
*/ | |
protected void addBuildListeners(Project project, int level) { | |
// Add the default listener | |
project.addBuildListener(createLogger(level)); | |
} | |
/** | |
* Creates the InputHandler and adds it to the project. | |
* | |
* @param project the project instance. | |
* @param inputHandlerClassname | |
* | |
* @exception BuildException if a specified InputHandler | |
* implementation could not be loaded. | |
*/ | |
private void addInputHandler(Project project, String inputHandlerClassname) throws BuildException { | |
InputHandler handler = null; | |
if (inputHandlerClassname == null) { | |
handler = new DefaultInputHandler(); | |
} else { | |
try { | |
handler = (InputHandler) | |
(Class.forName(inputHandlerClassname).newInstance()); | |
if (project != null) { | |
project.setProjectReference(handler); | |
} | |
} catch (ClassCastException e) { | |
String msg = "The specified input handler class " | |
+ inputHandlerClassname | |
+ " does not implement the InputHandler interface"; | |
throw new BuildException(msg); | |
} catch (Exception e) { | |
String msg = "Unable to instantiate specified input handler " | |
+ "class " + inputHandlerClassname + " : " | |
+ e.getClass().getName(); | |
throw new BuildException(msg); | |
} | |
} | |
project.setInputHandler(handler); | |
} | |
// XXX: (Jon Skeet) Any reason for writing a message and then using a bare | |
// RuntimeException rather than just using a BuildException here? Is it | |
// in case the message could end up being written to no loggers (as the | |
// loggers could have failed to be created due to this failure)? | |
/** | |
* Creates the default build logger for sending build events to the ant | |
* log. | |
* | |
* @return the logger instance for this build. | |
*/ | |
private BuildLogger createLogger(int level) { | |
BuildLogger logger = null; | |
logger = new DefaultLogger(); | |
logger.setMessageOutputLevel(level); | |
logger.setOutputPrintStream(System.out); | |
logger.setErrorPrintStream(System.err); | |
return logger; | |
} | |
} |