Which Ant property contains the CWD when the ant script is run? - ant

I don't want to get the basedir -- that appears to contain the build.xml script -- I want the CWD of the call to ant itself.
Basically, I want to do this:
$ cd /home/chrisr/projects/some_project
$ ant -f ../../tools/ant-build-rules/library.xml build-library
At this point, I need two things:
The path to ant-build-rules in absolute form; this is currently found in the basedir property, so I'm set there.
The path of some_project, in absolute form. This is what I don't know how to get.
Which property contains this information?

The java property user.dir contains the current directory
<project name="demo" default="printCWD">
<target name="printCWD">
<echo message="${user.dir}"/>
</target>
</project>

There is no such property, but you can run a script to get it.
${bsh:WorkDirPath.getPath()}
See urbancode.com.

Related

Ant: override default target/artifacts directory

I am looking for property or settings which will override the default target/artifacts directory when we issue ant build command.
We have couple of modules and when we issue ant build, each modules creates artifacts under ./target/artifacts directory.
I want to override the output to custom directory. some thing like
./target/small/artifacts
./target/big/artifacts
based on the property which specifies which configuration to build. Either big/small.
Please let me know if there is any property/settings which can achieve this.
Can you just use normal Ant properties?
<!-- Default value if none specified. -->
<property name="artifacttarget" value="small"/>
<target ...>
<mkdir dir="target/${artifacttarget}/artifacts"/>
...
Then invoke:
ant -Dartifacttarget=small
ant -Dartifacttarget=big

How to determine Jenkins build directory from Ant?

I am trying to migrate an Ant script I wrote to build and deploy projects from within the Jenkins framework (instead of triggered from an SVN post-commit hook, which was the expedient way we initially approached things). Everything is great, except I need to stage files for the deploy step and I want to stuff them into the 'build' directory Jenkins creates for the job (and since my build.xml lives in a non-project-specific location, ${basedir} and ${user.dir} do not point to the desired location).
within the Jenkins configuration, I've setup the following:
[Jenkins]
Build Record Root Directory: E:/builds/${ITEM_FULLNAME}
[Job-Specific]
Build File: C:\vc-tools\shadow\build.xml
when running a build, the script is appropriately launched and a job-specific build directory is created, e.g.
E:\builds\Test\2012-08-07_12-51-21
I want to get at this directory from within the build script, but cannot figure out how. some of the things I've tried:
[echo] ${basedir}: C:\vc-tools\shadow
[echo] ${user.dir}: C:\vc-tools
[echo] ${env.workspace}: C:\Program Files (x86)\Jenkins\workspace\Test
[echo] ${env.build_id}: 2012-08-07_12-51-21
[echo] ${jenkins_home}: C:\Program Files (x86)\Jenkins
[echo] ${BuildDir}: E:/builds/${ITEM_FULLNAME}
note: for that last one, I tried passing in:
BuildDir=E:/builds/${ITEM_FULLNAME}
as a property configured from the job within Jenkins (clearly ${} expansion doesn't take place in this context).
according to the documentation, there are no specific environment variables that are set to the full build directory path -- I can fudge it by hardcoding the E:\builds root and tacking on ${env.build_id}, but was hoping there would be an easier way to access the complete path from something Jenkins exposes (either an Ant property and an environment variable) in order to make the script more flexible.
I am using Jenkins version 1.476.
thanks
It's always a good idea for your project to have a copy of it's build logic included alongside the source code. It makes your build more portable across machines.
Having said that it's also quite common to setup build files containing common shared build logic. ANT defines the following tasks to support such activity:
include
import
So a possible solution is to store a simple build.xml file, in the root of your project directory:
<project name="my project" default="build">
<include file="C:\vc-tools\shadow\common-build-1.0.xml" as="common"/>
<target name="build" depends="common.build"/>
</project>
Notes:
It's a good idea to use a revision number in the common build file name. This assists in preserving backward compatibility with other builds using the older logic.
Update
When Jenkins runs a job is sets a number of environment variables.
The following ANT logic will print the location of the Jenkins workspace directory:
<property environment="env"/>
<target name="run">
<echo message="Jenkins workspace: ${env.WORKSPACE}"/>
<echo message="Job directory: ${env.WORKSPACE}../../jobs/${env.JOB_NAME}"/>
<echo message="Build data: ${env.WORKSPACE}../../jobs/${env.JOB_NAME}/build/${env.BUILD_ID}"/>
</target>
These days (Jenkins v. 1.484) 'run' target from answer above should look like this:
<target name="run">
<echo message="Jenkins workspace: ${env.WORKSPACE}"/>
<echo message="Job directory: ${env.WORKSPACE}/../../${env.JOB_NAME}"/>
<echo message="Build data: ${env.WORKSPACE}/../../${env.JOB_NAME}/builds/${env.BUILD_ID}"/>
</target>

How to create temporary directory in ant?

I'd like to create a temporary directory in ant (version 1.6.5) and assign it to a property.
The command "mktemp -d" would be ideal for this, but I cannot find similar functionality from inside ant
I can't find any official function in the docs apart from the tempfile task which apparently only creates files, not directories.
I'm considering using exec to call tempfile and get the result, however this will make my build.xml dependent on UNIX/linux, which I'd like to avoid.
Background: I'm trying to speed up an existing build process which builds inside networked filesystem. The build already copies all the source to a temporary directory, however this is on the same filesystem. I've tested changing this to /tmp/foo and it gives a worthwhile speed increase: 3mins vs 4mins.
You could combine the tempfile task with the java.io.tmpdir system property to get a file path to use to create a temporary dir:
<project default="test">
<target name="test">
<echo>${java.io.tmpdir}</echo>
<tempfile property="temp.file" destDir="${java.io.tmpdir}" prefix="build"/>
<echo>${temp.file}</echo>
</target>
</project>
Note that the tempfile task does not create the file (unless you ask it to). It just sets a property which you can use to create a file or dir.
This task sets a property to the name of a temporary file. Unlike
java.io.File.createTempFile, this task does not actually create the
temporary file, but it does guarantee that the file did not exist when
the task was executed.
Output in my environment:
test:
[echo] C:\Users\sudocode\AppData\Local\Temp\
[echo] C:\Users\sudocode\AppData\Local\Temp\build1749402932
The answer above only hints at how to create a temporary directory. The point is that merely returns a string. A more complete answer is
<target name="temptest" description="test making tempdir">
<tempfile property="mytempdir" destdir="${java.io.tmpdir}"/>
<tempfile property="mytempfile" destdir="${mytempdir}"/>
<tstamp>
<format property="now" pattern="MMMM dd yyyy"/>
</tstamp>
<copy tofile="${mytempfile}">
<string value="today=${now}"/>
</copy>
<property file="${mytempfile}"/>
<echo message="It it now ${today}"/>
</target>

Passing a variable into ant

If I pass a variable to ant by doing
ant -Dsomething=blah
How can I refer to it in my build.xml? I tried #something# and ${something} but neither seem to work.
Ultimately what I am trying to do is set some properties (versions) at compile time.
update: the problem of course turned out to be somewhere else - accepting the most complete looking answer with examples
Don't you hate it when you over think these things:
<project name="test">
<echo message="The value of foo is ${foo}"/>
</project>
Now, I'll run my program. Notice that I never defined a value for property foo in my build.xml. Instead, I'll get it from the command line:
$ ant -Dfoo=BAR_BAR_FOO
test:
[echo] The value of foo is BAR_BAR_FOO
BUILD SUCCESSFUL
time: 0 seconds
See. Nothing special at all. You treat properties set on the command line just like normal properties.
Here's where the fun comes in. Notice that I've defined the property foo in my build.xml this time around:
<project name="test">
<property name="foo" value="barfu"/>
<echo message="The value of foo is ${foo}"/>
</project>
Now watch the fun:
$ ant
test:
[echo] The value of foo is barfu
BUILD SUCCESSFUL
time: 0 seconds
Now, we'll set the property foo on the command line:
$ ant -Dfoo=BAR_BAR_FOO
test:
[echo] The value of foo is BAR_BAR_FOO
BUILD SUCCESSFUL
time: 0 seconds
See the command line overrides the value I set in the build.xml file itself. This way, you can have defaults that can be overwritten by the command line parameters.
It sounds like you want to do something like the following:
<mkdir dir="build/src"/>
<copy todir="build/src" overwrite="true">
<fileset dir="src" includes="**/*.java"/>
<filterset>
<filter token="VERSION" value="${version}"/>
</filterset>
</copy>
...which will cause your source to get copied, replacing #VERSION#:
public class a { public static final String VERSION = "#VERSION#"; }
...and then include build/src in your javac src.
That said, I don't recommend this approach since the source copy step is expensive, and it will undoubtedly cause confusion. In the past, I've stored a version.properties file in my package with version=x.y. In my Java code, I used Class.getResourceAsStream("version.properties") and java.util.Properties. In my build.xml, I used <property file="my/pkg/version.properties"/> so that I could create an output-${version}.jar.
${argsOne} works for me and is easily referenced if the invoking command is
ant -DargsOne=cmd_line_argument
Ant documentation also says so. This should work, try running with ant -debug and paste the output.

Passing filepath to ANT from BAT script

I am trying to invoke an ANT target from Windows (right-click) file context menu.
I have setup the registry entries to invoke a batch script which invokes my ANT EXEC target.
I need to pass the path of the file (on which user right-clicked) to my ANT target. So I am using %~dp1 to set an ANT properties in my bat script:
Set tobeusedfilepath=%~dp1
Set tobeusedfile=%~n1
resulting in:
tobeusedfilepath=D:\Project\Rel L\
tobeusedfile=file
The problem is %~dp1 returns a string with "\" as file separator. But ANT EXEC task wants "/"
[exec] '-source'
[exec] 'D:ProjectRel L/file'
[exec] ......
[exec] The file, 'D:ProjectRel L/file', does not exist.
Any suggestions how to get around this path separators?
set AntPath="D:\Project\Rel L\"
set AntPath=%AntPath:\=/%
set AntPath=%AntPath::/=:%
gives
set AntPath="D:\Project\Rel L\"
set AntPath="D:/Project/Rel L/"
set AntPath="D:Project/Rel L/"
If you are running on Windows Ant will happily accept OS directory separator which is \.
Upon examination of the output of your program I see that the path separators are missing: you have D:ProjectRel not D:\Project\Rel. I may only guess that you are trying to exec a Cygwin program. Cygwin programs will use \ as an escape character. Therefore you need to use a <pathconvert> property to adjust the directory separators.
Code snippet below illustrates how to do this
<property name="tobeusedfilepath" location="D:\Project\Rel L\"/>
<property name="tobeusedfile" value="file"/>
<property name="system-path-filename"
location="${tobeusedfilepath}/${tobeusedfile}"
/>
<pathconvert property="unixized-filename" targetos="unix">
<path location="${system-path-filename}"/>
</pathconvert>
<echo message="system-path-filename=${system-path-filename}"/>
<echo message="unixized-filename=${unixized-filename}"/>
And here is the output of this run:
[echo] system-path-filename=D:\Project\Rel L\file
[echo] unixized-filename=D:/Project/Rel L/file

Resources