ant filtering - fail if property not set

2019-01-23 11:26发布

I've got a ant build.xml that uses the <copy> task to copy a variety of xml files. It uses filtering to merge in properties from a build.properties file. Each environment (dev, stage, prod) has a different build.properties that stores configuration for that environment.

Sometimes we add new properties to the Spring XML or other config files that requires updating the build.properties file.

I want ant to fail fast if there are properties missing from build.properties. That is, if any raw @...@ tokens make it into the generated files, I want the build to die so that the user knows they need to add one or more properties to their local build.properties.

Is this possible with the built in tasks? I couldn't find anything in the docs. I'm about to write a custom ant task, but maybe I can spare myself the effort.

Thanks

标签: java ant
5条回答
我命由我不由天
2楼-- · 2019-01-23 11:35

If you are looking for a specific property, you can just use the fail task with the unless attribute, e.g.:

<fail unless="my.property">Computer says no. You forgot to set 'my.property'!</fail>

Refer to the documentation for Ant's fail task for more detail.

查看更多
贼婆χ
3楼-- · 2019-01-23 11:42

You can do it in ant 1.7, using a combination of the LoadFile task and the match condition.

<loadfile property="all-build-properties" srcFile="build.properties"/>
<condition property="missing-properties">
    <matches pattern="@[^@]*@" string="${all-build-properties}"/>
</condition>
<fail message="Some properties not set!" if="missing-properties"/>
查看更多
萌系小妹纸
4楼-- · 2019-01-23 11:42

I was going to suggest that you attempt to use <property file="${filter.file}" prefix="filter"> to actually load the properties into Ant, and then fail if any of them are not set, but I think I was interpreting your problem wrong (that you wanted to fail if a specified property was not set in the properties file).

I think your best bet might be to use <exec> to (depending on your dev platform) do a grep for the "@" character, and then set a property to the number of occurences found. Not sure of exact syntax but...

<exec command="grep \"@\" ${build.dir} | wc -l" outputproperty="token.count"/>
<condition property="token.found">
    <not>
        <equals arg1="${token.count}" arg2="0"/>
    </not>
</condition>
<fail if="token.found" message="Found token @ in files"/>
查看更多
小情绪 Triste *
5楼-- · 2019-01-23 11:59

if exec command is deprecated in your version of ant you can use redirectors, something like:

<exec executable="grep">
  <arg line="@ ${build.dir}"/>
  <redirector outputproperty="grep.out"/>
</exec>
<exec executable="wc" inputstring="${grep.out}">
  <arg line="-l"/>
  <redirector outputproperty="token.found"/>
</exec>

to create the token.found property

<condition property="token.found">
    <not>
        <equals arg1="${token.count}" arg2="0"/>
    </not>
</condition>
<fail if="token.found" message="Found token @ in files"/>

for the conditonal

查看更多
欢心
6楼-- · 2019-01-23 11:59

Since Ant 1.6.2 condition can also be nested inside fail.

The following macro makes it easy to conditionally check multiple properties.

<macrodef name="required-property">
    <attribute name="name"/>
    <attribute name="prop" default="@{name}"/>
    <attribute name="if" default="___"/>
    <attribute name="unless" default="___"/>
    <sequential>
        <fail message="You must set property '@{name}'">
            <condition>
                <and>
                    <not><isset property="@{prop}"/></not>
                    <or>
                        <equals arg1="@{if}" arg2="___"/>
                        <isset property="@{if}"/>
                    </or>
                    <or>
                        <equals arg1="@{unless}" arg2="___"/>
                        <not><isset property="@{unless}"/></not>
                    </or>
                </and>
            </condition>
        </fail>
    </sequential>
</macrodef>

<target name="required-property.test">
    <property name="prop" value=""/>
    <property name="cond" value="set"/>
    <required-property name="prop"/>
    <required-property name="prop" if="cond"/>
    <required-property name="prop" unless="cond"/>
    <required-property name="prop" if="cond2"/>
    <required-property name="prop" unless="cond2"/>
    <required-property name="prop" if="cond" unless="cond"/>
    <required-property name="prop" if="cond" unless="cond2"/>
    <required-property name="prop" if="cond2" unless="cond"/>
    <required-property name="prop" if="cond2" unless="cond2"/>
    <required-property name="prop2" unless="cond"/>
    <required-property name="prop2" if="cond2"/>
    <required-property name="prop2" if="cond2" unless="cond"/>
    <required-property name="prop2" if="cond" unless="cond"/>
    <required-property name="prop2" if="cond2" unless="cond2"/>
    <required-property name="success"/>
</target>
查看更多
登录 后发表回答