How can I use the Ant tar task and preserve file permissions? - ant

Of course it can be done using the exec task, but my question is:
Is it possible to do it using the tar task?

I don't think there is a way to retain existing permissions, per this note from the copy task:
Unix Note: File permissions are not retained when files are copied; they end up with the default UMASK permissions instead. This is caused by the lack of any means to query or set file permissions in the current Java runtimes. If you need a permission-preserving copy function, use <exec executable="cp" ... > instead.
However the tar task can take one or more tarfileset elements. The tarfileset can be defined with a filemode and/or dirmode attribute to specify the unix permissions. If you specify multiple includes matching only those files to get each set of required permissions, the files in that set will be included with those permissions.

It is impossible. This lack of permission makes ant tar task almost useless for me. There's no way to do it without executing the operating system tar with the exec task:
<exec executable="tar" output="/dev/null" os="Linux">
<arg value="--exclude-from=files_to_exclude.txt"/>
<arg value="-cvz"/>
<arg value="--file=${file.tar}"/>
<arg value="."/>
</exec>
There are gnu tar binaries for almost all operating systems known to man. Put one of them in your version control system and use it depending in your operating system. Yes, Ant will need to fork a process every time it is run.

Using tarfileset worked for our project. Here's a working example in case someone needs it:
<tar destfile="${dist}/${module.name}-${version}.tar">
<tarfileset dir="${package.dir}" filemode="550" includesfile="${home.dir}/includelist.txt">
<include name="*.sh"/>
</tarfileset>
</tar>
In this example, includelist.txt is used to tell which files to include in the tar file. All the files with *.sh extension will have Read and Execute permission (550) for the user and the group.
Hope this helps someone.

Related

Make a script executable in bin directory ant

Here is my ant script that wants to convert the script to executable from a zip. Here is what I do:
unzip a .zip file,
store to temp directory
run the script 'pkg' with a argument validate
<chmod dir="tmp/temp/test/bin" perm="ugo+rx" includes="**/*" />
<echo message="Making scripts exec: tmp/temp/test/bin" />
<exec executable="/bin/bash">
<arg value="tmp/temp/test/bin/pkg"/>
<arg value="validate"/>
</exec>
This does not make the script executable and instead gives this error:
Execute failed: java.io.IOException: Cannot run program "D:\tmp\temp\test\bin": CreateProcess error=5, Access is denied.
Cannot run program "D:\tmp\temp\test\bin": CreateProcess error=5, Access is denied.
Are you running this under Windows or Linux/Unix/MacOS?
Windows doesn't have the concept of executability in a file. Instead, it associates file suffixes with executable programs. For example, I could associate the .py suffix to be associated with the python.exe program. Opening foo.py will run that Python script under the Python executable. Change the name to foo.pl, and either the script won't run, or if you've associated .pl with perl.exe, will run the script under Perl.
You can add the suffix of your script to the %PATHEXT% environment variable which will allow you to type the file name sans extension. For example, if I added .py to %PATHEXT%, and I type in foo into the command line terminal, Windows may look for foo.py and then execute that. (unless it finds foo.exe or foo.bat first. Then those would execute).
The <chmod> task does nothing under Windows. In the <chmod> man page, it states:
Changes the permissions of a file or all files inside specified directories. Right now it has effect only under Unix or NonStop Kernel (Tandem).
Also, not all Zip implementations can store file permission and ownership information -- especially Unix style permissions and ownership. Some can, and some can't. Even if you somehow want to express the file's executability for Unix systems, it may not work.
What I recommend is to include a <condition> test in your script to test for the OS. Then, you can separate what to do if you're on Linux/Windows/MacOS and what you want to do on a Windows system.

Ant exec - Run executable from a network drive

I am running the following command from my ant target:
<exec executable="${soa.mypath}\deploy.exe" failonerror="true" vmlauncher="false">
<arg value="-n" />
<arg value="${myfile}" />
</exec>
Where ${soa.mypath} is B:\bin.
This drive B is a network drive that I mapped on a other server.
when I connect remotly to the server where that ant script is running I can totally see and browse the B drive via the Windows explorer and the user I use is the same user that runs tha ant script.
However when I run my target, I got this error:
[exec] The system cannot find the drive specified.
Which is very weird.
Do you know if I am missing some option in the exec command?
Thank you,
Regards
Using ant 1.9.3 under Windows 8.1 I was able to get this to work with no problem with a network-mounted drive, including various combinations of forward and backslashes in the path.
My only suggestion is to replace your property with the hard-coded executable path (B:\bin\deploy.exe) in the exec task and see if that works. Also - use hard-coded path to ${myfile}.
If deploy.exe has a -version command or similar you might also try that, to rule out the problem actually being in the drive/path of ${my file}.
hth

Multiple Ant properties files

Ant seems to be ignoring one of my properties files.
<property file="local.properties" />
<property file="build.properties" />
build.properties contains the typical properties my team wants to use. I'm introducing local.properties which contains overrides for my specific workstation. We're using Eclipse for this project (I'm using Kepler), but regardless of whether I build in Eclipse or build via the command line the build fails because it is using some values in build.properties even though local.properties contains overrides.
In my specific case, my version of Java is newer than the other developers/environments. Despite specifying the version I have in local.properties, it still tries to use the compiler for the version in build.properties.
I know the values are fine because if I put my local properties in build.properties everything works.
Eclipse doesn't care about your build.xml or your properties files. That's only with Ant.
Try running ant with the -d flag, and capture STDOUT and STDERR. This will show you whether or not the local.proeprties is being read in and what values are set. It will say whether or not it's attempting to read local.properties, whether it found local.properties, and if so, what properties are being set.
Also remember that properties are set first come/first serve. You didn't say where in your build.xml you're reading in local.properties. It could be that this is being read in a target while other properties are set outside of targets. Even if they appear later in the build.xml file, properties set outside of any target are set first. If these are set, and you read in local.properties, local.properties isn't going to over ride them. I mention this because it was a problem I ran into here. Someone had a bunch of <property/> tasks placed at the end of their build.xml,and they didn't realize that these would be set before any target was run.
Again, try this:
Unix and Mac:
$ ant -d 2>&1 | tee ant.out # Allows you to see and capture the results
Windows
$ ant -d > ant.out 2>&1 # There's no "tee" command in Windows.
The output of ant.out will be thousands of lines long, but it'll help you figure out what's going on. What you post looks correct.

ant copy tag won't keep file kind

I'm trying to build a Mac OS X bundle application automatically.
When copying the file "/System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/MacOS/JavaApplicationStub" of kind "Unix Executable File" with the copy tag:
<copy file="${stub.file}" todir="${dist.dir}/${ant.project.name}.app/Contents/MacOS"/> and getting a file of kind "Document" and the bundle doesn't execute. If I copy it from Finder it works fine.
Is there a way to copy it and keep it's kind with ant?
Thanks in advance!
The file ist copied correctly, but the execute permission ist lost as described in the ant manual:
Unix Note: File permissions are not retained when files are copied; they end up with the default UMASK permissions instead. This
is caused by the lack of any means to query or set file permissions in
the current Java runtimes.
You have to use the cp command or change the permission later with chmod:
<apply executable="chmod">
<arg value="a+rx"/>
<file file="${stub.file}" basedir="${dist.dir}/${ant.project.name}.app/Contents/MacOS"/>
</apply>

How to rename a folder using Ant?

I want to rename my application folder with a time stamp and then unzip a newer version of my app using the same folder name. Using the Ant (move task), it looks like you can move contents from one folder to another.
Is this the only way I can do this in Ant?
The move task does do what you're after, but the naming is a bit confusing. If you consider your directory is a 'file' in the Java sense - a file being a filesystem handle that can represent, among others a directory or a file in the usual sense - then the move task makes sense.
So the following
<move file="mySourceDirName" tofile="myTargetDirName"/>
means rename/move the directorymySourceDirName to be instead myTargetDirName.
The following then
<move file="mySourceDirName" todir="someExistingDir"/>
means to move the directory mySourceDirName to become a child directory of the existing someExistingDir directory.
So, in ant the 'file' attribute refers to the target in question, and the 'todir' attribute refers to the directory that is the new parent location for the target file or directory.
Just spelling out the answer already given, which is correct...
<project default="move">
<tstamp/>
<target name="move">
<move file="foo" tofile="foo-${TSTAMP}"/>
</target>
</project>
This moves foo to foo-HHMM.
For example:
$ find .
.
./build.xml
./foo
./foo/bar.txt
$
$ ant
Buildfile: C:\tmp\ant\build.xml
move:
BUILD SUCCESSFUL
Total time: 0 seconds
$
$ find .
.
./build.xml
./foo-1145
./foo-1145/bar.txt
$
If you want to rename folder, you can use move tag but it there is a cryptic way to use it. As #phasmal said you can use move but it moves the folder inside the desired folder. If you just want to rename, try following.
<move todir="newname">
<fileset dir="directory tobe renamed "/>
</move>
I think the move task is what you want. Is there some reason you don't want to use it?
It sounds like you're proposing moving the folder in which your build.xml file lives. Is that right? If so, I imagine ant might not be too happy it.

Resources