tar zcvf Test.tar.gz /var/trac/test /var/svn/test
So far I have:
<target name="archive" depends="init">
<tar compression="gzip" destfile="test.tar.gz">
<tarfileset dir="/">
<include name="/var/trac/test" />
</tarfileset>
<tarfileset dir="/">
<include name="/var/trac/svn" />
</tarfileset>
</tar>
</target>
With debugging on, it always says "No sources found" so I'm a bit perplexed on what to do next.
There are several things here that can go wrong:
Are /var/trac/test and /var/svn/test files or directories? Real tar would work fine with both; your task - the way it's written right now - would only work with files but not folders.
Do you (or, rather, does Ant process) have adequate permissions?
<include> elements contain patterns, which are generally relative to base dir. You're specifying them as absolute.
I would rewrite the above as:
<target name="archive" depends="init">
<tar compression="gzip" destfile="test.tar.gz">
<tarfileset dir="/var/trac" prefix="/var/trac">
<include name="test/**" />
<include name="svn/**" />
</tarfileset>
</tar>
</target>
prefix allows you to explicitly specify the path with which files in Tar archive should begin.
/** within <include> tells Ant to take all the files from that folder and all its subfolders. If /var/trac/test and /var/svn/test are indeed files and not folders then you can omit that.
Related
I have the following ant targets defined. The idea is to do the heavy work only, if some contents of a folder have changed.
<target name="checksumAssets">
<echo message="verify checksums" />
<checksum todir="${bin.loc}/../checksums" verifyproperty="checksum.isUpToDate.test">
<fileset dir="${bin.loc}/assets/" id="filelist">
<include name="somefolder/" />
<exclude name="somefolder/result.swf"/>
</fileset>
</checksum>
<echo message="${toString:filelist}"/>
<echoproperties regex="checksum.isUpToDate.test"/>
</target>
<target name="createAsset" depends="checksumAssets" unless="${checksum.isUpToDate.test}">
<!-- do create the assets and other magic -->
<echo message="create checksum files" />
<checksum todir="${bin.loc}/../checksums" >
<fileset refid="filelist" />
</checksum>
</target>
somefolder contains images which will be processed and result in a swf file containing these assets.
i want this heavy processing only to take place if something in the asset folder changes.
this works as espected in two cases:
i add a new file to somefolder
i change an existing file in somefolder
my problem is:
it does not work when i delete a file from this folder.
this means, the createAsset Target is not called on ant createAsset if i remove a file from the folder in question. it is called in the two aforementioned cases and if there are no checksum files present in the checksums folder.
is there something i missed?
ant version is 1.8.2
i've found a workaround.
since <checksum> only saves the checksum of single files, it cannot know if a file is missing from a previous run. for this it would need to save the checksum of a complete filelist on disk.
this is what i accomplished:
<target name="checksumAssets">
<echo message="verify checksums" />
<!-- generate filelist.txt with actual content of somefolder -->
<fileset dir="${bin.loc}/assets/somefolder/" id="filelist">
<exclude name="result.swf"/>
<exclude name="filelist.txt"/>
</fileset>
<concat destfile="${bin.loc}/assets/somefolder/filelist.txt" fixlastline="true">${toString:filelist}</concat>
<!-- checksum folder including the filelist.txt -->
<checksum todir="${bin.loc}/../checksums" verifyproperty="checksum.isUpToDate.test">
<fileset dir="${bin.loc}/assets/" id="checkedlist">
<include name="somefolder/" />
<exclude name="somefolder/result.swf"/>
</fileset>
</checksum>
</target>
<target name="createAsset" depends="checksumAssets" unless="${checksum.isUpToDate.test}">
<!-- do create the assets and other magic -->
<echo message="create checksum files" />
<checksum todir="${bin.loc}/../checksums" >
<fileset refid="checkedlist" />
</checksum>
</target>
first i generate a filelist.txt with the content of the current folder.
then i generate checksums of all files in this folder, including the filelist.txt
on every an run, filelist.txt will be generated and checked against the filelist.txt from the last successful run of createAsset.
now the createAsset target is run if a content file changes or if the content of this folder changes.
mission accomplished ;)
I have a zip file and, separately, a directory that contains some files. From the zip file I'd like to extract only those files that exist in the directory (performing a filename transformation on the files as they are being extracted..basically, I'm making backups of those files).
There is no problem doing something similar with a <copy> that has a fileset with a <present> element, but it doesn't seem to be working for me with unzip:
<unzip src="${cur.srcdir.live}" dest="${cur.srcdir.archive-files.dir}" overwrite="true">
<fileset dir=".">
<present present="both" targetdir="${cur.srcdir}" />
<type type="file" />
</fileset>
<globmapper from="*" to="*.${backup.suffix}" />
</unzip>
Has anyone done something like this before? This is Ant 1.8.0. Thanks!
I was able to solve my problem by "faking" the <present> selector that can be used in <copy>. Here's how:
First I used pathconvert to create a list of the files in my folder:
<pathconvert property="extract.list" pathsep="
">
<path>
<fileset dir="${extract.src.dir}" includes="${extract.src.dir.relpath}">
<type type="file" />
</fileset>
</path>
<map from="${extract.src.dir}\" to="" />
</pathconvert>
Notice the user of a map to have the list be relative paths instead of absolute paths. Plus, the delimiter is a newline.
Then this list gets written to a file:
<echo file="${props.tmp.file}" message="~~~~noop~~~~
${extract.list}" append="false" />
I put that "nooop" entry in there so that the file always has at least one line. This is important because of our next step where we use this as an includesfile. If the includesfile is empty, Ant interprets that as "allow anything"...but we want to make sure that an empty list results in nothing getting extracted from the zip.
Last step is to extract from the zip using our temp file from above as an includes file. The globmapper renames the files upon extraction, to the appropriate backup names:
<unzip src="${extract.archive}" dest="${extract.dest.dir}" overwrite="true">
<patternset>
<includesfile name="${props.tmp.file}" />
</patternset>
<globmapper from="*" to="*.${backup.suffix}" />
</unzip>
Adding this here in case someone needs to change the directory structure on extraction. I've spent so much trying to make this working. Ant Unzip task accepts cutdirsmapper.
<unzip dest="${build.dir}/packages">
<fileset dir="${src.dir}/packages" includes="*.pkg" />
<!-- Exctract build folder contents also moving one level up. -->
<cutdirsmapper dirs="1" />
<patternset>
<include name="build/" />
</patternset>
</unzip>
You can try calling unzip command via exec task.
The sample that I checked on Windows that refresh only changed files in dest.folder:
<property name="zip.file_name" value="Archive.zip"/>
<property name="src.folder" value="d:\"/>
<property name="dest.folder" value="d:\55"/>
<target name="unzip">
<echo>unzip -fo ${src.folder}${zip.file_name}</echo>
<exec dir="${dest.folder}" executable="cmd.exe" output="${src.folder}operation_result.txt">
<arg line="/c unzip -fo ${src.folder}${zip.file_name}"/>
</exec>
</target>
If you want to stay your original files you can use this command:
<arg line="/c unzip -foB ${src.folder}${zip.file_name}"/>
In case using -B parameter your original files (stored in folder) will be renamed - the tilde symbol will be appended. You get two sets of files - extracted from archive and old original files.
After that you can rename files with the help of move task.
I have a zip file which has one base folder inside it with other content inside that. I don't always know what that base folder is going to be called until I unzip it.
I'd like to move that base folder, and rename it at the same time, in ant - but can't seem to find out how. I've written code to extract the contents of the zip file to ${local.sdk.dir}/temp/ but from here i can't work out how to rename/move the extracted folder
<move todir="${local.sdk.dir}/${remote.sdk.file.name}">
<fileset dir="${local.sdk.dir}/temp/<WHAT_DO_I_PUT_HERE?>"></fileset>
</move>
also tried
<move todir="${local.sdk.dir}/${remote.sdk.file.name}" includeEmptyDirs="yes" verbose="true">
<fileset dir="${local.sdk.dir}/temp/" >
<include name="**/*" />
</fileset>
</move>
and played about with this, but closest I can get without ant throwing an error is to copy the contents of the temp dir, not the base folder within temp.
You can do all this in one step - copy from the zip file and rename the files changing the dir name as you copy. The copy task accepts a nested resource collection, so you can use a zipfileset to specify the files to copy directly from the zip file.
In order to rename the files as they are copied, you can use a mapper, which the copy task also takes as a nested element. In this case, a cutsdirmapper looks like the tool for the job.
So, if I've understood what you want to do correctly, something like this should work:
<copy todir="${local.sdk.dir}/${remote.sdk.file.name}">
<zipfileset src="${your.zip.file}" />
<cutdirsmapper dirs="1" />
</copy>
cutdirsmapper is only available in Ant 1.8.2 onward, so if you're using an earlier version, you could try a regexpmapper:
<regexpmapper from="[^/]*(.*)" to="\1" />
Similar to this question
<target name="relocate_sdk_folder">
<path id="sdk_folder_name">
<dirset dir="${local.sdk.dir}/temp/">
<include name="*"/>
</dirset>
</path>
<property name="sdk_folder_name" refid="sdk_folder_name" />
<echo message="renaming ${sdk_folder_name} to ${remote.sdk.file.name}" />
<move file="${sdk_folder_name}" tofile="${local.sdk.dir}/${remote.sdk.file.name}" />
</target>
I am still very new to ant and, although I know coldfusion, I don't know very much about java conventions, but I know that ant is built using java conventions. That being said I am working on an ant process to copy a project to a temp folder, change some code in the project, and then push the temp directory up to an FTP. I am trying to exclude all of my git, eclipse, and ant files from the copy so that my testing platform doesn't get cluttered. I setup a target to do the copy, but it seems that Ant not only is ignoring my excludes (which I am sure I wrote wrong), but it is only copying top level directories and files. No recursive copy. My current target is:
<target name="moveToTemp" depends="init">
<delete dir="./.ant/temp" />
<mkdir dir="./.ant/temp" />
<copy todir="./.ant/temp">
<fileset dir=".">
<include name="*" />
<exclude name=".*/**" />
<exclude name=".*" />
<exclude name="build.xml" />
<exclude name="settings.xml" />
<exclude name="WEB-INF/**" />
</fileset>
<filterset>
<filter token="set(environment='design')" value="set(environment='testing')" />
</filterset>
</copy>
</target>
I know that I am not doing my excludes right, but I don't know what I am doing wrong with them. I see double asterisks (**) used all the time in Ant but I can't figure out
By default an Ant fileset will (recursively) include all files under the specified directory, equivalent to:
<include name="**/*" />
That's the implicit include. If you supply an include, it overrides the implicit one.
Your include
<include name="*" />
Says 'match any file in the fileset directory', but that excludes traversal of subdirectories, hence your issue. Only files and the top-level directories are being copied.
See Patterns in the Ant docs for directory-based tasks: ** matches any directory tree (zero or more directories).
For your case you should be able to simply remove the 'include', so that the implicit 'include all' applies.
Suggest you also investigate the defaultexcludes task, which lets you set up this sort of thing once for the whole project.
Responding to the title of the question. You can include copy of empty directories as follows. (includeemptydirs attribute)
Example:
<copy includeemptydirs="true" todir="${directory}${file.separator}sentinel_files">
<fileset dir="${basedir}${file.separator}sentinel_files"/>
</copy>
Use the documentation provided in:
https://ant.apache.org/manual/Tasks/copy.html
Does anyone know how to recursively delete "empty" directories with ANT (empty includes directories that only contain ".svn" etc).
I know ant allows you to "includeEmptyDirs=true" but I want it to ONLY delete a directory if it is empty (and actually I'd probably need to walk up the recursive chain and delete the directory it was contained in if it is now empty).
Basically as part of our build process we copy over a set of directories that contain a bunch of other nested directories containing various XML and data, and when we move the location for that data our "copy" and checkin build process doesn't really work, and because we are checking into another source control (SVN), wiping out the directories and copying over isn't really an option either (we'd be blowing away the ".svn" folders).
Before we copy over the new builds I can "clear" out the directories by doing the following:
<delete>
<fileset dir="${webplatformBin}" includes="**/*"/>
</delete>
This leaves every directory (with the ".svn") as an empty directory and then I copy over the new files. After they're copied I'm not sure how I can clear out the empty directories that are left (if we've completely moved where the top-level data directory is etc.).
For example if I had a /projectA/data/localization/text.xml file and I moved it to /projectB/data/localization/text.xml, I would end up with an empty folder /projectA/data/localization/ (that would only contain a .svn folder).
Here's the best answer I've been able to come up with:
<delete includeemptydirs="true">
<fileset dir="${dirToStartFrom}" >
<and>
<size value="0"/>
<type type="dir"/>
</and>
</fileset>
</delete>
I then wrapped it in a macro so I can pass the dir name in from any target:
<!-- Find and delete empty folders under dir -->
<macrodef name="deleteEmptyFolders">
<attribute name="dir"/>
<sequential>
<delete includeemptydirs="true">
<fileset dir="#{dir}" >
<and>
<size value="0"/>
<type type="dir"/>
</and>
</fileset>
</delete>
</sequential>
</macrodef>
Like so:
<target name="clean">
<deleteEmptyFolders dir="build"/>
<deleteEmptyFolders dir="common"/>
<deleteEmptyFolders dir="lib"/>
</target>
Here's what I cooked up:
<!-- next three targets are connected
To remove empty folders from XXX folder. Process is recursed 3 times. This
is necessary because parent directories are not removed until all their children
are (if they are empty), and parents are processed before children
My example will process structures 3 deep, if you need to go deeper
then add members to the list like list="1,2,3,x,x,x,x,x,x" -->
<target name="rmmtdirs">
<foreach list="1,2,3" target="rmmtdirs_recurse" param="num"/>
</target>
<target name="rmmtdirs_recurse">
<foreach target="rmmtdir" param="rmdir">
<path>
<dirset dir="${XXX}"/>
</path>
</foreach>
</target>
<target name="rmmtdir">
<echo message=" Removing: ${rmdir} "/>
<delete includeemptydirs="true">
<fileset dir="${rmdir}" excludes="**/*"/>
</delete>
</target>
I was able to delete all the empty directories starting with the current working directory with the following:
<delete includeemptydirs="true">
<fileset dir="." includes="**" excludes="**/*.*" />
</delete>
If it is not sufficient to completely clear the target location (use defaultExcludes="false" to ensure the .svn folders are deleted), you could try writing a custom ant task to traverse the file system below the target, deleting empty directories as you move back up from each leaf.
This is probably easier to do with a batch file that gets called from ant.
You can use Raymond Chen's script, but it doesn't work if there are spaces in the names.