Ant Script to Add Clearcase Labels to Elements without Labels - ant

I am trying to create an Ant script that will create a label in ClearCase and then apply the label to the latest version of any file where the latest version does not have a label.
I am using this to create the label:
<ccmklbtype typename="${label.name}" failonerr="false"
ordinary="true" comment="${label.comment}"/>
When I use this to add the labels:
<ccmklabel viewpath="${view.path}" comment="${label.comment}" recurse="true"
typename="${label.name}" replace="false" version="\main\${side.branch}\LATEST"/>
It is, of course, adding the label to everything in the view path. My desired behavior would be to only add the label if the item doesn't already have a label on the latest version.
I can do what is desired via a command prompt, but I am trying to see if it can be done via Ant.
Does anyone have any ideas?
It looks like there is not a way to just label something that doesn't already have a name. Instead, I set it up to use an exec block in ANT that will label anything if it isn't labeled already with one of the labels used previously:
<target name="add_labels" description="Look for LATEST code that does not have a previous version label already on it. Skip the 0 generation as that is brought in from a previous release.">
<exec executable="cleartool" dir="${view.path}">
<arg value="find" />
<arg value="." />
<arg value="-ver" />
<arg value="version(\main\${side.branch}\LATEST)&&!version(\main\${side.branch}\0)${history.check}" />
<arg value="-exec" />
<arg value="cleartool mklabel -replace ${label.name} %CLEARCASE_XPN%" />
</exec>
</target>
It seems to work in testing.

Looking at the man page of ccmklabel, you see:
replace bool
If true, allow the replacement of a label of the same type on the same branch.
The default is false.
So with replace=true, if a file hasn't a label on the latest version, it will be put (or moved to) said LATEST version.
In the OP ruminator's case, he only wants to add a label if the version does not have one already.
2 approaches are possible:
ccmklabel in a view which already select only the versions you want to label.
Hard to do since the only version selector usable in a config spec is \main\${side.branch}\'{!lbtype(MY_TEST)}, which select the last version which isn't labelled 'MY_TEST' (and that doesn't fit exactly the initial selection criteria)
don't use ccmklabel in the ant script, and call insteald directly a cleartool find directive (which is more precise and can combine more version selectors than in a view config spec).
That is what the OP ruminator illustrates in his question update:
The find query focus on LATEST versions which haven't the right label:
<exec executable="cleartool" dir="${view.path}">
<arg value="find" />
<arg value="." />
<arg value="-ver" />
<arg value="version(\main\${side.branch}\LATEST)&&!version(\main\${side.branch}\0)${history.check}" />
<arg value="-exec" />
<arg value="cleartool mklabel -replace ${label.name} %CLEARCASE_XPN%" />
</exec>

Related

How to resolve 7-zip's 'Warnings: Headers Error' from .zip created by Ant build?

I have code for creating zip file in ant build script.
<target name="zip-dist" description="archiving artifacts">
<zip destfile="${artifacts}/${zipfile}.zip" update="false" basedir="${target.dist}" includes="*.xyz-*" />
</target>
When file is being extracted using win zip right click -> Extract All... there's no warning, but while extracting with 7-zip showing 'Warnings: Headers Error' but its successful.
I know this has no effect on the output as its just a warning so suggested users to ignore it or use win-zip method.
But trust me it is impossible to make them understand and they all are keep on eating my head.
There are many users and I am banging my head repeating same thing again and again. Still they want it to be fixed.
Can I use any attribute in ant-zip target or should I use any different zipping technique in ant build?
I have searched multiple online sources, this is last hope!
Please help.
I had the same issue.
Fixed adding only one attribute, to force Zip64 extensions:
zip64Mode="always"
Try and should work for you too.
Instead of regular zip target used 7-zip to create zip.
<property name="7z.exe" value="C:/Program Files/7-Zip/7z.exe" />
<target name="zip-dist" description="archiving artifacts">
<exec executable="${7z.exe}">
<arg value="a" />
<arg value="-tzip" />
<arg value="${artifacts}/${zipfile}.zip" />
<arg value="${target.dist}/*.xyz-*" />
</exec>
</target>
As 7-zip includes all necessary information regarding header, so that warning will not occur.
Of course, 7-zip must be available in system.

Apply task not working with mapper

I am banging my head on the walls with ant...
My target is the following:
<target name="js.minify">
<apply executable="java">
<arg line="-jar"></arg>
<arg path="path_to_file/yuicompressor-2.4.7.jar"></arg>
<arg line="-v"></arg>
<srcfile></srcfile>
<arg line="-o"></arg>
<targetfile></targetfile>
<globmapper from="*.js" to="*.min.js" casesensitive="no"/>
<fileset id="jsFiles" dir="${artifactsdir}/js">
</fileset>
</apply>
</target>
Here's the funny thing, with the mapper in the code nothing gets processed. I can even change the name of the executable to some non existing application and it won't complain, ie it skips the apply. If I remove the mapper and the target file, at least I get some error message. If I try another process with just the source file, it runs. I really narrowed it down to mapper which seems to select the files only if they have changed (?!), ie if I edit them and save them, it works... any idea how to force mapper to take any files, even non modified (whatever that means) files?
It sounds like you want to ignore the timestamp checking you get when you use <targetfile>.
You can do that using the force="true" parameter of the <apply> task. (It's at the bottom of the list of parameters, note that this option was new at Ant version 1.6.3.)
<apply executable="java" force="true">
...

How to acess property within a property in ant

Hi all please give a look to this code
in my properties file i have
win-x86.pc-shared-location=E:\Ant_Scripts
Now below i am trying to call PrintInstallerName_build from my build.xml,while as PrintInstallerName_build is in test.xml. In build.xml file,${platform.id} has value=win-x86 in the calling target and in called target param1 also has value=win-x86
<target name="PrintInstallerName" >
<echo>PlatForm.Id====>${platform.id}</echo>
<ant antfile="test.xml" target="PrintInstallerName_build">
<property name="param1" value="${platform.id}"/>
</ant>
<target name="PrintInstallerName_build" >
<echo>${param1.pc-shared-location}</echo><!--${param1.pc-shared-location}-->
<echo>${param1}.pc-shared-location}</echo><!--win-x86.pc-shared-location-->
<echo>${win-x86.pc-shared-location}</echo><!--E:\\Ant_Scripts-->
</target>
as you can see only the last statement gives correct output but it is hardcoded,i want to use param1 and the output should be E:\\Ant_Scripts i tried to use $ and # but none works,may be i am doing wrong somewhere can someone help please,i am struck and tomorrow is its DOD.
See Nesting of Braces in the Properties page of the Ant Manual.
In its default configuration Ant will not try to balance braces in
property expansions, it will only consume the text up to the first
closing brace when creating a property name. I.e. when expanding
something like ${a${b}} it will be translated into two parts:
the expansion of property a${b - likely nothing useful.
the literal text } resulting from the second closing brace
This means you can't use easily expand properties whose names are
given by properties, but there are some workarounds for older versions
of Ant. With Ant 1.8.0 and the the props Antlib you can configure Ant
to use the NestedPropertyExpander defined there if you need such a
feature.
You can use <propertycopy> to make it happen.
Consider that you need to have the property value of ${propA${propB}}
Use ant tag of propertycopy as follows:
<propertycopy property="myproperty" from="PropA.${PropB}"/>
<echo >${myproperty}</echo>
This will echo the value of ${propA${propB}}
<target name="PrintInstallerName_process" >
<echo>${param1}</echo><!--win-x86-->
<macrodef name="testing">
<attribute name="v" default="NOT SET"/>
<element name="some-tasks" optional="yes"/>
<sequential>
<echo>Source Dir of ${param1}: ${#{v}}</echo><!-- Dir of Win-x86:E:\Ant_Scripts-->
<some-tasks/>
</sequential>
</macrodef>
<testing v="${param1}.pc-shared-location">
<some-tasks>
</some-tasks>
</testing>
</target>
this is the way it works and for me it works fine anyways #sudocode your tip took me there so thank you very much

Apply a diff on multiple files - Ant

My ant project generates an "output" folder which contains the outputs of multiple runs and I would like to diff them all against files located in an "expected" folder (these lasts have the exact the same name as the ones in the output folder). I tried that:
<apply executable="diff">
<fileset dir="${output.dir}" />
<arg value="-u" />
<srcfile />
<arg value="${expected.dir}/" />
<srcfile />
<redirector>
<outputmapper type="merge" to="result.out" />
</redirector>
</apply>
But I have two problems:
First I am not allowed to put two <srclist /> in one <apply>, so how can I use two times the name of the current file treated in one <apply>?
Second I am not able to get the output of my <apply> in one single file. I tried different ways (putting the output argument in the <apply> tag...) but it always seems to only store the last execution of the apply. How can I append the result of each diff in one single file?
And I don't want to have to install anything else (so no ant-contrib with foreach).
Thanks.
This works for me:
<delete file="result.out" />
<apply executable="diff" force="yes" output="result.out" append="true">
<fileset dir="${output.dir}" />
<srcfile />
<targetfile />
<mapper type="glob" from="*" to="${expected.dir}/*" />
</apply>
Some explanation:
The apply task targetfile element lets you specify a second arg that is derived from the srcfile via the mapper.
To get the merged output use the output attribute and set append true. Note that you may need to delete the output file (i.e. truncate it) otherwise on rerun you'll not get a clean slate.
I fiddled with the arg list for diff to suit my OS, instead of passing expected.dir and the target file as successive elements, the mapper merges them into a single full path to the 'right hand' file for the diff.

ANT: How to read property setted in a foreach loop

Dear, I currently face some problem to retrieve the value of a property setted in a foreach loop. Maybe one of you could help me...
The purpose is to check if one file of a folder has been modified since the corresponding jar has been generated. This way I know if I have to generate the jar again.
What I do is to go through the folder with a foreach loop and if one file match my test, set a property to true.
The problem is that my variable doesn't seems to exist after my loop... Here is a simplified code example that has the same problem:
<target name="target">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
<foreach target="setVar" param="var" list="a,b"/>
<echo>myreturn in target: ${env.myreturn}</echo>
<property name="env.myreturn" value="c"/>
<echo>myreturn in second: ${env.myreturn}</echo>
</target>
<target name="setVar">
<property name="env.myreturn" value="${var}"/>
<echo>myreturn in setVar: ${env.myreturn}</echo>
</target>
The result of this code is:
target:
setVar:
[echo] myreturn in setVar: a
setVar:
[echo] myreturn in setVar: b
[echo] myreturn in target: ${env.myreturn}
[echo] myreturn in second: c
BUILD SUCCESSFUL
It seems that the variable is correctly set as it could be printed in the "setVar" target but no way to retrieve value from the calling target.
I also know it's not possible to assign a value to a property twice. But the problem doesn't even occurs... When it'll be the case I could add a check on the value of the property before to assign it to be sure it is not already initialized...
Do you have a clue on the way I can solve my problem ???
Many thanks in advance for your help :)
Try <for> task from ant-contrib instead of <foreach>. The <for> task takes advantage of Ant macro facility that came later. It works faster and is more flexible than the older <foreach> task. You are in the same project context when using <for>. That means properties set in the loop will be visible outside of the loop. Of course, normal rules for properties apply... you only get to set it once... unless you use <var> task from ant-contrib to overwrite or unset previously set properties.
Ah the joys of Ant hacking.
Not sure about your foreach problem, but can you not use the uptodate task for your requirement?
Even if I don't need it anymore thanks to sudocode, I found a solution for my question. Maybe it could be useful for someone else...
A collegue talked about the "antcallback" target of ant-contrib: it allows to return a result from a called target to the calling one. With a combination of "for" target and "antcallback" it is possible to do what I wanted to do:
<target name="target">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
<for param="file">
<path>
<fileset dir="../myDirectory" includes="**/*" />
</path>
<sequential>
<antcallback target="setVar" return="retValue">
<param name="file" value="#{file}"/>
</antcallback>
</sequential>
</for>
<echo>result: ${retValue}</echo>
</target>
<target name="setVar">
<property name="retValue" value="${file}"/>
</target>
"file" contains the name of the file in the directory. It is given to the called target as parameter with value "#{file}" ('#' necessary due to "for" target implementation).
At the end of the main target, ${retValue} contains the first value setted by the "setVar" target. No error is thrown when trying to set it multiple times, so it's not necessary to check if variable has already been instantiated before to set it in "setVar" target.
The <foreach> task uses the same logic as <antcall> under the covers, and any proprrties set inside a target invoked by <antcall> do not have scope beyond the execution of that target.
In other words, the env.myreturn property that you define in the setVar target is lost as soon as execution of that target completes.
This sort of scripting really isn't what Ant is designed for. The Ant-contrib library tries to patch up the holes, but it's still bending it way out of shape.
If you need to write such scripts, and want to use Ant tasks to achieve them, have a look at Gradle instead. It's a rather lovely blend of Groovy (for scripting) and Ant (for the tasks).
The other approaches here (<for>, <var>, <groovy>properties.put(....)</groovy>, <property>, <antcallback>) did not work with ANT 1.9.4, so I used the file system similar to this (pseudocode):
<target name="outer">
<for> <antcall target="inner" /> </for>
<loadproperties srcfile="tmpfile.properties" />
<echo message="${outerprop}" />
</target>
<target name="inner">
<!-- did not work: -->
<!--
<property name="outerprop" value="true" />
<var name="outerprop" value="true" />
<groovy>properties.put('outerprop','true')</groovy>
<antcallback target="setouterprop" />
-->
<echo message="outerprop=true" file="tmpfile.properties" />
</target>
Maybe the other approaches did not work because of my <antcall>, but I need it here. (outerprop is initially unset)

Resources