I have made a build file for the automated compilation of Oracle Forms files. An excerpt of the code is as follows:
<target name="build" description="compiles the source code">
...
<foreach item="File" property="filename" failonerror="false" >
<in>
<items basedir="${source.directory}\${project.type}\Forms">
<include name="*.fmb" />
</items>
</in>
<do>
<exec program="${forms.path}" workingdir="${source.directory}\${project.type}\Forms" commandline="module=${filename} userid=${username}/${password}#${database} batch=yes module_type=form compile_all=yes window_state=minimize" />
</do>
</foreach>
...
</target>
The build file navigates to the directory containing the forms that the user desires fo compile and attempts to compile each form. The failonerror attribute is set to false so that the build file does not exit if a compilation error occurs. Unfortunately, however, though this prevents the build file from exiting when a compilation error occurs, it also appears to make the build file exit the task. This is a problem because, unless the form that does not compile successfully is the last to be tested (based on the filename of the form in alphanumerical decsending order), there will be one or more forms that the build file does not attempt to compile. So, for example, if the folder containing the forms that are desired to be compiled contains 10 forms and the first form does not compile successfully, the build file will not attempt to compile the remaining 9 forms (ie exit the task). Is there a way to make the build file attempt to compile remaining forms after encountering after failing to compile a form? Thanks in advance!
Apologies, this has now been solved. The problem is that the you need to set “failonerror” in the task instead.
Related
I need to add the ability to a phing build to:
Parse an existing xml file within the project area to get an existing build number (in format 1.2.3)
Ask the user what type of 'change' this is (i.e. major, minor, fix)
Based on the response of the user at the time of run, upgrade the respective digit from the build number (if major increase 1 by 1; if minor increase 2 by 1; if fix increase 3 by 1)
Store the build number back into the original xml file
Have the new build number available for use when naming a zip file (later in the build).
Wondering if anyone already has a phing build file that does something like this or if you happen to know what phing tasks might help with these steps?
As a starting point you could do it without overhead using the version task (it uses a property file to store the version information) or with some more effort from a xml file.
The following example build script (documentation links can be found in the description attributes) contains both ways.
<?xml version="1.0" encoding="UTF-8" ?>
<project name="version test"
default="help"
phingVersion="3.0"
description="https://stackoverflow.com/questions/68584221/phing-update-version-number-in-xml-manifest"
>
<target name="help" description="usage help">
<echo>Usage:</echo>
<echo>bin/phing xml-file-based-workflow</echo>
<echo>bin/phing property-file-based-workflow</echo>
</target>
<target name="xml-file-based-workflow"
description="version handling with xml file"
depends="user-input,handle-xml-version,use-version"
/>
<target name="property-file-based-workflow"
description="version handling with property file"
depends="user-input,handle-property-version,use-version"
/>
<target name="user-input"
description="https://www.phing.info/guide/hlhtml/#InputTask"
hidden="true"
>
<input message="what is your release type?" propertyName="release.type" defaultValue="Bugfix"/>
</target>
<target name="handle-property-version"
description="https://www.phing.info/guide/hlhtml/#VersionTask"
hidden="true"
>
<version releasetype="${release.type}" file="VERSION.txt" property="version.number"/>
</target>
<target name="handle-xml-version"
description="
https://www.phing.info/guide/hlhtml/#XmlPropertyTask
https://www.phing.info/guide/hlhtml/#EchoPropertiesTask
https://www.phing.info/guide/hlhtml/#VersionTask
https://www.phing.info/guide/hlhtml/#DeleteTask
https://www.phing.info/guide/hlhtml/#EchoXMLTask
"
hidden="true"
>
<xmlproperty file="VERSION.xml" />
<echoproperties destfile="VERSION.txt" regex="/version\.number/"/>
<version releasetype="${release.type}" file="VERSION.txt" property="version.number"/>
<delete file="VERSION.txt"/>
<echoxml file="VERSION.xml">
<version>
<number>${version.number}</number>
</version>
</echoxml>
</target>
<target name="use-version"
description="https://www.phing.info/guide/hlhtml/#EchoTask"
hidden="true"
>
<echo message="${version.number}" />
</target>
</project>
In short, my problem is:
How to load an NAnt script in side a custom task, and execute it?
Detailed explanation:
In our current project build, we need to execute external programs. The external programs need to be located before the build kicks off. (coz it takes so looong time)
What I want is to have some NAnt module, like those FindXXX.cmake modules in CMake, so I can have modules like:
<?xml version="1.0"?>
<project name="FindSQLServerCore" default="FindSQLServer">
<target name="FindSQLServer">
<module>
<path>
<pathelement dir="C:\Program Files\Microsoft SQL Server\100\Tools\Binn" />
<pathelement dir="C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn" />
</path>
<files>
<file name="SQLCmd.exe" />
</files>
</module>
</target>
</project>
And when I need to include SQLServer in my build script, I can do:
<find module="SQLServer" required="true" />
My way to do it is by create 2 custom tasks: FindTask & ModuleTask.
FindTask is going to locate the FindXXX.include and loaded it into current NAnt project.
ModuleTask is going to find specified file under given path and return results.
But I cannot find ways to create & execute NAnt tasks by loading a build script in FindTask. The Project.CreateTask(XmlNode) only accepts node that is already loaded but not from newly loaded XML.
Is there a way to create task by loading a build script inside a custom task?
Or is my way doing this the NAnt style? Any better ways to achieve same goal?
PS. You might ask why not just use
<include file="FindSQLServer.include" />
The reason I'm not doing it this way is I want to pass the required parameter in, but not set it as a variable and pass it in.
You can get the NANT extension here:NAntFind#github
One way to load an NAnt script and execute it inside a custom task is to create a new project, and load the script using the project, then execute. Example:
var findProject = new Project(nantModule, Level.Info, Project.IndentationLevel);
findProject.Execute();
If the project fails, an exception should be thrown out.
I have an ant script which does in the beginning some checks and then compiles the code and deploys it to the tomcat server. The script for the build-war-deploy process looks like this:
<target name="build-war-deploy" depends="clean-up,gwtc,check-settings" description="Package GWT app to web archive and deploy to web server">
<war basedir="${war.dir}" destfile="${deploy.dir}/${app.name}.war" webxml="${webinf.dir}/web.xml">
<!-- <include name="WEB-INF/**" /> -->
<webinf dir="${webinf.dir}/">
<include name="**/*.jar" />
</webinf>
</war>
</target>
This target works perfectly fine, meaning after running the ant script the application is indeed deployed on tomcat.
After the build-war-deploy target I need to do some cleanup processes and therefore I created some other targets and added an dependency to the build-war-deploy target so that it is being executed afterwards.
<target name="cleanup" depends="build-war-deploy" description="clean up processes">
<exec dir="./" executable="python" failonerror="true">
<arg line="deploy_cleanup.py ${app.name}" />
</exec>
</target>
However, after the ant script executes the build-war-deploy target it stops and says that the build was successful. Does anyone know why it did not perform the last target?
build-war-deploy:
[war] Building war: C:\Apache Tomcat\apache-tomcat-6.0.33\webapps\test.war
BUILD SUCCESSFUL
Total time: 2 minutes 22 seconds
I would try using an outputproperty. Perhaps the python file is executing -- not doing what you want but executing and returning the results which you never see. I mean if the python script returns an error message, doesn't ant view that as successfully executing?
Something like:
<exec dir="./" executable="python" outputproperty="outProp" failonerror="true">
<arg line="deploy_cleanup.py ${app.name}" />
</exec>
<echo>${outProp}</echo>
outputproperty: The name of a property in which the output of the command should be stored. Unless the error stream is redirected to a separate file or stream, this property will include the error output.
I am using acceleoCompiler inside an ant script and when i run the ant script everything shows an output except acceleoCompiler.
For instance, [javac] and [mkdir] shows up. But nothing relating to acceleoCompiler shows up. Am i doing something wrong?
The ant script:
<eclipse.refreshLocal resource="${F_FOLDER}/bin/" depth="infinite"/>
<eclipse.refreshLocal resource="${FE_FOLDER}/bin/" depth="infinite"/>
<mkdir dir="${F_OUTPUT}"/>
<mkdir dir="${FE_OUTPUT}"/>
<javac
srcdir="${F_SRC}generator/"
destdir="${FR_OUTPUT}"
executable="${JAVA_JDK}/javac"
fork="true"
includeantruntime="false"
failonerror="false"
/>
<javac
srcdir="${FE_SRC}generator/"
destdir="${FE_OUTPUT}"
executable="${JAVA_JDK}/javac"
fork="true"
includeantruntime="false"
failonerror="false"
/>
<acceleoCompiler sourceFolder="${F_SRC}"
outputFolder="${F_OUTPUT}"
dependencies=""
binaryResource="true"
packagesToRegister="org.eclipse.emf.ecore.EcorePackage">
</acceleoCompiler>
<acceleoCompiler sourceFolder="${F_SRC}"
outputFolder="${FE_OUTPUT}"
dependencies=""
binaryResource="true"
packagesToRegister="org.eclipse.emf.ecore.EcorePackage">
</acceleoCompiler>
The absence of logging messages doesn't mean you're doing anything wrong. If you look at the source for mkdir or javac you'll see that they call the Ant Task method log() in most cases. The Acceleo Ant task however only calls log() if it finds a problem - if all is well it is silent and enigmatic.
References:
Ant mkdir task source.
AcceleoCompiler source via the Acceleo wiki FAQ.
I have a generic common.xml file that holds a number of generic nant targets that are re-used among multiple builds. What I want to do is 'override' some of these nant targets and include additional steps either before or after the existing target is executed.
Are nant targets used from the current file first? ie. If i create a nant target in the current buildfile with the same name as a target in an included file does that one get called and the included one ignored? If that's the case I can just do and call the included target but it would seem like then that would be a recursive call rather then to an included task.
Thoughts?
I had the same question (and found the same results), but I also found a workaround. Allow me to illustrate with an example.
You have a ProjectFile.build and a CommonFile.build. Let's say you want to overwrite a target called "Clean".
You would need to create a new file (call it CommonFile_Clean.build) which contains:
<?xml version="1.0"?>
<project>
<target name="Clean">
<echo message="Do clean stuff here" />
</target>
</project>
In CommonFile.build, you conditionally include CommonFile_Clean.build:
<?xml version="1.0"?>
<project>
<echo message="checking Clean definition..." />
<if test="${not target::exists('Clean')}">
<echo message="Clean target not defined." />
<include buildfile="CommonFile_Clean.build" />
</if>
</project>
In ProjectFile.build, you can either define the Clean target (in which case CommonFile_Clean.build will not be used) or use the default implementation as defined in CommonFile_Clean.build.
Of course, if you have a large number of targets, this will be quite a bit of work.
Hope that helps.
No, I've just tried it for you, as I have a similar set-up, in that I have all of the build targets we use in a commonFile.build and then use the following code to bring it in...
<include buildfile="../commonFile.build"/>
In my newFile.build (that includes the commonFile.build at the top of the file), I added a new target called 'build', as it exists in the commonFile, and here's the error message you get in response...
BUILD FAILED
Duplicate target named 'build'!
Nice idea, probably bourne of OO principles, but sadly it doesn't work.
Any good?