blob: 02a504a29fb85769c749142f5f96315b6ced4f8d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.ant;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Vector;
import org.apache.ivy.util.FileUtil;
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 junit.framework.TestCase;
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;
}
}