Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Coding style ant条件目标和';递归';_Coding Style_Ant_If Statement_Dependencies - Fatal编程技术网

Coding style ant条件目标和';递归';

Coding style ant条件目标和';递归';,coding-style,ant,if-statement,dependencies,Coding Style,Ant,If Statement,Dependencies,我对ant还比较陌生,我看过Bob叔叔的《直到你放弃》一集 因此,我尝试将ant目标定义得尽可能小,这样您就可以准确地看到目标的本质,不再需要更多。有关更多详细信息,请参考子目标 这种风格是好是坏是另一种争论(或者可能是一场火焰战) 因此,我创建了一个构建脚本,在伪代码中,该脚本如下所示: build = compile instrument if coverage <target name="build" depends="compile, coverage"/>

我对ant还比较陌生,我看过Bob叔叔的《直到你放弃》一集

因此,我尝试将ant目标定义得尽可能小,这样您就可以准确地看到目标的本质,不再需要更多。有关更多详细信息,请参考子目标

这种风格是好是坏是另一种争论(或者可能是一场火焰战)

因此,我创建了一个构建脚本,在伪代码中,该脚本如下所示:

build =
   compile
   instrument if coverage
<target name="build" depends="compile, coverage"/>

<target name="compile"> .... </target>

<target name="coverage" depends="
       create-coverage-dirs, 
       taskdef-cobertura"
 if="build.with.coverage">

  <cobertura-instrument ...> ... </cobertura-instrument>

</target>

<target name="create-coverage-dirs">
  ...    
</target>

<target name="taskdef-cobertura">
  ...
</target>
coverage
任务也分为子目标:

coverage:
   create-coverage-dirs
   call-cobertura
编辑-我想表示不应运行
覆盖率
子目标

但是。。。我很难用ant ese“干净”地表达这一点

假设我可以使用
depends
属性来指示。。。目标之间的依赖关系,我得到了如下结果:

build =
   compile
   instrument if coverage
<target name="build" depends="compile, coverage"/>

<target name="compile"> .... </target>

<target name="coverage" depends="
       create-coverage-dirs, 
       taskdef-cobertura"
 if="build.with.coverage">

  <cobertura-instrument ...> ... </cobertura-instrument>

</target>

<target name="create-coverage-dirs">
  ...    
</target>

<target name="taskdef-cobertura">
  ...
</target>
我可以在每个覆盖率子任务中添加
if
属性,但我觉得这并不干净

所以问题是:

  • 我的蚂蚁语是一种可怕的方言吗?我是在“把蚂蚁变成蚂蚁”吗
  • 是应该这样使用
    if
    ,还是存在
    if和recurse
    类型的属性
  • 测试属性是否存在,而不是它是否为true或false。如果不想运行覆盖率目标,则不要定义属性
    build.with.coverage

    从Ant 1.8.0开始,您可以使用属性扩展将属性响应为布尔值:

    <target name="coverage" depends="
               create-coverage-dirs, 
               taskdef-cobertura"
            if="${build.with.coverage}">
    
    
    
    测试属性是否存在,而不是它是否为真。如果不想运行覆盖率目标,则不要定义属性
    build.with.coverage

    从Ant 1.8.0开始,您可以使用属性扩展将属性响应为布尔值:

    <target name="coverage" depends="
               create-coverage-dirs, 
               taskdef-cobertura"
            if="${build.with.coverage}">
    

    在这种情况下,我根本不会使用属性,而是完全依赖于
    depends
    (对于这个任务,这对我来说似乎更自然):

    
    ...
    ...
    
    在这种情况下,我根本不会使用属性,而是完全依赖于
    depends
    (对于这个任务,这对我来说似乎更自然):

    
    ...
    ...
    
    跟我重复一遍:Ant不是一种编程语言。事实上,在黑板上写100遍

    Ant不是一种编程语言,所以不要这样认为。这是一个构建依赖关系矩阵

    程序员很难对这个想法保持清醒的头脑。他们想告诉蚂蚁每一步以及什么时候该做。他们想要循环,如果语句。他们将求助于使用
    build.sh
    脚本来调用Ant中的各种目标,因为您无法轻松编程Ant

    在Ant中,您可以指定离散任务,以及哪些任务依赖于其他任务,并让Ant处理在何时何地执行任务

    我想说的是,您通常不会将任务拆分为子任务,然后尝试调用
    。为什么?因为这是一个标准化目标名称的好方法。开发人员知道,
    clean
    将删除所有构建的工件,
    compile
    将运行
    任务,
    test
    将运行
    junit
    测试。因此,您应该使用:
    cobertura
    中的目标


    编辑 我的问题是:我认为“覆盖率”与“优化”和“调试”相关,即构建风格。这就是我的困难所在:对于Java,覆盖率会导致编译步骤中额外的中间目标

    我正在查看Corburta页面,而
    任务(编译目标的一部分)中没有实际的更改

    相反,您可以在已经构建的
    .class
    文件上运行Corburtura,然后运行
    任务。最大的变化是
    任务,它现在必须包括对Corburtura JAR和插入指令的类的引用

    我想你可以有一个
    corburtura
    目标,或者你想叫它什么。这个目标运行插入指令的JUnit测试。这是你希望开发人员达到的目标,应该包含一个描述,说明它运行插入指令的测试

    当然,如果不首先检测Junit测试,就无法运行检测后的Junit测试。因此,您的
    corburtura
    目标将依赖于另一个
    工具。测试
    目标。此目标是内部的。运行
    build.xml
    的人通常不会说“工具测试”没有运行这些测试。因此,此目标没有描述

    当然,
    instrument.tests
    目标依赖于要插入的
    .class
    文件,因此它将依赖于运行
    任务的
    编译
    目标:

    <target name="instrument.classes"
       depends="compile">
       <coburtura-instrument/>
    </target>
    
    <target name="corburtura"
       depends="instrument.classes"
       description="Runs the JUnit tests instrumented with Corburtura">
       <junit/>
    </target>
    
    
    
    唯一的问题是,您两次指定了
    目标:一次在插入指令时指定,一次用于正常测试。这可能是一个小问题。如果您更新JUnit测试的运行方式,您必须在两个位置执行

    如果要解决此问题,可以使用
    定义一个JUnit测试运行宏。我使用了页面上的内容来帮助编写大纲。完全未经测试,可能有很多语法错误:

    <target name="instrument.tests"
        depends="compile">
        <corburtura-instrument/>
    </target>
    
    <target name="corburtura"
        depends="instrument.tests"
        description="Instrument and run the JUnit tests">
    
        <run.junit.test fork.flag="true">
            <systemproperty.addition>
                <sysproperty key="net.sourceforge.corbertura.datafile"
                    file="${basedir}/cobertura.ser" />
            </systemproperty.addition>
            <pre.classpath>
                <classpath location="${instrumented.dir}" />
            </pre.classpath>
            <post.classpath>
                <classpath refid="cobertura_classpath" />
            </post.classpath>
        </run.junit.test>
    </target>
    
    <target name="test"
        description="Runs the Junit tests without any instrumentation">
        <run.junit.test/>
    </target>
    
    <macrodef name="run.junit.test">
        <attribute name="fork.flag" default="false"/>
        <element name="sysproperty.addition" optional="yes"/>
        <element name="pre.classpath" optional="yes"/>
        <element name="post.classpath" optional="yes"/>
        <sequential>
            <junit fork="@{fork.flag}" dir="${basedir}" failureProperty="test.failed">
    
                <systemproperty.addtion/>
                <pre.classpath/>
                <classpath location="${classes.dir}" />
                <post.classpath/>
    
                <formatter type="xml" />
                <test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
                <batchtest todir="${reports.xml.dir}" unless="testcase">
                    <fileset dir="${src.dir}">
                        <include name="**/*Test.java" />
                    </fileset>
                </batchtest>
            </junit>
        </sequential>
    </macrodef>
    
    
    
    跟我重复一遍:Ant不是一种编程语言。事实上,把它写在黑板上100遍

    Ant不是一种编程语言,所以不要这样认为,它是一种构建依赖矩阵

    程序员很难对这一想法了如指掌。他们想告诉Ant每一步以及什么时候应该完成。他们想要循环,if语句。他们会求助于使用
    build.sh
    脚本来调用Ant中的各种目标,因为你无法轻松地编程Ant

    在一个
    <project>
       <description>
          yadda, yadda, yadda
       </description>
    
       <taskdef name="cobertura"/>
    
       <target name="compile"
            description="Compile the code"/>
    
        <!-- Do you have to compile code before you run Cobertura?--> 
        <target name="coverage"
           description="Calculate test coverage"
           depends="compile">
    
           <mkdir dir="${coverage.dir}"/>
           <cobertura-instrument/>
        </target>
    <project>
    
    $ ant -p
    
    <target name="instrument.classes"
       depends="compile">
       <coburtura-instrument/>
    </target>
    
    <target name="corburtura"
       depends="instrument.classes"
       description="Runs the JUnit tests instrumented with Corburtura">
       <junit/>
    </target>
    
    <target name="instrument.tests"
        depends="compile">
        <corburtura-instrument/>
    </target>
    
    <target name="corburtura"
        depends="instrument.tests"
        description="Instrument and run the JUnit tests">
    
        <run.junit.test fork.flag="true">
            <systemproperty.addition>
                <sysproperty key="net.sourceforge.corbertura.datafile"
                    file="${basedir}/cobertura.ser" />
            </systemproperty.addition>
            <pre.classpath>
                <classpath location="${instrumented.dir}" />
            </pre.classpath>
            <post.classpath>
                <classpath refid="cobertura_classpath" />
            </post.classpath>
        </run.junit.test>
    </target>
    
    <target name="test"
        description="Runs the Junit tests without any instrumentation">
        <run.junit.test/>
    </target>
    
    <macrodef name="run.junit.test">
        <attribute name="fork.flag" default="false"/>
        <element name="sysproperty.addition" optional="yes"/>
        <element name="pre.classpath" optional="yes"/>
        <element name="post.classpath" optional="yes"/>
        <sequential>
            <junit fork="@{fork.flag}" dir="${basedir}" failureProperty="test.failed">
    
                <systemproperty.addtion/>
                <pre.classpath/>
                <classpath location="${classes.dir}" />
                <post.classpath/>
    
                <formatter type="xml" />
                <test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
                <batchtest todir="${reports.xml.dir}" unless="testcase">
                    <fileset dir="${src.dir}">
                        <include name="**/*Test.java" />
                    </fileset>
                </batchtest>
            </junit>
        </sequential>
    </macrodef>