【问题标题】:How to apply an Ant task to a list of values in a string如何将 Ant 任务应用于字符串中的值列表
【发布时间】:2012-06-13 22:18:58
【问题描述】:

我正在编写一个 Ant 脚本,旨在模仿 VSS 的“影子文件夹”概念,作为从 VSS 迁移到 Subversion 的权宜之计(无需重新配置我们的构建管理软件)。脚本相当简单:

  • 创建构建文件夹
  • 从 Subversion 中提取源文件到构建文件夹中
  • 翻译源文件
  • 将源代码和目标代码文件从构建文件夹复制到用于部署的最终位置

在我将整个主干拉入构建文件夹并从那里开始的情况下,所有工作都“正常”...除了“构建”需要 30 多分钟,我希望将其作为一部分启动提交后事件(再次模仿 VSS 的“影子文件夹”功能,该功能将所有文件的“最新”副本保存在独立于 VSS 数据库的文件夹中,并根据所有签入进行更新)。

我一直在修改脚本,目的是对已更改的文件执行更有针对性的下载(svn diff 为我提供文件列表,svn export 可用于单独拉下它们,我相信)。

现在,问题是:有没有办法使用 Ant Core 来“迭代地”调用列表中每个元素的目标?这是此处发布的问题的重复:

In ant, how to apply a target on a list of files (without ant-contrib)?

但我拒绝接受这不能在本地完成。这篇文章:

How to distribute each element of a list to argument of a task Ant?

给了我希望,但我对 Ant 的工作方式(或设计方式)缺乏基本的理解来放弃。我希望我能做类似的事情:

<?xml version="1.0" encoding="UTF-8"?>
<project name="Test XmlProperty" default="test" basedir=".">
   <target name="test">
      <xmlproperty file="log.xml" collapseAttributes="true" />
      <echo>Affected resources: ${log.logentry.paths.path}</echo>

      <macrodef name="svnExportFile">
         <attribute name="svnRepoUrls"/>

         <sequential>
            <loadresource property="lead.path">
               <string value="${svnRepoUrls}"/>
               <filterchain>
                  <tokenfilter>
                     <replaceregex pattern="(\w+)[,${line.separator}]*.*" replace="\1" flags="g"/>
                  </tokenfilter>
               </filterchain>
            </loadresource>

            <loadresource property="rest.paths">
               <string value="${svnRepoUrls}"/>
               <filterchain>
                  <tokenfilter>
                     <replaceregex pattern="(\w+)[,${line.separator}]*(.*)" replace="\2" flags="g"/>
                  </tokenfilter>
               </filterchain>
            </loadresource>

            <echo message="${lead.path}"/>
            <echo message="${rest.paths}"/>

            <svnExportFile svnRepoUrls="${rest.paths}"/>
         </sequential>
      </macrodef>

      <svnExportFile svnRepoUrls="${log.logentry.paths.path}"/>
   </target>
</project>

虽然我没有让正则表达式工作得很好。这是对Ant的重大违反吗?我应该放弃希望并简单地使用 Ant-contrib 运行吗?我采用它的速度很慢,因为它似乎自 2008 年以来没有更新,我希望限制所有这些东西工作所需的依赖数量。

有什么想法吗?

编辑:我越来越近了(有点)......上面的代码在最初的帖子中没有正确引用,我在发布之前没有机会尝试它(需要离开并且没有想丢失我输入的所有内容)。无论如何,没有办法停止递归(我怀疑属性是不可变的,因此不会像我希望的那样重置),所以它不起作用(还没有?)。

我试图完成与上面相同的基本概念(我知道它不受欢迎,但它非常方便,因为它允许您通过 if/unless 属性有条件地执行任务)——虽然这不起作用,因为 Ant 显然不想允许递归:

'antcall 任务调用自己的父目标'

并尝试通过依赖启动递归:

'循环依赖:svn.export.file

如果有人好奇,这里是版本:

<?xml version="1.0" encoding="UTF-8"?>
<project name="Test XmlProperty" default="test" basedir=".">
   <target name="test">
      <xmlproperty file="log.xml" collapseAttributes="true" />
      <echo>Affected resources: ${log.logentry.paths.path}</echo>

      <antcall target="svn.export.file" inheritAll="false">
         <param name="svnRepoUrls" value="${log.logentry.paths.path}"/>
      </antcall>
   </target>

   <target name="svn.export.file" if="svnRepoUrls">
      <loadresource property="lead.path">
         <string value="${svnRepoUrls}"/>
         <filterchain>
            <tokenfilter>
               <replaceregex pattern="(\w+)[,${line.separator}]*.*" replace="\1" flags="g"/>
            </tokenfilter>
         </filterchain>
      </loadresource>

      <loadresource property="rest.paths">
         <string value="${svnRepoUrls}"/>
         <filterchain>
            <tokenfilter>
               <replaceregex pattern="(\w+)[,${line.separator}]*(.*)" replace="\2" flags="g"/>
            </tokenfilter>
         </filterchain>
      </loadresource>

      <echo message="${lead.path}"/>
      <echo message="${rest.paths}"/>

      <antcall target="svn.export.file" inheritAll="false">
         <param name="svnRepoUrls" value="${rest.paths}"/>
      </antcall>

   </target>
</project>

【问题讨论】:

  • 一定要在ant中完成吗?为什么没有 ant-contrib?
  • 我的帖子有点长,但我提到了两个原因:1)ant-contrib 自 2008 年以来似乎没有任何动作——也许是因为一切都很好,不需要改变,但对我来说似乎很奇怪,2)我希望限制我的依赖。
  • 如果没有它,我认为 Ant 相当残废。
  • 我读过一条评论,它暗示 和 ant-contrib 是可怕的东西,破坏了构建的优雅或类似的东西。我可以欣赏定义依赖关系和所有这些的优雅,但是在某些时候你需要对一组项目执行一些操作——我还没有看到有人抱怨 ;为什么不能有 或类似的东西(我会说 ,但我想它会搞砸依赖关系——s 不应该遇到这样的问题) .呃。
  • 如果有人觉得 Ant 很优雅,我不会雇用他们。

标签: ant


【解决方案1】:

我承认,它很丑……而且我不太确定我是否会坚持使用它作为我的解决方案(我想我可能会继续安装 ant-contrib,因为这个“代码”既是丑陋且令人困惑)——但它似乎起到了作用,它有点证明我的理论,是的,你可以为列表中的每个元素调用一个目标,而无需依赖!

<?xml version="1.0" encoding="UTF-8"?>
<project name="Test XmlProperty" default="test" basedir=".">
   <target name="test">
      <xmlproperty file="log.xml" collapseAttributes="true" />
      <echo>Affected resources: ${log.logentry.paths.path}</echo>

      <antcall target="svn.export" inheritAll="false">
         <param name="svn.repo.urls" value="${log.logentry.paths.path}"/>
      </antcall>
   </target>
   <target name="svn.export" if="svn.repo.urls">
      <macrodef name="svnExportFile">
         <attribute name="urls"/>

         <sequential>
            <macrodef name="parsePath">
               <attribute name="property"/>
               <attribute name="replacePart"/>

               <sequential>
                  <loadresource property="@{property}">
                     <string value="@{urls}"/>
                     <filterchain>
                        <tokenfilter>
                           <replaceregex pattern="([^,]+),?(.*)" replace="@{replacePart}" flags="g"/>
                        </tokenfilter>
                     </filterchain>
                  </loadresource>
               </sequential>
            </macrodef>

            <parsePath property="lead.path" replacePart="\1"/>
            <fail>
               <condition>
                  <not>
                     <isset property="lead.path"/>
                  </not>
               </condition>
            </fail>
            <parsePath property="rest.paths" replacePart="\2"/>

            <echo>lead.path:${lead.path}</echo>
            <echo>rest.paths:${rest.paths}</echo>

            <antcall target="svn.export.deux"/>
         </sequential>
      </macrodef>

      <svnExportFile urls="${svn.repo.urls}"/>
   </target>
   <target name="svn.export.deux" if="rest.paths">
      <echo>rest.paths:${rest.paths}</echo>
      <echo>svn.repo.urls:${svn.repo.urls}</echo>
      <antcall target="svn.export" inheritAll="false">
         <param name="svn.repo.urls" value="${rest.paths}"/>
      </antcall>
   </target>
</project>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2011-07-02
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    相关资源
    最近更新 更多