How to create temporary directory in ant? - 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>

Related

Ant: How to call a directory with php files and save the result as overwritten files

How can I use Ant to execute each php file in a directory? The output for the php execution should overwrite the original file.
The directory is on a localhost webserver with php installed. I assume the solution would involve GET and have src point to the http equivalent of each file.
Some dynamic version of
c:/webroot/php/file1.php
c:/webroot/php/file2.php
translate into
get src="localhost/php/file1.php"
get src="localhost/php/file2.php"
and then have the output overwrite itself.
Why not use the php command line combined with the ANT apply task?
Something like:
<apply executable="C:\PHP5\php.exe">
<arg value="-f"/>
<fileset dir="c:/webroot/php" includes="*.php"/>
</apply>
It's not clear to me why you want to overwrite your source files....
Update
Alternatively use an embedded groovy script
<fileset id="phpfiles" dir="c:/webroot/php" includes="*.php"/>
<groovy>
project.references.phpfiles.each {
def file = new File(it.toString())
ant.get(src:"http://localhost/php/${file.name}", dest:"output/${file.name}")
}
</groovy>

Ant Task to FTP only specified files

I have an Ant task that FTPs all files in a specified directory, and it uses a fileset:
<fileset dir="${publicDirectory}">
<include name="media/**/*" />
</fileset>
I have a file that contains all the files that I would like to include:
media/some/dir/1.txt
media/some/other/2.txt
...
How can I have the fileset read the file and only include whatever I've listed there?
I've tried quite a few things, but nothing seems to be able to get around a basic issue: The <ftp> task works only on filesets and not other types of resources. I've tried various filterchains, but to no avail.
The best I could come up with was using the Ant-Contrib <for> or <foreach> task to loop through the file and then use an <exec> task to execute the command line version of ftp.

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>

listing all files and subdirectories using ant

I am trying to create a rpm package using ant task for that I need to create specfile which will have all the file names in the following format
%attr(0755, root, root) %dir dir1
%attr(0755, root, root) %dir dir1/dir2
%attr(0755, root, root) %dir dir1/dir2/dir3
%attr(0500, root, root) dir1/file1
%attr(0500, root, root) dir1/dir2/file1
I have such directory structure created during my build process but using ant I am not able to list all the files and directories which I can then write into my specfile
following is what I have tried to list the files but it does not differentiate between files and directory , moreover I need some way to iterate over the list.
<fileset id="dist.contents" dir="${nativePackageDir}" includes="**"/> |
<property name="prop.dist.contents" refid="dist.contents"/> | <target name="javaobject-library" depends="props">
<echo>${prop.dist.contents}</echo>
<dirset id="dist.contents" dir="${nativePackageDir}" includes="*"/>
<property name="prop.dist.contents" refid="dist.contents"/>
<echo>${prop.dist.contents}</echo>
Using dirset instead of fileset should fix your problem.
You simply have to write in java an ant task implementation, to which you'll provide as parameters the input directory and the path of the specfile you want to be written.
I find it better and more manageable to have reusable ant tasks in java, instead of having gigantic ant xml files.

Ant delete task

I have several files with name abc* and i want to delete all those files. is it possible using ant task. For eg. my directory structure is:
c:\
myapp\
abc.xml
abc.txt
abc-1.2.xml
abc-abc.xml
abcdef.xml
pqr.xml
xyz.xml
abc\
so from this, i need to delete all abc* files. So if i use ant it should delete following:
abc.xml
abc.txt
abc-1.2.xml
abc-abc.xml
abcdef.xml
it should leave directory with abc*
Can somebody help me.
Almas
<target name="testingdelete" >
<delete>
<fileset dir="." includes="**/abc*"/>
</delete>
</target>
should work.
It deletes all files with abc* and leaves behind directories named abc. It will delete from all sub-directories as well.

Resources