Сделать ant тихим без флага -q?
У меня есть файл сборки ant, который часто запускается из совершенно разных сред. По умолчанию я ищу то же поведение, что и при использовании:
ant -q
Однако, поскольку некоторые конфигурации членов команды различаются, указание опции -q в каждой среде человека выполняется нелегко единообразным способом (некоторые из них запускают ant из eclipse, некоторые из командной строки, некоторые - от отладки/профилирования инструменты и т.д. Каждый с другим методом для указания аргументов ant типа -q)
Итак, я ищу способ для файла ant для вызова себя спокойно...
Что-то вроде следующего было бы идеальным:
<target name="default">
<antcall quiet="yes" target="build" /> <!-- doesn't work -->
</target>
Может ли кто-нибудь подумать о том, чтобы добиться чего-то подобного? Все, что мне нужно, - это запустить сборку, когда запускается цель по умолчанию, независимо от того, установлен ли -q.
Ответы
Ответ 1
Один из вариантов может заключаться в том, чтобы установить уровень ведения журнала в пределах целевого объекта.
Доступ к регистраторам возможен с помощью короткой задачи script. Что-то вроде:
<target ... >
<script language="javascript">
var logger = project.getBuildListeners( ).firstElement( );
logger.setMessageOutputLevel( 0 );
</script>
...
</target>
Я не знаком с тем, как Eclipse вызывает Ant, но может потребоваться перебрать все слушатели сборки, чтобы получить "тишину".
Предложите, чтобы как-то вы в конечном итоге это сделали, вы легко переключаетесь обратно на многословную работу.
Изменить - ответ на комментарий: вы можете получить доступ к свойствам проекта из script с помощью project.getProperty()
:
<property name="verboseFlag" value="1" />
<script language="javascript">
var logger = project.getBuildListeners().firstElement();
var verboseMode = project.getProperty( "verboseFlag" )
if ( ! "1".equals( verboseMode ) )
logger.setMessageOutputLevel( 0 );
</script>
(несколько старый) API-документы здесь, в том числе для project
класс.
Ответ 2
Для управления уровнем входа из ant script вы можете выполнить эту простую задачу =
public class SetLogLevel extends Task
{
private int logLevel = -1;
public void execute()
{
if (logLevel == -1)
{
throw new BuildException("Error - No Loglevel specified !!");
}
Vector listeners = this.getProject().getBuildListeners();
for (Iterator i = listeners.iterator(); i.hasNext();)
{
BuildListener listener = (BuildListener) i.next();
if (listener instanceof BuildLogger)
{
BuildLogger logger = (BuildLogger) listener;
logger.setMessageOutputLevel(logLevel);
}
}
}
/**
*
* @see org.apache.tools.ant.taskdefs.Echo$EchoLevel
*
*/
public void setLevel(EchoLevel echoLevel) {
String option = echoLevel.getValue();
if (option.equals("error")) {
logLevel = Project.MSG_ERR;
} else if (option.equals("warning")) {
logLevel = Project.MSG_WARN;
} else if (option.equals("info")) {
logLevel = Project.MSG_INFO;
} else if (option.equals("verbose")) {
logLevel = Project.MSG_VERBOSE;
} else {
// must be "debug"
logLevel = Project.MSG_DEBUG;
}
}
}
сопоставьте его с taskdef и используйте его так:
<setloglevel level="error"/>
... должны быть указаны только ошибки
<setloglevel level="info" />
... снова информация о loglevel
Это то, что я делаю, чтобы сократить лог файлы при использовании разговорных задач, таких как f.e. Задача cvs
Ответ 3
Основываясь на других ответах:
<macrodef name="quiet">
<element name="body" implicit="yes"/>
<sequential>
<script language="javascript">
project.getBuildListeners().firstElement().setMessageOutputLevel(0);
</script>
<body/>
<script language="javascript">
// TODO: restore last log level
project.getBuildListeners().firstElement().setMessageOutputLevel(2);
</script>
</sequential>
</macrodef>
<target name="test-quiet">
<quiet>
<echoproperties/>
</quiet>
</target>
Ответ 4
После прочтения ответа Мартина, я думаю, что наиболее удобно помещать весь материал в скриптdef. Здесь решение с groovy=
<project>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<!-- testproperty referenced from verboseflag attribute
comment out to make it unset -->
<property name="someverboseflag" value="whatever"/>
<scriptdef name="setloglevel" language="groovy">
<attribute name="loglevel"/>
<attribute name="verboseflag"/>
switch (attributes.'loglevel') {
case 'error':
project.getBuildListeners()[0].setMessageOutputLevel(0)
break
case 'warn':
project.getBuildListeners()[0].setMessageOutputLevel(1)
break
case 'info':
project.getBuildListeners()[0].setMessageOutputLevel(2)
break
case 'verbose':
project.getBuildListeners()[0].setMessageOutputLevel(3)
break
case 'debug':
project.getBuildListeners()[0].setMessageOutputLevel(4)
break
}
if (project.getProperty(attributes.'verboseflag') == null)
{
println "Property " + attributes.'verboseflag' + " not set, default => Loglevel WARN !"
project.getBuildListeners()[0].setMessageOutputLevel(1)
}
</scriptdef>
<!-- the loglevel given in attribute loglevel is only used
when verboseflag attribute is set, otherwise
loglevel WARN is used -->
<setloglevel loglevel="debug" verboseflag="someverboseflag"/>
<!-- test -->
<echo level="error">getting logged when Loglevel ERROR and higher..</echo>
<echo level="warning">getting logged when Loglevel WARN and higher..</echo>
<echo level="info">getting logged when Loglevel INFO and higher..</echo>
<echo level="verbose">getting logged when Loglevel VERBOSE and higher..</echo>
<echo level="debug">getting logged when Loglevel DEBUG..</echo>
</project>
Каждый язык сценариев, работающий с Bean Scipting Framework в Java VM, может использоваться для сценариев в ant с полным доступом к ant api - это вопрос вкуса. Используется Javascript, Beanshell, (J) ruby до и в последнее время переключился на Groovy.