Ant 在没有-q标志的情况下让蚂蚁安静?

Ant 在没有-q标志的情况下让蚂蚁安静?,ant,build,build-process,Ant,Build,Build Process,我有一个ant构建文件,它通常运行在完全不同的环境中。默认情况下,我寻找的行为与使用: ant -q 但是,由于一些团队成员的配置不同,在每个人的环境中指定-q选项并不容易以统一的方式完成(有些人从eclipse运行ant,有些人从命令行运行,有些人从调试/分析工具运行,等等。每个人都使用不同的方法指定ant参数,如-q) 因此,我正在寻找一种方法,让ant文件安静地调用本身 类似于以下内容的内容将是理想的: <target name="default"> <antc

我有一个ant构建文件,它通常运行在完全不同的环境中。默认情况下,我寻找的行为与使用:

ant -q
但是,由于一些团队成员的配置不同,在每个人的环境中指定-q选项并不容易以统一的方式完成(有些人从eclipse运行ant,有些人从命令行运行,有些人从调试/分析工具运行,等等。每个人都使用不同的方法指定ant参数,如-q

因此,我正在寻找一种方法,让ant文件安静地调用本身

类似于以下内容的内容将是理想的:

<target name="default">
    <antcall quiet="yes" target="build" /> <!-- doesn't work -->
</target>


有人能想出办法来完成这样的事情吗?我所追求的是,无论是否设置了-q,只要运行默认目标,构建就可以安静地运行。

要从ant脚本中控制日志级别,您可以执行以下简单任务=

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" />

。。。再次输入日志级别信息


这就是我在使用f.e.cvs task之类的对话任务时缩短日志文件的方法。一个选项可能是从目标内设置日志记录级别

您可以通过短脚本任务访问记录器。比如:

<target ... >
    <script language="javascript">
        var logger = project.getBuildListeners( ).firstElement( );
        logger.setMessageOutputLevel( 0 );
    </script>
    ...
</target>

(有点老了),包括。

在阅读了马丁的答案后,我认为把全部内容放在脚本中是最舒服的。下面是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>

开关(属性为“日志级别”){
案例“错误”:
project.getBuildListeners()[0]。setMessageOutputLevel(0)
打破
“警告”案例:
project.getBuildListeners()[0]。setMessageOutputLevel(1)
打破
案例“信息”:
project.getBuildListeners()[0]。setMessageOutputLevel(2)
打破
案例“详细”:
project.getBuildListeners()[0]。setMessageOutputLevel(3)
打破
案例“调试”:
project.getBuildListeners()[0]。setMessageOutputLevel(4)
打破
}
if(project.getProperty(attributes.verboseflag')==null)
{
println“Property”+attributes.'verboseflag'+“未设置,默认值=>日志级别警告!”
project.getBuildListeners()[0]。setMessageOutputLevel(1)
}
当日志级别错误或更高时记录。。
日志级别警告及更高时记录。。
日志级别信息和更高级别信息时被记录。。
当日志级别为VERBOSE或更高时获取日志。。
日志级别调试时正在记录。。

在Java VM中使用Bean Sciting Framework运行的每种脚本语言都可以用于在ant中编写脚本,并且可以完全访问ant api—这是一个品味问题。使用Javascript、Beanshell、(J)ruby之前和最近切换到Groovy。

基于其他答案:

<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>

project.getBuildListeners().firstElement().setMessageOutputLevel(0);
//TODO:还原上一个日志级别
project.getBuildListeners().firstElement().setMessageOutputLevel(2);

我不熟悉做这种事情(通过java扩展ant)但我会在谷歌上搜索如何使其工作的细节,然后尝试一下……基本上,这都是关于扩展org.apache.tools.ant.Task基本上,这都是关于扩展org.apache.tools.ant.Task的。通常,您有多个自编任务,并将它们放入一个jar中。在这个jar中有一个名为antlib.xml的xml文件,它在taskname和classname之间进行映射。把那个罐子放在ant的视线中,但不要简单地放在%ant_HOME%/lib中,因为你正在污染你的ant安装。最好放在一些../extralibs文件夹中,并使用-libpath/to/extralibs选项启动ant。然后在antscript中加载任务,如下所示:谢谢。这些都很有帮助。有趣的是,我的第一反应是将这个Jar放在我的ant lib目录中,因为它会有可重用的ant内容。现在,我的蚂蚁库中唯一的东西就是常春藤。我想把这个罐子放进本地的常春藤储存库会很方便,然后我可以像ant contrib一样自动检索它…@martin:wow。我甚至不知道javascript可以与Ant一起使用。太棒了。当我使用setMessageOutputLevel(1)时,只有我的echo命令被打印出来,这非常有效。这正是我想要的。现在,我所要做的就是测试这在运行Ant的其他环境(命令行、eclipse等)中是否有效。@martin:在脚本的“第2行”中,是否有一种说法类似于,
if(verboseFlagNotSet)logger.setMessageOutputLevel(1)
也就是说,您知道检查详细标志状态的方法吗?@gmale-应该可以。我在答案上加了一个例子。您可以从JS中读取(和设置)Ant属性。@马丁:谢谢您的回答,它也很有用,但是。。。对不起,我应该说得更清楚些。我所说的“verbose标志”是指-v选项。也就是说,是否有一种方法可以检测用户何时使用设置为:
ant-v-f build.xml
的详细标志调用了ant。因此,当用户指定verbose标志时,我想不使用记录器。日志级别直接传递给ants日志框架,我认为在ant启动后您无法访问它。但是你可以用+1来检查我的想法!哈哈。你可以在ant脚本中使用groovy!!!这几乎让我流口水。:-)Groovy甚至提供了自己的任务。。。。除了groovy之外,还有许多其他语言通过Ant中的Bean脚本框架运行:(J)ruby、Beanshell、Javascript(来自Mozilla的Rhino)、Jython、Judoscript。。一种语言适合每种口味/恋物癖顺便说一句。还有另一种方法,使用Groovy中的Ant,不使用xml,see=Fine,但仍然打印目标名称。
<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>