【问题标题】:Using Ant to merge two different properties files使用 Ant 合并两个不同的属性文件
【发布时间】:2011-06-03 19:24:09
【问题描述】:

我有一个默认属性文件,以及一些特定于部署的属性文件,它们会根据部署环境覆盖默认设置的某些设置。我希望我的 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>

【问题讨论】:

    标签: ant build merge properties


    【解决方案1】:

    我是这样做的:

    <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>
    

    【讨论】:

    • 对我来说似乎是最好的答案,因为它应该与常规属性文件一起使用,而不是需要 @tokens@
    • 但是这似乎为各种属性的值添加了转义标记。例如:我有 aa=D:\abcd。这已转换为 aa=D\:\\abcd。有没有办法避免这种情况?发现 ant concat 任务效果更好。
    【解决方案2】:

    也许你应该为此查看 ant 的 concat 任务。

    【讨论】:

      【解决方案3】:

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

      然后将这个“模板”文件指定给任务的“文件”属性。同样在过滤器集中,指定多个,首先列出最不重要的一个。

      所以它看起来像这样:

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

      【讨论】:

        【解决方案4】:

        我个人使用这个:

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

        【讨论】:

          【解决方案5】:

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

          • 需要使用@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>
          

          【讨论】:

          • 为了更正确,我可以阅读 PREFIX 的属性以确保它是相同的,但不值得额外费用
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-31
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 2016-09-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多