Include/Exclude buildfiles - nant

How do you do this? Given several build files, I only want to include the ones where the target (specified from the command line) exists. Using target::exists in does not seem to work. Thanks.
<target name="*">
<property name="curr.target" value="${target::get-current-target()}"/>
<nant target="${curr.target}">
<buildfiles>
<include name="*.build" if="${target::exists(curr.target)}"/>
<!-- avoid recursive execution of current build file-->
<exclude name="${project::get-buildfile-path()}" />
</buildfiles>
</nant>
</target>
Using robaker's solution, my final build file looks like this. It does not fail anymore if the target is not found in a certain build file (unlike my previous code).
<project>
<include buildfile="A.build"/>
<include buildfile="B.build"/>
<target name="*">
<nant target="${target::get-current-target()}"/>
</target>
</project>

Why not just use the include task to include all your child build scripts instead?

Related

phing toString method with fileset

Phing's documentation shows an example that should display a list all php files of a certain folder using a fileset with an id of "sourcefiles":
https://www.phing.info/guide/chunkhtml/ch04s02.html
(See 4.2.4)
So I put together a build-xml with this task:
<project default="countFile">
<property name="BUILD_DIR" value="./buildTest"/>
<target name="dist" depends="build">
<fileset id="sourcefiles" dir="${BUILD_DIR}">
<include name="./*.*" />
</fileset>
<echo>files in build dir: ${toString:sourcefiles}</echo>
<echo>build dir: ${BUILD_DIR}</echo>
<echo>OS: ${os.name}</echo>
</target>
</project>
I also tried the one-liner version from the documentation: <fileset id="sourcefiles" dir=".build" includes="**/*.txt"/>.
However, the output is nothing else but exactly that dollar-curly-brace-text as text: '${toString:sourcefiles}' instead of its interpolated result.
What would be the proper way to right it? Is this an error in the docs?
(I am not new to deployment, but new to phing.)
The include element inside your fileset has a non valid pattern. From the documentation
In patterns, one asterisk (*) maps to a part of a file/directory name within a
directory level. Two asterisks (**) may include above the "border" of the directory
separator.
Your example becomes:
<project default="countFile">
<property name="BUILD_DIR" value="./buildTest"/>
<target name="dist" depends="build">
<fileset id="sourcefiles" dir="${BUILD_DIR}">
<include name="*.*" />
</fileset>
<echo>files in build dir: ${toString:sourcefiles}</echo>
<echo>build dir: ${BUILD_DIR}</echo>
<echo>OS: ${os.name}</echo>
</target>
</project>
And will output something like:
Buildfile: C:\Users\XXX\test\build.xml
[autoloader] Loading autoloader from C:\Users\XXX\test/bootstrap.php
[php] Evaluating PHP expression: ini_set('error_reporting', -1);
[php] Evaluating PHP expression: ini_set('memory_limit', -1);
[php] Evaluating PHP expression: ini_set('date.timezone', 'UTC');
Phing Build Tests > test:
[echo] files in build dir: bootstrap.php;build.xml;phpunit-sparse.xml;phpunit.xml
BUILD FINISHED
Total time: 0.4785 seconds
Build finished at 30.11.2020 23:19 with exit code 0.
Also note that the ${toString:XXX} feature is only available for phing 3.x

Using cvs add command in Ant to 'update' a module

Using ant through eclipse. What I'm trying to do is to add files or subdirectories to a module that already exists in the repository.
The problem is that I do not know (or shouldn't) what kind of files or subdirectories the script is going to find in the previously checked-out module.
Checksout module -> Modifies it (adding files, subsdirs) -> Add that module to the control version -> Commits
I'm making an approach like this:
<target name="checkout" >
<cvs cvsrsh="plink" cvsroot="${cvsroot}" package="${mymodule}" dest="${extract.dir}" command="checkout"/>
</target>
<target name="cvs_add" >
<cvs cvsrsh="plink" cvsroot="${cvsroot}" package="${mymodule}" dest="${extract.dir}" command="add -kb"/>
</target>
And getting this message:
[cvs] cvs add: in directory .:
[cvs] cvs [add aborted]: there is no version here; do 'cvs checkout' first
I also tried using ant-contrib's 'foreach', in order to navigate between files and subdirs, also not working.
I'd love a non-ant-contrib advice in this matter, or something not related with exec task. But I'm open minded.
I have came up with this solution:
<ac:for param="file">
<path>
<fileset dir="${mymodule}">
<!-- <include name="**/*.jar"/> -->
</fileset>
</path>
<sequential>
<local name="filename" />
<basename property="filename" file="#{file}"/>
<echo message="${filename}"/>
<cvs cvsrsh="plink" cvsroot="${cvsroot}" dest="${mymodule}" command="add -kb ${filename}"/>
</sequential>
</ac:for>
I finally surrender to ant-contrib. If anyone make a different approach, let me know.

Phing: get a filename without the extension

Given a Phing loop such as this
<target name="lessc">
<exec command="lessc ${absolute-filename}" logoutput="false" output="${project.basedir}/public/assets/css/libraries/${filename}" />
</target>
<target name="build-in-loop">
<foreach param="filename" absparam="absolute-filename" target="lessc">
<fileset dir="${project.basedir}/assets/less/libraries/">
<include name="*.less"/>
</fileset>
</foreach>
</target>
In target lessc, how can I extract the file name without extension from the variable absolute-filename? In the example above, the output file will have the extension .less - obviously not what I need.
I know there is a task made for less, and that I could extend Phing to support this specific operation, but I would like to know first if Phing basically allows simple string manipulation on variables.
Found the answer, not sure if it's the best solution, but works for me:
just need to use the mapper tag
<mapper type="glob" from="*.less" to="*"/>
in the foreach loop, like this:
<target name="build-in-loop">
<foreach param="filename" absparam="absolute-filename" target="lessc">
<fileset dir="${project.basedir}/assets/less/libraries/">
<include name="*.less"/>
</fileset>
</foreach>
</target>
At this point, in the variable ${filename} in the target task there will be the filename without extension.

NAnt ignoring property in included build file

I'm trying to make my project build file include a local build file, to allow for some customization for each developer, without having to keep exclulding the build file from version control commits etc.
But NAnt keeps ignoring the properties in my included build file, and not overwriting the properties set in the global build file.
For demo purposes this short build file behaves the same:
<project name="FooProject" default="showme" basedir="." >
<description>Foo</description>
<!-- Overwrite this property in local.build -->
<property name="database.connectionstring" overwrite="true" readonly="false" value="foo" />
<include buildfile="local.build" failonerror="true" verbose="true" />
<target name="showme" description="Show connectionstring variable">
<echo message="Connectionstring: ${database.connectionstring}" />
</target>
</project>
-and my local.build file looks like this:
<property name="database.connectionstring" value="bar" />
The expected output when running NAnt with this build file is "Connectionstring: bar", but the resulit is "Connectionstring: foo", no matter which combination of readonly and overwrite I try.
It does fail if I rename the file to something else, so NAnt is aware of the included file.
NAnt is v0.91 alpha.
Am I overlooking something or is NAnt not supposed to work like I expect?
It seems you should still wrap the contents of the included build file inside a project-element. Like so:
<project>
<property name="database.connectionstring" value="bar" />
</project>
When I did that the connectionstring was "bar".
Granted: I use Nant 0.91 final.

NAnt - Including source files in a csc task outside of the base directory

I am just starting to pick up NAnt as a replacement for MSBuild in our CruiseControl project.
One of the things we do inside a set of projects is link in a single AssemblyInfo.cs file from outside of the project tree to make versioning easier (it lives in a directory above the project folders).
Is there an obvious way of achieving this in the <sources> section of the <csc> task?
From what I can tell, the <sources> section only supports a single <include> element, which must be underneath the basedir of the task.
I suppose another option would be to copy the single AssemblyInfo.cs file as part of the task prior to calling csc, but wondered whether there was a cleaner way of doing this.
You are not limited to a single <include/> in <sources/>. You can reference whatever you want if you don't specift the basedir property of <sources/>:
<csc target="exe" output="HelloWorld.exe" debug="true">
<sources>
<!-- Will use project dir as base dir -->
<include name="**/*.cs" />
<!-- Absolute path -->
<include name="/tmp/42/*.cs" />
<!-- Relative to project dir -->
<include name="../../Shared/*.cs" />
</sources>
<references>
<include name="System.dll" />
<include name="System.Data.dll" />
</references>
</csc>