【问题标题】:Ant task to compare two properties filesAnt 任务比较两个属性文件
【发布时间】:2013-01-17 14:48:47
【问题描述】:

有谁知道比较两个(Java)属性文件的 Ant 任务?我找不到任何东西,但我想在开始实施之前确定一下。

  • 输入:两个属性文件
  • 输出:在一个文件中但不在另一个文件中的属性键列表。

明确一点:它应该执行属性文件语法感知比较,比较键的存在,但忽略值。

【问题讨论】:

标签: java ant file-comparison


【解决方案1】:

最好的选择是使用PropDiff 实用程序。它具有比较、组合和交叉 Java 属性文件的选项。它是开源的,因此您可以根据自己的要求对其进行修改。

这是 PropDiff 的 documentation

【讨论】:

    【解决方案2】:

    您可以尝试将groovy ant taskjava-diff-utils 库结合起来

    示例

    ├── build.xml
    ├── file1.properties
    └── file2.properties
    

    运行构建会产生以下输出:

    diff:
       [groovy] [DeleteDelta, position: 1, lines: [two=2]]
       [groovy] [InsertDelta, position: 3, lines: [threeandhalf=3.5]]
       [groovy] [ChangeDelta, position: 4, lines: [five=5] to [five=55555]]
    

    build.xml

    <project name="demo" default="diff" xmlns:ivy="antlib:org.apache.ivy.ant">
    
        <target name="resolve">
            <ivy:cachepath pathid="build.path">
                <dependency org="org.codehaus.groovy" name="groovy-all" rev="2.1.0-rc-1" conf="default"/>
                <dependency org="com.googlecode.java-diff-utils" name="diffutils" rev="1.2.1" conf="default"/>
            </ivy:cachepath>
        </target>
    
        <target name="diff" depends="resolve">
            <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
    
            <groovy>
                import difflib.*
    
                def original = new File("file1.properties").readLines()
                def revised  = new File("file2.properties").readLines()
    
                Patch patch = DiffUtils.diff(original, revised)
    
                patch.getDeltas().each {
                    println it
                }
            </groovy>
        </target>
    
    </project>
    

    注意事项:

    file1.properties

    one=1
    two=2
    three=3
    four=4
    five=5
    

    file2.properties

    one=1
    three=3
    threeandhalf=3.5
    four=4
    five=55555
    

    修改示例

    返回第二个文件中缺少的第一个文件中的属性:

    diff:
       [groovy] Missing keys: [two]
    

    build.xml

    <project name="demo" default="diff" xmlns:ivy="antlib:org.apache.ivy.ant">
    
        <target name="resolve">
            <ivy:cachepath pathid="build.path">
                <dependency org="org.codehaus.groovy" name="groovy-all" rev="2.1.0-rc-1" conf="default"/>
            </ivy:cachepath>
        </target>
    
        <target name="diff" depends="resolve">
            <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
    
            <groovy>
                def source = new Properties()
                def target = new Properties()
    
                new File("file1.properties").withInputStream { source.load(it) }
                new File("file2.properties").withInputStream { target.load(it) }
    
                def diff = source.findResults { k,v ->
                    k in target ? null : k
                }
    
                println "Missing keys: ${diff}"
            </groovy>
        </target>
    
    </project>
    

    【讨论】:

    • 感谢您的详尽回答。虽然仅比较文本文件很有用,但这不是我要寻找的答案。我对内容感知比较感兴趣。这意味着它应该比较键的存在,但忽略值。我也更新了问题。很抱歉造成混乱。
    • @NeemePraks 我创建了第二个示例来查找丢失的键。
    • 谢谢,这似乎有效。虽然我更喜欢完整的 Ant 任务,但现在就足够了。
    • @NeemePraks 没有什么能阻止您编写自己的自定义任务。就我个人而言,我发现嵌入 Groovy 脚本更简单。它是即时的、更简单的更改,并且 groovy 与 ANT 很好地集成。
    【解决方案3】:

    这是另一种只需要 ant-contrib 库的方法:

    <target name="checkPropertyFiles">
        <antcall target="ensureTwoFilesHaveSameProperties">
            <param name="file1" value="file1.properties"/>
            <param name="file2" value="file2.properties"/>
        </antcall>
    </target>
    
    <target name="ensureTwoFilesHaveSameProperties">
        <loadproperties srcFile="${file1}" prefix="prefixfile1"/>
        <loadproperties srcFile="${file2}" prefix="prefixfile2"/>
    
        <propertyselector property="file1.list" delimiter="," match="prefixfile1\.(.+)" select="\1"/>
        <propertyselector property="file2.list" delimiter="," match="prefixfile2\.(.+)" select="\1"/>
    
        <for list="${file1.list}" param="file1.property">
            <sequential>
                <if>
                    <not>
                        <matches pattern=",@{file1.property}," string=",${file2.list}," />
                    </not>
                    <then>
                        <property name="error.encountered" value="true"/>
                        <echo message="Property @{file1.property} is present in ${file1} but not in ${file2}"/>
                    </then>
                </if>
            </sequential>
        </for>
        <for list="${file2.list}" param="file2.property">
            <sequential>
                <if>
                    <not>
                        <matches pattern=",@{file2.property}," string=",${file1.list}," />
                    </not>
                    <then>
                        <property name="error.encountered" value="true"/>
                        <echo message="Property @{file2.property} is present in ${file2} but not in ${file1}"/>
                    </then>
                </if>
            </sequential>
        </for>
    
        <fail message="Property files do not have the same set of keys.">
            <condition>
                <isset property="error.encountered"/>
            </condition>
        </fail>
    
        <echo message="OK: ${file1} has same properties as ${file2}"/>
    </target>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      • 2023-03-31
      相关资源
      最近更新 更多