Phing: Reprompt after invalid database connection details - phing

I'm writing a Phing task that needs to connect to a database using details supplied by the user.
I am able to prompt the user for the host/user/password/database and test the details using the PDOSQLExecTask.
What I don't know how to do is re-prompt the user to re-supply the details if they are found to be invalid, and keep re-prompting until they get it right.
The following block was my attempt, but it errors because Phing doesn't like when a task calls itself.
<target name="prompt-and-test-database-connection">
<trycatch>
<try>
<input propertyName="db.host" message="Database host" promptChar=":" />
<input propertyName="db.user" message="Database user" promptChar=":" />
<input propertyName="db.pass" message="Database password" promptChar=":" />
<input propertyName="db.name" message="Database name" promptChar=":" />
<echo message="Testing connection..." />
<pdosqlexec url="mysql:host=${db.host};dbname=${db.name}" userid="${db.user}" password="${db.pass}" onerror="continue">
USE `${db.name}`;
</pdosqlexec>
</try>
<catch>
<echo level="error">Invalid database connection details. Please try again.</echo>
<phingcall target="prompt-and-test-database-connection" />
</catch>
</trycatch>
</target>

You can use <retry> task. Since <retry> only accepts one nested task I extracted the connection in another task. The following works for me:
<target name="try-connection">
<retry retryCount="3">
<phingcall target="connection"/>
</retry>
</target>
<target name="connection">
<input propertyName="db.host" message="Database host" promptChar=":"/>
<input propertyName="db.user" message="Database user" promptChar=":"/>
<input propertyName="db.pass" message="Database password" promptChar=":"/>
<input propertyName="db.name" message="Database name" promptChar=":"/>
<echo message="Testing connection..."/>
<pdosqlexec url="mysql:host=${db.host};dbname=${db.name}"
userid="${db.user}"
password="${db.pass}"
onerror="continue">
USE `${db.name}`;
</pdosqlexec>
</target>

Related

phing dbdeploy with postgres

Hiho,
I want to use Phing an dbdeploy with a postgres DB.
the problem is that I can not connect to the database with the connection string because I can not define a password.
Does any one has an solution for this?
The following is the deply xml:
`
<!-- load the dbdeploy task -->
<taskdef name="dbdeploy" classname="phing.tasks.ext.dbdeploy.DbDeployTask" />
<!-- these two filenames will contain the generated SQL to do the deploy and roll it back -->
<property name="build.dbdeploy.deployfile" value="scripts/deploy-${DSTAMP}${TSTAMP}.sql" />
<property name="build.dbdeploy.undofile" value="scripts/undo-${DSTAMP}${TSTAMP}.sql" />
<!-- generate the deployment scripts -->
<dbdeploy
url="pgsql:host=${db.host};dbname=${db.name}"
userid="${db.username}"
password=""
dir="${phing.dir}/sql"
outputfile="${build.dbdeploy.deployfile}"
undooutputfile="${build.dbdeploy.undofile}" />
<!-- execute the SQL - Use psql command line to avoid trouble with large
files or many statements and PDO -->
<trycatch>
<try>
<exec
command="pqsql -h${db.host} -U${db.username} -p${db.port} -d${db.name} < ${build.dbdeploy.deployfile} -W"
dir="${phing.dir}"
checkreturn="true"
output="${phing.dir}/cache/deploy-${DSTAMP}${TSTAMP}.log"
error="${phing.dir}/cache/deploy-error-${DSTAMP}${TSTAMP}.log"
/>
<echo msg="Datenbank erfolgreich ausgerollt"/>
</try>
<catch>
<echo msg="Fehler beim ausrollen der Datenbank, führe Rollback durch"/>
<exec
command="pgsql -h${db.host} -U${db.username} -p${db.port} -d${db.name} < ${build.dbdeploy.undofile}"
dir="${phing.dir}"
checkreturn="true"
/>
<echo msg="Rollback erfolgreich"/>
</catch>
</trycatch>
</target>
<!-- ============================================ -->
<!-- Target: writeFiles -->
<!-- ============================================ -->
<target name="writeFiles" description="Write all properties in files">
<copy
file="${dir}config/autoload/local.php.dist"
tofile="${dir}config/autoload/local.php"
overwrite="true"
>
<filterchain>
<replacetokens begintoken="#" endtoken="#">
<token key="db.host" value="${db.host}"/>
<token key="db.username" value="${db.username}"/>
<token key="db.password" value="${db.password}"/>
<token key="db.name" value="${db.name}"/>
<token key="db.port" value="${db.port}"/>
</replacetokens>
</filterchain>
</copy>
<echo>local.php geschrieben.</echo>
</target>`
You can create a password file for the system user (the user which will execute the phing script).

How do I check if a file contains a string (using Nant)?

At the moment I'm calling findstr and storing the output in a property to check afterwards - I'm sure there must be a better solution.
<exec program="findstr.exe"
workingdir="${workspaceDir}"
commandline='/i /c:"someText" ${fileName}'
failonerror="false"
output="${coverageExcludeLog}"
resultproperty="foundFile"
/>
Is this really the best way of doing this?
<loadfile file="${fileName}" property="MyFileContents" />
<property name="Mystring" value="someText" />
<property name="search.file" value="${string::contains(MyFileContents, Mystring)}" />
<if test="${bool::parse(search.file)}" > <!-- true or false-->
<echo message="Found the string ${Mystring} in the file ${fileName}" />
</if>

phing input task within if strange behaviour

I'm encountering the following:
<target name="test_something">
<if>
<equals arg1="1" arg2="1" />
<then>
<input propertyname="confirm_cleanup" defaultValue="y" validArgs="y,n" promptChar="?">Hello</input>
</then>
</if>
</target>
When I run the task, the output is: HelloHelloHelloHello(y,n) [y]?
Any ideas why it is echoed 4 times?
Cheers

Nantcontrib <record> task

I am trying to attach a log file to email.
My code is:
**<loadtasks assembly=".../tasks.dll" />
<record name="c:foo\log.txt" action="Start" />
<target name="email">
<mail
from="abc#foo.com"
tolist="xyz#foo.com"
subject="Build"
message="Build Failed"
mailhost="smtp.anywhere.net">
<files>
<include name="c:foo\log.txt" />
</files>
<attachment>
<include name="c:foo\log.txt" />
</attachment>
</mail>
</target>
<record name="c:foo\log.txt" action="Close" />**
My command is:
nant -f:filename.build email -l:c:foo\log.txt
I get following error:
System.Security.SecurityException: Request for the permission of type 'System.Se
curity.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMa
rk& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.IO.FileSystemInfo.get_FullName()
at NAnt.Contrib.Tasks.RecordTask.ExecuteTask()
at NAnt.Core.Task.Execute()
at NAnt.Core.Project.InitializeProjectDocument(XmlDocument doc)
at NAnt.Core.Project.Execute()
at NAnt.Core.Project.Run()
When i dont use <record> tasks it gives another error like, could not attach txt file. bcoz it being used by another process.
Why am I getting this error?
i do something like flush in record task , just before sending email then copy the file to attach in email , hope this workaround works
<echo>${emailsubject}</echo>
<echo>Sending Email</echo>
<echo>Attaching File : ${build.log.dir}/email_${build.log.filename}</echo>
<echo>Attaching File : ${path.vsshelper.log}/logs/email_${build.log.getlistoffiles}</echo>
<record name="${build.log.dir}/${build.log.filename}" action="Flush" level="Verbose"/>
<sleep milliseconds="5000" />
<copy file= "${build.log.dir}/${build.log.filename}" tofile="${build.log.dir}/email_${build.log.filename}" />
<copy file= "${path.vsshelper.log}/logs/${build.log.getlistoffiles}" tofile="${path.vsshelper.log}/logs/email_${build.log.getlistoffiles}" />
Make sure that the file is closed before you try to email it.

nant logs with data and time stamp

How to run NAnt scripts in command line and get the timings of each task on the log file?
using nant <record> task or
NAnt -buildfile:testscript.build testnanttarget
This produces console output but I can't see any timing information.
All I want each log message prefixed with datatime.
You can use the tstamp task to display the current date/time. Just include it everywhere where you want timing information. It will not prefix each line with a timestamp, but at least you can time some strategic points.
<tstamp />
Here is a sample of tstamp
<echo>
-----------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
TASK : INITIALIZE
-----------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
</echo>
<loadtasks assembly="nantcontrib-0.85/bin/NAnt.Contrib.Tasks.dll" />
<!-- http://www.basilv.com/psd/blog/2007/how-to-add-logging-to-ant-builds -->
<tstamp>
<formatter property="timestamp" pattern="yyMMdd_HHmm"/>
</tstamp>
<property name="build.log.filename" value="build_${timestamp}.log"/>
<echo message="build.log.filename: ${build.log.filename}" />
<record name="${build.log.dir}/${build.log.filename}" action="Start" level="Verbose"/>
<echo message="Build logged to ${build.log.filename}"/>
<echo message="Build Start at: ${datetime::now()}" />
</target>