使用Ant合并两个不同的属性文件

时间:2011-01-05 04:48:01

标签: ant build merge properties

我有一个默认属性文件,以及一些特定于部署的属性文件,这些文件根据部署环境覆盖默认设置中的某些设置。我希望我的Ant构建脚本合并两个属性文件(用部署特定值覆盖默认值),然后将结果属性输出到新文件。

我试过这样做,但我没有成功:

<target depends="init" name="configure-target-environment">
    <filterset id="application-properties-filterset">
        <filtersfile file="${build.config.path}/${target.environment}/application.properties" />
    </filterset>

    <copy todir="${web-inf.path}/conf" file="${build.config.path}/application.properties" overwrite="true" failonerror="true" >
        <filterset refid="application-properties-filterset" />
    </copy>
</target>

5 个答案:

答案 0 :(得分:4)

我是这样做的:

<property prefix="app.properties" file="custom.application.properties" />
<property prefix="app.properties" file="default.application.properties" />
<echoproperties destfile="application.properties">
   <propertyset>
      <propertyref prefix="app.properties"/>
      <mapper type="glob" from="app.properties.*" to="*"/>
   </propertyset>
</echoproperties>

答案 1 :(得分:2)

也许你应该看看蚂蚁的concat任务。

答案 2 :(得分:2)

我想出了这个。需要创建一个额外的属性文件,每个键/值采用以下格式: mail.server.host = @ mail.server.host @ 等...

然后将此“模板”文件指定为任务的“文件”属性。同样在filterset中,指定首先列出的最不重要的多个。

所以它看起来像这样:

                           

<copy todir="${web-inf.path}/conf" file="${build.config.path}/template.application.properties" overwrite="true" failonerror="true" >
    <filterset refid="application-properties-filterset" />
</copy>

答案 3 :(得分:0)

我个人用这个:

<copy todir="${web-inf.path}/conf" filtering="true">
  <fileset dir="${build.config.path}" includes="*.properties" /> 
  <filterset>
    <filtersfile file="application-properties-filterset" /> 
  </filterset>
</copy>

答案 4 :(得分:0)

其他答案还可以,但我需要一个没有这些限制的答案:

  • 需要使用@ tokens @(第一个答案)
  • 将所有属性指定为模板
  • 物业扩张 - 例如我将属性定义为prop2 = $ {prop1},它将通过任何加载和回声属性的解决方案进行扩展
  • EchoProperties(@ user2500146)转义像冒号的字符,这些字符对于URL属性很恼火(不是Ant的错,这是标准的Java属性,它允许:代替=)
  • 基于concat的解决方案的重复属性(这是有效的,因为第二个定义被忽略,但我不想重复

最后我不得不在过滤器中使用javascript,但我的解决方案带来了默认属性,当且仅当它们未在主属性文件中定义时。 它的工作原理是使用一个模糊的前缀加载主要属性,然后将其复制到目标,然后在过滤掉在第一步中加载的任何默认属性时连接默认属性。

你可以逐字使用,但是一旦你确信,可能会想要取出日志语句或将它们更改为调试级别

<!-- merge the main.properties.file with the default.properties.file
     into the output.properties.file (make sure these are defined) -->
<target name="merge">
    <!--Obscure enough prefix to ensure the right props are handled-->
    <property name="prefix" value="__MY_PREFIX__"/>
    <!--Load the main properties so we can tell if the default is needed-->
    <property prefix="${prefix}" file="${main.properties.file}"/>

    <!--Copy the main properties, then append the defaults selectively-->
    <copy file="${main.properties.file}" tofile="${output.properties.file}" overwrite="true"/>
    <concat destfile="${output.properties.file}" append="true">
        <fileset file="${default.properties.file}"/>
        <filterchain>
            <!--Filter out lines with properties that were already in the main properties -->
            <scriptfilter language="javascript"> <![CDATA[
            var line = self.getToken();
            project.log("line: " + line);
            var skipLine = false;
            // lines that do not define properties are concatenated
            if (line.indexOf("=") != -1) {
                // get the property name from the line
                var propName = line.substr(0, line.indexOf('='));
                project.log("line prop: " + propName);
                var loadedPropName = "__MY_PREFIX__" + propName;
                if (project.getProperty(loadedPropName) != null) {
                    project.log("prop has original: " + project.getProperty(loadedPropName));
                   // skip this line, the property is defined
                   skipLine = true;
                }
            }

            if (skipLine) {
                project.log("skipping line: " + line);
                self.setToken(null);
            }
            else {
                // else leave the line in as it was
                project.log("adding default line: " + line);
                self.setToken(line);
            }

]]> </scriptfilter>
        </filterchain>
    </concat>
</target>