Ending target early in Phing - build

I am trying to modify a Phing script and cannot see what I thought would be an obvious feature.
The Phing script has a generic 'confirm' target which checks for input at various stages of execution. I want to automate the script so that it can run without input. I would expect to be able to to this by inserting some kind of <break> or <end> type task within the target so that it returns early. The manual does't appear to list such functionality.
I know I can achieve this, by creating an intermediate target to check the cmd line argument first and then call the confirm target, but is there a more elegant way?
This is the target that needs automating and is called from multiple places. The trigger to skip would be a property set via cmd line -D.
<!-- confirm a user action -->
<target name="confirm">
<input propertyname="confirm" validargs="yes,no">
${confirm.message} ('yes' to continue)
</input>
<if>
<not>
<equals arg1="${confirm}" arg2="yes" />
</not>
<then>
<fail message="You didn't say 'yes'" />
</then>
</if>
</target>

For the same purpose I'm using this tech:
<if>
<not>
<isset property="confirm" />
</not>
<then>
<input propertyname="confirm" validargs="yes,no">
${confirm.message} ('yes' to continue)
</input>
<if>
<not>
<equals arg1="${confirm}" arg2="yes" />
</not>
<then>
<fail message="You didn't say 'yes'" />
</then>
</if>
</then>
</if>
then you can execute
phing build.xml -Dconfirm=yes
without promt.

Related

Copy the value from a property in an Ant propertyfile to another property

I need to copy the value of one property in a propertyfile to a second property, and add that to the propertyfile.
For example, if I have a property file Test.properties containing
2018=jan;feb;mar
2019=jan;feb;mar
2020=jan;feb;mar
********************************
name=john,math,sudha
my input property is "2020" and output is "2021", after running Ant Test.properties should contain
2018=jan;feb;mar
2019=jan;feb;mar
2020=jan;feb;mar
2021=jan;feb;mar
********************************
name=john,math,sudha
with out changing the order How could I do that?
You might be able to use something based on the following:
The idea is to read the propertyfile, then use two <propertyset> instances with the <echoproperties> task to update the file.
<property name="prop.file" value="Test.properties" />
<property name="input" value="2020" />
<property name="output" value="2021" />
<property name="pf" value="prefix" />
<property name="input.prop" value="${pf}.${input}" />
<loadproperties srcfile="${prop.file}" prefix="${pf}" />
<echoproperties destfile="${prop.file}">
<propertyset>
<propertyref prefix="${pf}" />
<mapper type="glob" from="${pf}.*" to="*" />
</propertyset>
<propertyset>
<propertyref name="${input.prop}" />
<mapper type="glob" from="${input.prop}*" to="${output}*" />
</propertyset>
</echoproperties>
There's more code there than you might expect: the "prefix" is being used to ensure that the properties loaded from the file don't clash with any in your Ant buildfile as properties are imutable.
The order of the propertysets in the echoproperties task is important, especially if there is already a value for property "2021" in the file that you are updating. Where properties appear in both sets, the value in the last propertyset seen "wins" and is echoed to the output file.
<property name="prop.file" value="test.properties" />
<property name="input" value="2020" />
<property name="output" value="2021" />
<replaceregexp file="${prop.file}"
match="${input}(=)(.*)"
replace="${input}=\2${line.separator}${output}=\2"
flags="gi"
byline="true" />

Execute selected ant tasks for a selected set of projects

I have defined targets in ant for our games, e.g. clean, build-ios, build-android, deploy-ios, deploy-android, etc. Now I would like to define a new set of targets that represent our games, say game1, game2, game3.
My goal is to be able to launch ant with a set of target games and a set of target tasks so that for each selected game, each selected task is executed.
Example pseudo code: Foreach [game1, game3]: clean, build-ios, deploy-ios
How can I achieve this with ant? A requirement would be to define which games and which tasks are selected through targets, not to write them in a file that is altered manually.
The subant task is useful for situations where you have multiple subprojects that share similar structures.
In your main build.xml, define a target that rubs the desired build target on your game subdirectories, along with all of the generalized build targets.
<target name="deploy-all">
<subant target="deploy">
<dirset dir="." includes="game-*" />
</subant>
<echo message="All games deployed." />
</target>
<target name="deploy" depends="deploy-ios,deploy-android">
<echo message="${ant.project.name} build complete." />
</target>
<target name="clean">
<echo message="Cleaning ${ant.project.name}" />
</target>
<target name="build-ios" depends="clean">
<echo message="Building iOS ${ant.project.name}" />
</target>
<target name="build-android" depends="clean">
<echo message="Building Android ${ant.project.name}" />
</target>
<target name="deploy-ios" depends="build-ios">
<echo message="Deploying iOS ${ant.project.name}" />
</target>
<target name="deploy-android" depends="build-android">
<echo message="Deploying Android ${ant.project.name}" />
</target>
Then, in the game-* subdirectories, create a simple build.xml that links back to the common one.
game-1/build.xml:
<project name="game-1" default="build">
<import file="../build.xml" />
<echo message="=== Building Game 1 ===" />
</project>
game-2/build.xml:
<project name="game-2" default="build">
<import file="../build.xml" />
<echo message="=== Building Game 2 ===" />
</project>
Edit: If your build needs to include/exclude certain subprojects based on the user's input or a pre-defined property, you can modify the subant task's nested resource collection to accommodate for this.
<property name="game.includes" value="game-*" />
<property name="game.excludes" value="" />
<subant target="deploy">
<dirset dir="." includes="${game.includes}" excludes="${game.excludes}" />
</subant>
The user can then run a command that optionally passes values for game.includes and/or game.excludes. If these properties are not specified, the values defined above by the property task will be used as defaults.

How can I execute an ant target depending on the value of an environment variable?

I want to execute an ant script on two different computers. Depending on the name of the computer either one of the two targets should be executed. Following doesn't work:
<project name="import" default="all">
<property environment="env"/>
<target name="staging" if="${env.COMPUTERNAME}='STG'">
<echo>executed on staging</echo>
</target>
<target name="production" if="${env.COMPUTERNAME}='PRD'">
<echo>executed on production</echo>
</target>
<target name="all" depends="staging,production" description="STG or PRD"/>
</project>
As I understood, "if" can only be used with property and it checks whether a property is set or not. But is there a way to to make a condition depending on the value of a property?
I would suggest writing an "init" target that sets any conditions you need for later build steps, and also fails the build if certain required properties don't evaluate to what's expected.
For example:
<target name="all" depends="staging,production,init" />
<target name="staging" if="staging.environment" depends="init">
<echo message="executed on staging" />
</target>
<target name="production" if="production.environment" depends="init">
<echo message="executed on production" />
</target>
<target name="init">
<condition property="staging.environment">
<equals arg1="${env.COMPUTERNAME}" arg2="STG" />
</condition>
<condition property="production.environment">
<equals arg1="${env.COMPUTERNAME}" arg2="PRD" />
</condition>
<fail message="Neither staging nor production environment detected">
<condition>
<not>
<or>
<isset property="staging.environment" />
<isset property="production.environment" />
</or>
</not>
</condition>
</fail>
</target>

svclog file is not being generated

Been wasting a full day arround this problem.
This had never happen to me before.
My service is working in an Azure machine.
I'm trying to generate a .svclog file to trace whats causing my ios app not being able to login on https, but the svclog file is not being generated.
I tried to use fiddler to capture the requests but i get nothing when i try to login by the app.
If I try to use the app with http address im able to login but the svclog is also not generated.
If I use tcptrace i can see a request and an answer but it is encrypted.
I have given permissions to "Everyone" on the folder at c:\logs\
any idea what i might be missing here? is there some sort of pre requirement to make the tracer work
This is my system diagnostics in web.Config:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add initializeData="c:\logs\myMessages.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="messagelistener" traceOutputOptions="DateTime, Timestamp">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\logs\Traces.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="xmlTraceListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>

I want to use NAnt's foreach to iterate files in a folder, how to force alphabetic iteration?

I have an NAnt task "ship" to package my current .sql scripts into a build, then name the build with an incrementing int {######} and copy it to a build folder.
I have another NAnt task which executes those build scripts.
They must execute in order, but in my last attempt, they were not. Can I "force" NAnt to work alphabetically?
FAIL:
<fileset basedir="source\tsql\builds\" id="buildfiles">
<include name="*.sql.template.sql" />
<exclude name="*.sql" />
<exclude name="*asSentTo*" />
</fileset>
<foreach item="File" property"filename">
<in refid="buildfiles">
<echo message="${filename}" />
</in>
</foreach>
PASS:
<foreach item="File" property="filename" in="source\tsql\builds">
<do>
<if test="${string::ends-with(filename,'.sql.template.sql')}">
<echo message="${filename}" />
</if>
</do>
</foreach>
To satisfy my curiosity I tried to reproduce the problem with this script:
<?xml version="1.0"?>
<project name="foreach.test" default="foreach.alpha">
<target name="foreach.alpha">
<foreach item="File" in="C:\foo" property="filename">
<do>
<echo message="${filename}" />
</do>
</foreach>
</target>
</project>
The filenames are printed out in alphabetical order. So conventional use of foreach already seems to be the solution to the problem.
Here is how you do it with a fileset
<fileset id="mySet">
<include name="*.sql" />
</fileset>
<copy>
<fileset refid="mySet" />
</copy>
<foreach item="File" property="filename">
<in>
<items refid="mySet" />
</in>
<do>
<echo message="Copied files: ${filename} to directory: ${Folder}." />
</do>
</foreach>