regex AFTER grouping construct not being set correctly? - regex

Based on this thread. I've tried to replace the set the current version of my project in my NAnt script.
Here's my Replace snippet
<target name="Replace">
<loadfile file="${SetVersionCpp.File}" property="h.file.content" />
<regex
input="${h.file.content}"
pattern="(?'BEFORE'[.\s]*)${LineBegining}\s*[\s\d,]*\r\n(?'AFTER'[.\s]*)" />
<echo
file="${SetVersionCpp.File}"
message="${BEFORE}${LineBegining} ${ReplaceWith}
${AFTER}"
append="false"
verbose="true" />
</target>
Which I call on this file
#define FILEVER 0, 2, 0, 3
#define PRODUCTVER 0, 2, 0, 3
#define STRFILEVER "00.02.00.03\0"
#define STRPRODUCTVER "00.02.00.03\0"
with the following parameters
<property name="SetVersionCpp.File" value="${baseline.dir}\VersionNo.h" />
<property name="LineBegining" value="#define FILEVER" />
<property name="ReplaceWith" value="${FileVersion}" />
Based on the output, the AFTER variable is not capturing the rest of the file for some reason. This is what I get:
[#define FILEVER 0, 2, 0, 30
]
*I put it in brackets so that the whitespace got correctly formatted
Any ideas what I'm doing wrong?

I've fixed it by setting the options to Singleline so that . would match line breaks and by removing the classes from the groups:
<regex
input="${h.file.content}"
options="Singleline"
pattern="(?'BEFORE'.*)${LineBegining}\s*[\s\d,]*\r\n(?'AFTER'.*)" />

Related

replaceregexp ant not inserting tabulation

I want to replace a tabulation when I have a match in a file. I have this code:
<property name="line.separator" location="\r" />
<property name="tab.separator" location="\t" />
<target name="replace">
<replaceregexp
match='#WebMethod([\s\S]*?(?=public))public\s+(\w+)\s+(\w*)[\s\S]+?(?=\))[\s\S]+?(?=MSE)(\w+)\s+(\w*)[\s\S+]+?(?=throws)throws\s+(\w*)'
replace='#WebMethod(operationName="\$4")${line.separator}${tab.separator}#RequestWrapper(localName = "\$3")${line.separator}\r#ResponseWrapper(localName = "\$2")${line.separator}\rpublic \$2 \$3\(${line.separator}\r\r\$4 \$5)${line.separator}\r\rthrows MSFWebServiceException' flags="g,m">
<fileset dir="${project.dir}" />
</replaceregexp>
But the part of
#WebMethod(operationName="\$4")${line.separator}${tab.separator}#RequestWrapper
returns this:
#WebMethod(operationName="MSEPDetalleFigPartDTO")
C:t#RequestWrapper
So the \n goes ok, but the \t doesn't work because it replace the \t with C:t instead of a tabulation.
Any help would be appreciate.
kindest regards
This is cause by location instead of value and \t instead of :
<property name="tab.separator" location="\t" />
instead of
<property name="tab.separator" value=" " />
The property line.separator is already set (because it is an Ant built-in property), so your first line is just ignored.
location="\t" means the file location of the file t in the root directory, in your case it is the drive C:

ant replaceregexp xml newline

I'm trying to change an xml element value from "true" to "false" using ANT replaceregexp task but am having difficulties matching across a new line. The relevant part of the XML node in question:
<validationRules>
<fullName>CAReversaApprovallLockdown</fullName>
<active>true</active>
In my text editor (sublime), I'm able to use the following regex to find/replace but I can't figure out how to replicate this in ANT replaceregexp:
/fullname>\n <active>true
I can't figure out the correct syntax to match the combination of the newline and the spacing afterwards. The spacing after the newline is always the same, if that makes things easier.
Looking at https://ant.apache.org/manual/Tasks/replaceregexp.html I've tried various combinations of ^ and $ with m flag, \s+ for spaces etc but just can't hit the right combo....any ideas?
My current progress is below but no luck unfortunately...
<target name="deactivate_val_rules">
<echo message="deactivating validation rules..." />
<replaceregexp match="/fullname>\r\n\s+<active>true" flags="gim" byline="false">
<substitution expression="/fullname>\r\n <active>false"/>
<fileset dir="src\objects" includes="Claim_Approvals__c.object"/>
</replaceregexp>
</target>
Got it - the following gave the correct result:
<target name="deactivate_val_rules">
<echo message="deactivating workflows..." />
<replaceregexp match="/fullname>\r\n\s+<active>true" flags="gis" byline="false">
<substitution expression="/fullname>${line.separator} <active>false"/>
<fileset dir="src\objects" includes="Claim_Approvals__c.object"/>
</replaceregexp>
</target>
The output viewed via diff is:
- <fullName>the_name</fullName>
- <active>true</active>
+ <fullName>the_name</fullname>
+ <active>false</active>
To Use replaceregexp you need to define the value to be changed as reference.
For Example:
<validationRules>
<fullName>CAReversaApprovallLockdown</fullName>
<active>true</active>
Ant:
<target name = "deactivate_val_rules">
<echo message="deactivating validation rules..." />
<replaceregexp file="${FILE_LOACTION}/FILE_NAME.FILE_EXT" match="true" replace="false" />
</target>

ant-contrib for loop and regex in ant scripting

I have a requirement using ant, that the target should extract the two parameters passed as comma separated in a long list of similar pair of parameters passed which are semicolon separated. Currently I am doing something like this:
<?xml version="1.0"?>
<project name="" basedir="." default="test" xmlns:ac="antlib:net.sf.antcontrib">
<target name="test" >
<echo message="Hey There I am using What's App" />
<ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
<ac:sequential>
<ac:propertyregex property="param1"
input="#{val}"
regexp="([^\.]*)\,.*"
select="\1"
casesensitive="true" />
<ac:propertyregex property="param2"
input="#{val}"
regexp=".*,([^\.]*)"
select="\1"
casesensitive="true" />
<echo message = "val = ${param1}"/>
<echo message = "value = ${param2}"/>
</ac:sequential>
</ac:for>
</target>
</project>
But I am getting the output as:
Buildfile: /tmp/Manish/build.xml
test:
[echo] Hey There I am using What's App
[echo] val = asdfg
[echo] value = dasfdf
[echo] val = asdfg
[echo] value = dasfdf
[echo] val = asdfg
[echo] value = dasfdf
So this is getting looped 3 times(correct) but by only the first value passed in the for loop parameter. Is there some obvious mistake I am making?
Thanks,
Manish Joshi
Try using foreach instead of for and put the propertyregex into a separate target. Here is an example from my ant script, it basically does the same thing.
<target name="loadTestStatic" depends="setTargetEnv,setPassword">
<loadfile property="controlFile" srcFile="${projectDir}/test/config/static/controlFile.txt"/>
<foreach list="${controlFile}" delimiter="${line.separator}" param="descriptor" target="loadConfig"/>
</target>
<target name="loadConfig">
<if>
<matches string="${descriptor}" pattern="^camTool:"/>
<then>
<propertyregex property="camToolFile"
input="${descriptor}"
regexp="camTool:(.*)"
select="\1"
casesensitive="false" />
<echo message="Got cam tool file ${camToolFile}"/>
<camTool file="${camToolFile}"/>
</then>
<else>
<!-- todo: add CM Tool, SQL as required -->
<echo message="Unexpected config ${descriptor} ignored"/>
</else>
</if>
</target>
An alternative approach is to use a scripting language like groovy.
<groovy>
<arg value="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu"/>
args[0].tokenize(";").each {
def m = it.tokenize(",")
println "val = ${m[0]}"
println "value = ${m[1]}"
}
</groovy>
Alternatively use Ant addon Flaka, f.e. :
<project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- with cvs property -->
<property name="foobar" value="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu"/>
<fl:for var="item" in="split('${foobar}', ';')">
<fl:let>
param1 ::= split(item, ',')[0]
param2 ::= split(item, ',')[1]
</fl:let>
<echo>
$${param1} => ${param1}
$${param2} => ${param2}
</echo>
</fl:for>
<!-- with list inline -->
<fl:for var="item" in="split('asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu', ';')">
<fl:let>
param1 ::= split(item, ',')[0]
param2 ::= split(item, ',')[1]
</fl:let>
<echo>
$${param1} => ${param1}
$${param2} => ${param2}
</echo>
</fl:for>
</project>
Notice the double '::' in param1 ::= split(item, ',')[0]
means overriding any (also userproperties, defined via -Dkey=value as commandline arguments) existing property
whereas ':=' creates a property but won't overwrite if property already exists.
<target name="myTarget">
<ac:propertyregex property="param1"
input="${myValue}"
regexp="([^\.]*)\,.*"
select="\1"
casesensitive="true" />
<ac:propertyregex property="param2"
input="${myValue}"
regexp=".*,([^\.]*)"
select="\1"
casesensitive="true" />
<echo message = "val = ${param1}"/>
<echo message = "value = ${param2}"/>
</target>
<ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
<ac:sequential>
<antcall target="myTarget">
<param name="myValue" value="#{val}" />
</antcall>
</ac:sequential>
</ac:for>
Properties in Ant are immutable. You will need to use the variable task from ant-contrib (although it is discouraged) to unset the properties:
<ac:for list="asdfg,dasfdf;vxxexqxx,hyyypyly;dksfgsgdgf,abaifuacu" delimiter=";" param="val">
<ac:sequential>
<ac:propertyregex property="param1"
input="#{val}"
regexp="([^\.]*)\,.*"
select="\1"
casesensitive="true" />
<ac:propertyregex property="param2"
input="#{val}"
regexp=".*,([^\.]*)"
select="\1"
casesensitive="true" />
<echo message = "val = ${param1}"/>
<echo message = "value = ${param2}"/>
<ac:var name="param1" unset="true"/>
<ac:var name="param2" unset="true"/>
</ac:sequential>
</ac:for>

Ant PropertyRegex won't support capture group when in property

I'm trying to create an ant build target that supports var substitution dynamically.
<target name="replace_property" depends="init_ant_contrib">
<propertyregex input="${replace_inboundproperty"
property="${replace_outboundproperty}"
regex="${replace_match}"
replace="${replace_target}"
global="true"
override="true" />
</target>
so I load the properties file and i'm basically setting the vars as such:
replace_inboundproperty="/target/path/targetfile"
replace_outboundproperty=blah
replace_match="/target/(.*)/targetfile"
replace_target="\1"
so when I echo blah, I'm getting "1". Now if I actually do this:
<target name="replace_property" depends="init_ant_contrib">
<propertyregex input="${replace_inboundproperty"
property="${replace_outboundproperty}"
regex="${replace_match}"
replace="\1"
global="true"
override="true" />
</target>
and echo blah, I'll get "path".
Can anyone tell me what I'm missing to allow the replace to use capture groups from a properties file / ant -D? Using ant-contrib 1.0b3.
Thanks!
Found out that in the properties file, if you double escape it, it'll function correctly:
replace_target=\\1

Email notification on success/failed build using ant target

my current code(build.xml) enables me to send email on successful build, but when failed, nothing happens. The targets are called from a build.bat file through command similar to " ........ -DrepositoryAddress=%1 -DbuildResultUUID=%2 startPublish " (for all targets, in order startActivity->startPublish->mailer->startActivity).
Now, I also want email notification when the build fails.I guess trycatch will help me get the task done, but HOW? Not sure about it, where/how to place it(edit it?)? I kind of used trycatch, it gave me something like " Problem: failed to create task or type trycatch" . What modifications are required in current script/xml file to enable this functionality of sending email indicating status of build (successful or failed). Please guide/help.Thanks so much.
'
<target name="startActivity">
<fail message="Missing repositoryAddress" unless="repositoryAddress"/>
<fail message="Missing buildResultUUID" unless="buildResultUUID"/>
<fail message="Missing activityLabel" unless="activityLabel"/>
<!-- Replace ADMIN with your real credentials. -->
<startBuildActivity
buildResultUUID="${buildResultUUID}"
label="${activityLabel}"
autoComplete="true"
repositoryAddress="${repositoryAddress}"
userId="BuildAdmin"
password="Abc1234"/>
</target>
<target name="startPublish">
<sleep seconds="10"/>
<fail message="Missing repositoryAddress" unless="repositoryAddress"/>
<fail message="Missing buildResultUUID" unless="buildResultUUID"/>
<artifactfilePublisher repositoryAddress="${repositoryAddress}"
userId="BuildAdmin"
password="Abc1234"
buildResultUUID="${buildResultUUID}"
filePath="E:\Setup.msi"
label="Installer" />
</target>
<target name="mailer">
<property name="report" value="E:\Report.html"/>
<mail from="dmin#company.com" messagemimetype="text/html" charset="ISO-7779-1" messagefile="${report}" mailhost="HMMMM.company.com" mailport="25" tolist="admin#company.com" subject="Build status" />
</target>
<taskdef name="startBuildActivity"
classname="com.ibm.team.build.ant.task.StartBuildActivityTask" />
<taskdef name="artifactfilePublisher"
classname="com.ibm.team.build.ant.task.ArtifactFilePublisherTask" />
</project>'
you can implement a BuildListener that sends the email as described in the ant FAQ