代码之家  ›  专栏  ›  技术社区  ›  Strelok

如何在Ant中参数化路径?

  •  1
  • Strelok  · 技术社区  · 15 年前

    我在一个名为 构建依赖项.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="build-dependencies">
      ...
      <path id="common-jars">
        <fileset file="artifacts/project-1/jar/some*.jar" />
        <fileset file="artifacts/project-2/jar/someother*.jar" />
      </path>
      ...
    </project>
    

    我把它放在我的顶部 编译文件 文件。现在,我需要使工件文件夹成为一个参数,以便在不同目标的执行期间更改它。 有这个…

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="build-dependencies">
      ...
      <path id="common-jars">
        <fileset file="${artifacts}/project-1/jar/some*.jar" />
        <fileset file="${artifacts}/project-2/jar/someother*.jar" />
      </path>
      ...
    </project>
    

    …并且在目标中定义“工件”属性(并更改它)不起作用,因为在中定义路径时,似乎会发生属性替换。 构建依赖项.xml

    我怎么解决这个问题?我想的一种方法是使用参数化宏,并在实际使用路径之前调用它,但这似乎并不优雅。像这样:

    <macrodef name="create-common-jars">
      <attribute name="artifacts"/>
      <sequential>
        <path id="common-jars">
          <fileset file="@{artifacts}/project-1/jar/some*.jar" />
          <fileset file="@{artifacts}/project-2/jar/someother*.jar" />
        </path>
      </sequential>
    </macrodef>
    

    编辑:ivy和命令行参数不是选项。

    6 回复  |  直到 14 年前
        1
  •  3
  •   martin clayton egrunin    14 年前

    您不需要参数化路径。你想要一个 PatternSet . 您可以在顶层定义模式集,然后在需要时在单个目标中引用它。例如:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="build-dependencies">
      ...
      <patternset id="common-jars">
        <include name="project-1/jar/some*.jar" />
        <include name="project-2/jar/someother*.jar" />
      </patternset>
      ...
      <path id="instrumented-jars">
        <fileset dir="instrumented">
          <patternset refid="common-jars" />
        </fileset>
      </path>
      ...
      <path id="standard-jars">
        <fileset dir="not-instrumented">
          <patternset refid="common-jars" />
        </fileset>
      </path>
      ...
    </project>
    
        2
  •  0
  •   Mark O'Connor    15 年前

    我建议使用 ivy 管理类路径依赖项。Ivy有一个称为配置的简洁概念,它允许您根据工件的使用对工件集合进行分组。

    以下是我自己的一个构建文件的改编:

    <target name="retrieve" description="3rd party dependencies">
        <ivy:resolve/>
    
        <ivy:cachepath pathid="build.path" conf="build"/>
        <ivy:cachepath pathid="runtime.path" conf="runtime"/>
    </target>
    

    配置在 IV.XML 文件(将替换 构建依赖项.xml 文件)

    <ivy-module version="2.0">
        <info organisation="com.myspotontheweb" module="HelloWorld"/>
    
        <configurations>
            <conf name="build" description="jars needed for build" />
            <conf name="runtime" extends="build" description="jars needed at runtime" />
        </configurations>
    
        <dependencies>
            <dependency org="org1" name="project1" rev="1.0" conf="build->default"/>
            <dependency org="org2" name="project2" rev="1.0" conf="build->default"/>
            <dependency org="org3" name="project3" rev="1.0" conf="runtime->default"/>
            <dependency org="org4" name="project4" rev="1.0" conf="runtime->default"/>
        </dependencies>
    </ivy-module>
    

    与每个项目关联的JAR工件将从联机Maven存储库中自动下载和缓存,或者您可以创建自己的本地存储库来保存本地拥有的工件的集合。

        3
  •  0
  •   omermuhammed    15 年前

    让我们调用文件build.xml。所以通过运行ant命令来执行它。在第一种情况下,工件名称被硬编码在下面第三行定义的属性中。

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="build-dependencies">
    <property name="artifacts" value="first-value" />
      ...
      <path id="common-jars">
        <fileset file="artifacts/project-1/jar/some*.jar" />
        <fileset file="artifacts/project-2/jar/someother*.jar" />
      </path>
      ...
    </project>
    

    现在,当您想要更改它并为该工件属性使用另一个值时,我们就这样运行脚本

    ant -Dartifacts=new-value
    

    这将覆盖build.xml中的硬编码工件值。

    如果使用Ant目标,可以做类似的事情,在第一行的目标中定义属性,如果要覆盖默认值,则在调用该目标时将该属性作为参数传递。

    你的评论使我想起了别的事情。让开发人员创建一个artifacts-dir-name.xml文件。它只有一行:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="artifacts-file">
    <property name="artifacts" value="new-value" />
    </project>
    

    现在,在build.xml文件中,在定义artifactures属性的行之前,导入该文件,从而:

    <import file="artifacts-dir-name.xml" optional="true" />
    

    现在在Eclipse中,如果该文件存在,那么将从中读取属性,并将工件设置为“新值”,否则将从build.xml中读取属性,并将其设置为“第一值”。开发人员需要做的就是确保该目录中存在artifacts-dir-name.xml文件。这也可以在Eclipse中运行。

        4
  •  0
  •   Persimmonium    15 年前

    使用环境变量是一个选项吗(如果在Eclipse启动时设置了这些变量,它们将被接收)?如果是这样,就让每个工件都有一个集合,这样应该可以工作:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="build-dependencies">
      <property environment="env"/>
      <path id="common-jars">
        <fileset file="${env.ARTIFACTS}/project-1/jar/some*.jar" />
        <fileset file="${env.ARTIFACTS}/project-2/jar/someother*.jar" />
      </path>
    </project>
    
        5
  •  0
  •   Strelok    15 年前

    好吧,我认为除了使用一个接受参数并用适当的工件文件夹创建路径的宏之外,没有其他明显的方法可以让我做我想做的事情。

    为了提供一点上下文,我为什么要尝试我想要的是在单独的文件夹中包含“已检测”和“未检测”工件。在我的“目标”中,我可以改变工件模式。我现在要做的是,我有一个宏: <initialise-build-settings artifacts-mode="instrumented" /> 设置所有路径和其他变量。

    谢谢你们的回答,伙计们。

        6
  •  0
  •   mamboking    15 年前

    您可以使用不同的依赖项执行此操作:

    SETPATA.XML:

    <project name="setpath">
      <target name="setCommonJars">
        <path id="common-jars">
          <fileset file="${param1}/some*.jar" />
          <fileset file="${param1}/someother*.jar" />
        </path>
      </target>
    </project>
    

    XML:

    <project name="Test path" basedir=".">
      <import file="./setpath.xml" />
    
      <target name="buildT1" depends="setT1,setCommonJars">
        <property name="jar-str" refid="common-jars" />
        <echo message="buildT1: ${jar-str}" />
      </target>
    
      <target name="buildT2" depends="setT2,setCommonJars">
        <property name="jar-str" refid="common-jars" />
        <echo message="buildT2: ${jar-str}" />
      </target>
    
      <target name="setT1">
        <property name="param1" value="t1" />
      </target>
    
      <target name="setT2">
        <property name="param1" value="t2" />
      </target>
    
    </project>
    

    如果调用target buildt1,则使用T1目录;如果调用buildt2,则使用t2目录。