In Ant you can use the following script:
<first id="first">
<fileset dir="dir.zips" includes="**/a.zip" />
</first>
<echo message="${toString:first}" />
to get the first file from the filelist.
Is there any alternative for the same in NAnt. <First> is not a valid task in NAnt.
I found an alterative, though it is not efficient
<property name="iter" value="0" overwrite="true"/>
<property name="first" value="" overwrite="true"/>
<foreach item="file" property="filename" in"src\build">
<do>
<if test="${iter == '0'}">
<property name="first" value="${filename}" overwrite="true"/>
</if>
<do>
<property name = "iter" value="${int::parse(iter) + 1}"/>
</foreach>
Since the loop won't break after first iteration, I have decided to create a custom task.
Related
My goal is to run TestBox scripts on Jenkins. But using the Ant script from
https://testbox.ortusbooks.com/content/running_tests/ant_runner.html
as a template, I get this error
BUILD FAILED
C:\public\data\trunk\AutomatedTesting\Box_Unit_Tests\build.xml:38: The reference to entity "bundles" must end with the ';' delimiter.
with this script:
<?xml version="1.0" encoding="UTF-8"?>
<project name="testbox-ant-runner" default="init" basedir=".">
<!-- THE URL TO THE RUNNER, PLEASE CHANGE ACCORDINGLY-->
<property name="basedir" value="C:\public\data\trunk\AutomatedTesting\Box_Unit_Tests" />
<property name="url.runner" value="C:\public\data\ColdBox\testbox\test-harness\runner.cfm?"/>
<!-- FILL OUT THE BUNDLES TO TEST, CAN BE A LIST OF CFC PATHS -->
<property name="test.bundles" value="http://localhost/application/testing/TestBox/Hello.cfc?method=runRemote" />
<!-- FILL OUT THE DIRECTORY MAPPING TO TEST -->
<property name="test.directory" value="test.specs" />
<!-- FILL OUT IF YOU WANT THE DIRECTORY RUNNER TO RECURSE OR NOT -->
<property name="test.recurse" value="true" />
<!-- FILL OUT THE LABELS YOU WANT TO APPLY TO THE TESTS -->
<property name="test.labels" value="" />
<!-- FILL OUT THE TEST REPORTER YOU WANT, AVAILABLE REPORTERS ARE: ANTJunit, Codexwiki, console, dot, doc, json, junit, min, raw, simple, tap, text, xml -->
<property name="test.reporter" value="simple" />
<!-- FILL OUT WHERE REPORTING RESULTS ARE STORED -->
<property name="report.dir" value="${basedir}\results" />
<property name="junitreport.dir" value="${report.dir}\junitreport" />
<target name="init" description="Init the tests">
<mkdir dir="${junitreport.dir}" />
<tstamp prefix="start">
<format property="TODAY" pattern="MM-dd-YYYY hh:mm:ss aa"/>
</tstamp>
<concat destfile="${report.dir}\Latestrun.log">Tests ran at ${start.TODAY}</concat>
</target>
<target name="run">
<get dest="${report.dir}/results.html"
src="${url.runner}&bundles=${test.bundles}&reporter=${test.reporter}"
verbose="true"/>
<-- Create fancy junit reports -->
<junitreport todir="${junitreport.dir}">
<fileset dir="${report.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junitreport.dir}">
<param name="TITLE" expression="My Awesome TestBox Results"/>
</report>
</junitreport>
</target>
</project>
Any thoughts?
I want to merge two different files using Ant. How do I do it?
Ex a.java and B.java
<target name="merge">
<property prefix="app.properties" file="input1.txt" />
<property prefix="app.properties" file="input2.txt" />
<echoproperties destfile="output.txt">
<propertyset>
<propertyref prefix="app.properties"/>
<mapper type="glob" from="app.properties.*" to=""/>
</propertyset>
</echoproperties>
</target>
this is not working correctly
Use the concat task
<concat destfile="output.txt">
<fileset file="input1.txt" />
<fileset file="input2.txt" />
</concat>
I'd like to "map" a bunch of ant properties, based on a prefix (sounds simple enough).
I have a solution, but it's not elegant (having to write out to a properties file, then read it back in!)
Question: Is there a quicker/more generic/simpler/out-of-the-box/straight-forward way of doing the below "load-propertyset" within ANT? (... than the example I've provided below)
(Roughly analogous to the Groovy > ConfigSlurper > Special Environment Configuration behaviour.)
For example:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Config">
<!-- Section 1. (These will be loaded from a property file...) -->
<property name="a.yyy" value="foo" />
<property name="a.zzz" value="cat" />
<property name="b.xxx" value="bar" />
<property name="b.zzz" value="dog" />
<macrodef name="load-propertyset">
<attribute name="prefix" />
<attribute name="outfile" default="123" />
<attribute name="propset" default="123" />
<sequential>
<propertyset id="#{propset}">
<propertyref prefix="#{prefix}" />
<globmapper from="#{prefix}.*" to="*" />
</propertyset>
<echo level="debug">Created propertyset - '#{propset}' from prefix='#{prefix}'</echo>
<tempfile property="#{outfile}" suffix=".properties" deleteonexit="true" />
<echo level="debug">Writing propset to temp file - '${#{outfile}}'</echo>
<echoproperties destfile="${#{outfile}}">
<propertyset refid="#{propset}"/>
</echoproperties>
<echo level="debug">Reading props from temp file - '${#{outfile}}'</echo>
<property file="${#{outfile}}" />
<delete file="${#{outfile}}" />
</sequential>
</macrodef>
<load-propertyset prefix="a" />
<load-propertyset prefix="b" />
<echo>>>> Using variables xxx=${xxx} yyy=${yyy} zzz=${zzz}</echo>
</project>
I'm sure I'm missing something simple, for instance:
Can I reference properties within a propertyset? (e.g. ${myprops.yyy} ?)
I'd like to avoid something like ${${filter}.hostname}.
The third-party Ant-Contrib has an <antcallback> task that takes the <antcall> task and adds the ability to return properties to the caller:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Config" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<!-- Section 1. (These will be loaded from a property file...) -->
<property name="a.yyy" value="foo" />
<property name="a.zzz" value="cat" />
<property name="b.xxx" value="bar" />
<property name="b.zzz" value="dog" />
<macrodef name="load-propertyset">
<attribute name="prefix" />
<attribute name="return" />
<sequential>
<antcallback target="-empty-target" return="#{return}">
<propertyset>
<propertyref prefix="#{prefix}" />
<globmapper from="#{prefix}.*" to="*" />
</propertyset>
</antcallback>
</sequential>
</macrodef>
<target name="-empty-target"/>
<target name="run">
<property name="properties-to-return" value="xxx,yyy,zzz"/>
<load-propertyset prefix="a" return="${properties-to-return}"/>
<load-propertyset prefix="b" return="${properties-to-return}"/>
<echo>>>> Using variables xxx=${xxx} yyy=${yyy} zzz=${zzz}</echo>
</target>
</project>
The properties-to-return concept is a bit of a maintenance burden. Luckily, <antcallback> doesn't fail when asked to return a property that wasn't set. Only the properties-to-return property needs to be modified when you want a new mapped property.
I'm in a situation that involves running an ant build with optional parameters that are always specified but but not always defined, like so
ant -DBUILD_ENVIRONMENT=test -Dusername_ext= -Dconf.dir_ext= -Dcgi-dir_ext=
If the parameters are not given values on the command line they will be by loading a .properties file. I have the following code that will check if the property isset and is not blank.
<if>
<bool>
<and>
<isset property="username_ext"/>
<not>
<equals arg1="${username_ext}" arg2="" />
</not>
</and>
</bool>
<then>
<property name="username" value="${username_ext}" />
</then>
</if>
<property file="${BUILD_ENVIRONMENT}.properties" />
Since there are multiple properties it seems like I should write a target that will do the same actions for each property rather than repeat that code every time.
<antcall target="checkexists">
<property name="propname" value="username"/>
<property name="paramname" value="username_ext"/>
</antcall>
<antcall target="checkexists">
<property name="propname" value="conf.dir"/>
<property name="paramname" value="conf.dir_ext"/>
</antcall>
But AFAIK an antcall will not set a global property. How then can I write a target that will accept the name of a parameter it needs to check is set and is not blank, and then copy that in to a parameter that other targets can use?
Rather than using a target you could use a macro to conditionally set properties based on whether or not another property is set to a non-empty value.
<macrodef name="set-property">
<attribute name="name" />
<attribute name="if-property-isset" />
<attribute name="value" default="${#{if-property-isset}}" />
<sequential>
<condition property="#{name}" value="#{value}">
<and>
<isset property="#{if-property-isset}" />
<not>
<equals arg1="${#{if-property-isset}}" arg2="" />
</not>
</and>
</condition>
</sequential>
</macrodef>
<target name="test-macro">
<set-property name="username" if-property-isset="username_ext" />
<set-property name="conf.dir" if-property-isset="conf.dir_ext" />
<property name="conf.dir" value="default conf directory" />
<echo message="username = ${username}" />
<echo message="conf.dir = ${conf.dir}" />
</target>
Output
$ ant test-macro -Dusername_ext=jsmith -Dconf.dir_ext=
Buildfile: /your/project/build.xml
test-macro:
[echo] username = jsmith
[echo] conf.dir = default conf directory
BUILD SUCCESSFUL
Total time: 1 second
Alternate Property Value
This macro also allows you set the property to a different value than the one provided on the command line.
<target name="test-macro">
<set-property name="username" if-property-isset="username_ext"
value="It worked!" />
<set-property name="conf.dir" if-property-isset="conf.dir_ext" />
<property name="conf.dir" value="default conf directory" />
<echo message="username = ${username}" />
<echo message="conf.dir = ${conf.dir}" />
</target>
Output
$ ant test-macro -Dusername_ext=jsmith -Dconf.dir_ext=
Buildfile: /your/project/build.xml
test-macro:
[echo] username = It worked!
[echo] conf.dir = default conf directory
BUILD SUCCESSFUL
Total time: 1 second
Say I have the string - "D:\ApEx_Schema\Functions\new.sql##\main\ONEVIEW_Integration\3"
I require to fetch the following into diff variables
- file name
- file path
- and the version (which is the last character of the string)
Pls any helps using ANT tasks
======================================
I am trying to read a txt file which contains data as given below :-
.\ApEx_Schema\Functions\new.sql##\main\ONEVIEW_Integration\3
.\ApEx_Schema\Functions\Functions.sql##\main\ONEVIEW_Integration\3
.\ApEx_Schema\Indexes\Indexes.sql##\main\ONEVIEW_Integration\2
and trying to collect the file name, its path details and its version and updating the same in a DB using the SQL task.
Though my build.xml is not giving output as desired.
Any suggestions and views!!!
My Build.xml file looks like -
==============START===========================
<description>
obiee copy files build file
</description>
<replace file="D:\buildFRIDAY\database.txt" token=".\" value="D:\"/>
<loadfile property="src" srcFile="D:\buildFRIDAY\database.txt"/>
<path id="antclasspath">
<fileset dir="D:\OraHome_1\oracledi\drivers">
<include name="ojdbc14.jar"/>
</fileset>
</path>
<for list="${src}" param="detls" delimiter="${line.separator}">
<sequential>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<propertyregex property="path" input="#{detls}"
regexp="(.*)\\.*##" select="\1" />
<propertyregex property="file" input="#{detls}"
regexp=".*\\(.*)##" select="\1" />
<propertyregex property="version" input="#{detls}"
regexp=".*\\(.*)" select="\1" />
<echo>
Input: #{detls}
Path: ${path}
File: ${file}
Version: ${version}
</echo>
<if>
<matches string="#{detls}" pattern=".sql" />
<then>
</then>
</if>
<if>
<matches string="#{detls}" pattern="[0-9]" />
<then>
<sql
driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#172.16.88.68:1521:rdev"
userid="rapid"
password="rapid"
print="yes"
classpathref="antclasspath">
Insert into ROLTA_PATCH_FILE_APP_TAB (PATCH_NO,FILE_NAME,FILE_PATH,FILE_VERSION,APPLIED_DATE,STATUS) values ('3.2.12',"#{detls}",'D:\ApEx_Schema\Functions\Functions.sql','3',to_date('11-MAR-11','DD-MON-RR'),'Y');
Insert into ROLTA_PATCH_TAB (PATCH_NO,PATCH_NAME,APPL_NAME,APPLIED_DATE) values ('3.2.12','2.1.11','#{detls}',to_date('11-MAR-11','DD-MON-RR'));
</sql>
</then>
</if>
</sequential>
</for>
==============END===========================
This isn't something that Ant is good at.
Probably the simplest solution is to use the ant-contrib propertyregex task:
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<property name="candidate"
value="D:\ApEx_Schema\Functions\new.sql##\main\ONEVIEW_Integration\3" />
<propertyregex property="path" input="${candidate}"
regexp="(.*)\\.*##" select="\1" />
<propertyregex property="file" input="${candidate}"
regexp=".*\\(.*)##" select="\1" />
<propertyregex property="version" input="${candidate}"
regexp=".*\\(.*)" select="\1" />
<echo>
Input: ${candidate}
Path: ${path}
File: ${file}
Version: ${version}
</echo>
That involves getting hold of the jar of the ant-contrib collection of tasks.
A - pretty nasty - alternative is to use a scriptdef task.
<scriptdef name="get_elements" language="javascript">
<attribute name="candidate" />
<attribute name="path-property" />
<attribute name="file-property" />
<attribute name="version-property" />
<![CDATA[
filesep = project.getProperty( "file.separator" );
candidate = attributes.get( "candidate" );
path = candidate.substring( 0, candidate.indexOf( "##" ) );
file = path.substring( path.lastIndexOf( filesep ) + 1 );
path = path.substring( 0, path.lastIndexOf( filesep ) );
version = candidate.substring( candidate.lastIndexOf( filesep ) + 1 );
project.setProperty( attributes.get( "path-property" ), path );
project.setProperty( attributes.get( "file-property" ), file );
project.setProperty( attributes.get( "version-property" ), version );
]]>
</scriptdef>
<property name="candidate"
location="D:\ApEx_Schema\Functions\new.sql##\main\ONEVIEW_Integration\3"
relative="yes" />
<get_elements candidate="${candidate}"
path-property="path"
file-property="file"
version-property="version" />
<echo>
Input: ${candidate}
Path: ${path}
File: ${file}
Version: ${version}
</echo>
(Note: tested this on a unix OS, so you may need to adjust path separator treatments if on Windows.)
Update:
Some notes on your implementation.
You may need to namespace the 'for' task:
<ac:for list="${src}" param="detls" delimiter="${line.separator}"
xmlns:ac="antlib:net.sf.antcontrib">
...
</ac:for>
If you want propertyregex to change a property (which you do as you're iterating) you need to set
override="yes" on each of those.
Inside a for you need to escape the at signs, for example:
<propertyregex property="path"
input="#{detls}"
regexp="(.*)\\.*\#\#" select="\1"
override="yes"/>
To refer to the property set by the propertyregex use ${path} rather than #{path}.
An alternative that won't require the contributed task "propertyregex", nor javascript.
<property name="candidate" value="D:\ApEx_Schema\Functions\new.sql##\main\ONEVIEW_Integration\3" />
<pathconvert property="path">
<path location="${candidate}" />
<regexpmapper from="(.*)\\.*##" to="\1" />
</pathconvert>
<pathconvert property="file">
<path location="${candidate}" />
<regexpmapper from=".*\\(.*)##" to="\1" />
</pathconvert>
<pathconvert property="version">
<path location="${candidate}" />
<regexpmapper from=".*\\(.*)" to="\1" />
</pathconvert>
<echo>
Input: ${candidate}
Path: ${path}
File: ${file}
Version: ${version}
</echo>