【问题标题】:Testing Macrodef Attribute without IF在没有 IF 的情况下测试 Macrodef 属性
【发布时间】:2009-10-28 17:54:14
【问题描述】:

如果 macrodef 属性设置为 prod,我将尝试删除所有以 log 开头的行(示例如下)。我计划使用 replaceregexp 删除所有以 log 开头的行。但是,除了使用 if 任务之外,我不确定如何测试属性是否设置为特定值。我不想引入任何非核心 Ant 任务来执行此操作,但我想不出任何其他解决方案。除了使用 if 任务,我还有其他选择吗?

谢谢

<macrodef name="setBuildstamp">
    <attribute name="platform" />
    <sequential>
        <if>
            <equals arg1="platform" arg2="prod" />
            <then>
                <replaceregexp match="^log\(.*" value="" />
            </then> 
        </if>
    </sequential>
</macrodef>

【问题讨论】:

  • 我认为创建一个单独的宏来处理这个是不可接受的?

标签: ant ant-contrib


【解决方案1】:

您应该使用对参数的引用,例如 @{platform}

另外,您的 replaceregexp 任务缺少一些参数。

我认为在您的特定情况下,最好使用linecontainsregexp 过滤器阅读器。这是修改后的代码(注意 linecontainsregexp 的 negate 参数)。

<macrodef name="setBuildstamp">
  <attribute name="platform" />
  <sequential>
    <if>
      <equals arg1="@{platform}" arg2="prod" />
      <then>
        <copy todir="dest-dir">
          <fileset dir="src-dir"/>
          <filterchain>
            <linecontainsregexp
              regexp="^log\(.*"
              negate="true"
            />
          </filterchain>
        </copy>
      </then> 
    </if>
  </sequential>
</macrodef>

【讨论】:

  • 关于过滤的好意见...我试图专注于问题的“使用核心任务”部分。
【解决方案2】:

它们可能是解决这个问题的几种方法,但没有一个比使用 ant-contrib 元素更简单。我不确定这是否能满足您的申请所需,但您可以尝试以下方法:

使用条件目标。如果您可以将宏定义替换为要调用的目标,这可能对您有用。请注意,这将全局设置属性,因此它可能不适用于您的应用程序。

<target name="default">
  <condition property="platformIsProd">
    <equals arg1="${platform}" arg2="prod" />
  </condition>
  <antcall target="do-buildstamp" />
</target>
<target name="do-buildstamp" if="platformIsProd">
  <echo>doing prod stuff...</echo>
</target>

处理“else”情况。如果您需要处理另一种情况,则需要提供一些目标...

<target name="default">
  <property name="platform" value="prod" />
  <antcall target="do-buildstamp" />
</target>
<target name="do-buildstamp">
  <condition property="platformIsProd">
    <equals arg1="${platform}" arg2="prod" />
  </condition>
  <antcall target="do-buildstamp-prod" />
  <antcall target="do-buildstamp-other" />
</target>
<target name="do-buildstamp-prod" if="platformIsProd">
  <echo>doing internal prod stuff...</echo>
</target>
<target name="do-buildstamp-other" unless="platformIsProd">
  <echo>doing internal non-prod stuff...</echo>
</target>

使用外部构建文件。如果您需要使用不同的属性值进行多次调用,您可以将其隔离在同一项目中的另一个构建文件中。这会对性能造成一点影响,但您不需要额外的库。

在 build.xml 中:

<target name="default">
  <ant antfile="buildstamp.xml" target="do-buildstamp" />
  <ant antfile="buildstamp.xml" target="do-buildstamp">
    <property name="platform" value="prod" />
  </ant>
  <ant antfile="buildstamp.xml" target="do-buildstamp">
    <property name="platform" value="nonprod" />
  </ant>
</target>

在 buildstamp.xml 中:

<condition property="platformIsProd">
  <equals arg1="${platform}" arg2="prod" />
</condition>
<target name="do-buildstamp">
  <antcall target="do-buildstamp-prod" />
  <antcall target="do-buildstamp-other" />
</target>
<target name="do-buildstamp-prod" if="platformIsProd">
  <echo>doing external prod stuff...</echo>
</target>
<target name="do-buildstamp-other" unless="platformIsProd">
  <echo>doing external non-prod stuff...</echo>
</target>

将 ant-contrib 添加到您的项目中。当然,如果您可以将文件添加到您的项目中,最简单的方法就是添加 ant-contrib.jar 文件。您可以将其放在“工具”文件夹下,然后使用 taskdef 将其拉入:

<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${basedir}/tools/ant-contrib.jar" />

【讨论】:

  • 我决定采纳你的建议并添加了 ant-contrib 库。
【解决方案3】:

看起来,当您专门为生产环境构建项目时 - 您正在剥离不想在生产环境中运行的代码。因此,您创建的二进制文件与在您的开发或测试环境中运行的二进制文件不同。

如何在运行时而不是构建时使用环境变量或属性文件来确定是否发生日志记录?这样,当您在生产中遇到问题并且想要使用相同的二进制文件(而不是确定修订、检查代码、使用不同的环境标志重新构建)时,您只需将其重新部署到您的开发或测试环境并在属性文件或环境变量中打开调试?

【讨论】:

  • 我们实际上正在开发一个 Javascript TV Widget 应用程序,该应用程序有一些严重的性能限制,因此我们正在尝试删除任何多余的东西。
  • 啊,对于 JavaScript,我可以看到想要保持你的函数小而精。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
相关资源
最近更新 更多