We have an ant build process that currently build our war file. A subset of non compiled files (html) in the war have the need for token replacement however I don't want to do that on disk (we don't want to save the changes). Is there any way to perform the token replacement as the war is being built.
Current war process
<war basedir="${company.webapps.dir}" destfile="${dist.dir}/${company.war.filename}"
webxml="${company.webapps.dir}/WEB-INF/web.xml" update="true">
<exclude name="WEB-INF/**" />
<exclude name="**/*.coffee" />
<exclude name="**/*.haml" />
<exclude name="**/*.sass" />
<exclude name="**/*.scss" />
<webinf dir="${company.webapps.dir}/WEB-INF/">
<include name="**/*" />
<exclude name="**/servlet-api.jar" />
</webinf>
<manifest>
<attribute name="build-timestamp" value="${build.info.timestamp}" />
</manifest>
</war>
If it didn't add a large amount of time I'd be ok with this being a post WAR task
I'm confused by your statement "I don't want to do that on the disk. (We don't want to save the changes.)". Can you elaborate on that. You can use the <copy/> task with <filterset> and that will allow you to process your HTML files and replace whatever tokens you want to replace in them.
Then you can use the copied versions of the files that have the replaced tokens in your war. I tried using <filterset> in the war itself, but it doesn't work with <fileset> or <classes>. You have to use <copy> to use <filterset>, and that's how I've always done it.
What do you mean save the changes? You don't have to save the copied files, they're work files just like everything else.
<copy dir="${html.dir}"
todir="${html.work.dir}">
<filterset>
<filter token="${token1}" value="${value1}"/>
<filter token="${token2}" value="${value2}"/>
<filterset>
</copy>
<war destfile="${war.file}"
webxml="${web.xml.file}">
<classes dir="${html.work.dir}"/> <!-- The munged HTML files -->
Related
I have an ant task to concatenate javascript files in a directory and output to concat.js What I want to do is first check if any files have a later modified time than that of concact.js before proceeding.
Here is the existing task:
<target name="minijs" depends="lintjs">
<echo>Concatinating ${plugins.dir} to ${plugins.concat}</echo>
<concat destfile="${plugins.concat}">
<fileset dir="${plugins.dir}">
<exclude name="**/vendor/**" />
<exclude name="*beconcat*" />
<include name="**/*.js" />
</fileset>
</concat>
This is what the uptodate task has been created for
<uptodate property="isUpToDate"
targetfile="${plugins.concat}">
<srcfiles dir="${plugins.dir}">
<exclude name="**/vendor/**" />
<exclude name="*beconcat*" />
<include name="**/*.js" />
</srcfiles>
will set the property isUpToDate if none of the files is newer than the target file - and not set the property at all if one of the files is. You can then use unless to conditionally rebuild the file.
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 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
Is there a way to call the Ant replace task on files in an FTP? I have a project with some static IDs in the code that change depending on whether I am on development platform or production. I setup my and build.xml file to copy all my files to FTP, but I need to change those static IDs either on the way to the FTP or when they hit it.
Ant doesnot have inbulit replace task.
I achieved it by calling "del" first and than used "put", as below.
<ftp action="del" server="%ftpservername%" userid="%ftpserver_user%" password="%ftpserver_pwd%">
<fileset>
<include name="%file1%.db" />
<include name="%file2%.db" />
</fileset>
</ftp>
<ftp action="put" retriesAllowed="-1" remotedir="%dest_dir%" server="%ftpservername%" port="%ftpport%" userid="%ftpserver_user%" password="%ftpserver_pwd%" binary="yes">
<fileset dir="%src_dir%">
<include name="%file1%.db" />
<include name="%file2%.db" />
</fileset>
</ftp>
we can also do for directory which is in ant.apache.org
If you are looking to do replace within the ant ftp task, it looks like this is not supported. But you could do a replace followed by ftp.
<replace dir="${ftp.src} token="###" value="replaced"/>
<ftp server="server" userid="user" password="password">
<fileset dir="${ftp.src}"/>
</ftp>
Or perhaps you are looking for something different.
I would like to unjar multiple JAR files and then rebuild into one JAR using an ant build script. Is this possible?
Yes, it's possible with ant. A jar file is basically a zip with a special manifest file. So to unjar, we need to unzip the jars. Ant includes an unzip task.
To unzip/unjar all the jar files in your project:
<target name="unjar_dependencies" depends="clean">
<unzip dest="${build.dir}">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</unzip>
</target>
Obviously you need to declare ${build.dir} and ${lib.dir} first. The line <include name="**/*.jar" /> tells ant to include all files that end up with the jar extension, you can tweak that include to suit your needs.
To pack everything into a jar, you use the jar task:
<target name="make_jar" depends="compile, unjar_dependencies">
<jar basedir="${build.dir}"
destfile="${dist.dir}/${project_name}.jar">
<manifest>
<attribute name="Main-Class" value="${mainclass}" />
</manifest>
<fileset dir="${build.dir}">
<include name="**/*.class" />
</fileset>
<fileset dir="${src.dir}">
<include name="applicationContext.xml" />
<include name="log4j.properties" />
</fileset>
</jar>
</target>
In this example, we include different filesets. In one fileset we are including all compiled classes. In another fileset we include two config files that this particular project depends upon.
Yes it is !
You have two possibilities :
Espen answer :
One possible solution that creates one
jar file from all the jar files in a
given directory:
<target name="dependencies.jar">
<jar destfile="WebContent/dependencies.jar">
<zipgroupfileset dir="lib/default/" includes="*.jar"
excludes="*.properties" />
</jar>
</target>
This is useful if you don't need to exclude content that are in some jars (like for example some properties configuration file that might override yours, etc). Here the excludes properties is filtering out files from the dir property.
Use zipfileset
The other solution is to use the zipfileset tag where the excludes property this time will filter out content from the jar to be merged.
<jar destfile="your_final_jar.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="main.class"/>
<attribute name="Class-Path" value="."/>
</manifest>
<zipfileset
excludes="META-INF/*.SF"
src="/path/to/first/jar/to/include.jar"/>
</jar>
Of course you can combine the two tags (zipfileset and zipgroupfileset) inside the same jar tag to get the best of the two.
Yes, it's possible.
One possible solution that creates one jar file from all the jar files in a given directory:
<target name="dependencies.jar">
<jar destfile="WebContent/dependencies.jar">
<zipgroupfileset dir="lib/default/" includes="*.jar"
excludes="*.properties" />
</jar>
</target>
There is also a project devoted to repackage jars called JarJar. You can use it to repackage mutiple Jars into one. Depending on your requirements, you can even rename classes to prevent version conflicts.
From their getting started page:
In this example we include classes from jaxen.jar and add a rule that changes any class name starting with "org.jaxen" to start with "org.example.jaxen" instead (in our imaginary world we control the example.org domain):
<target name="jar" depends="compile">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="lib/jarjar.jar"/>
<jarjar jarfile="dist/example.jar">
<fileset dir="build/main"/>
<zipfileset src="lib/jaxen.jar"/>
<rule pattern="org.jaxen.**" result="org.example.#1"/>
</jarjar>
</target>