I am trying to do the following in ANT but I am stuck.
Read which projects are installed in my project workspace.
workspace
buildtools
build.xml
project1
build.xml
project.name = "project1"
IP = "44.55.66.77"
SERVER_NAME = "project1.local"
DOCUMENT_ROOT = "c:\inetpub\project1"
project2
build.xml
project.name = "project2"
IP = "44.55.66.77"
SERVER_NAME = "project2.local"
DOCUMENT_ROOT = "c:\inetpub\project2"
....
Create an Apache virtualhost directive for each project.
<VirtualHost 44.55.66.77>
DocumentRoot "c:\inetpub\project1"
ServerName project1.local
</VirtualHost>
<VirtualHost 44.55.66.77>
DocumentRoot "c:\inetpub\project2"
ServerName project2.local
</VirtualHost>
....
Concatenate the virtualhost directives into an Apache configuration file.
I have spent many hours studying the different tasks that I could use. Concat, loadproperties, fileset, filterreaders, etc.. I get overwhelmed with all the possibilities and my head spins.
Here is my horrible guess at how this might be done:
<concat destfile={$apache.config.file}>
<fileset>
<include name="**/build.xml"/>
<loadproperties resource="fileset.item.project.name???"/>
<filterchain>
<replacetokens>
<token key="IP"
value="${p.IP}"/>
<token key="DOCUMENT_ROOT"
value="${p.DOCUMENT_ROOT}"/>
<token key="SERVER_NAME"
value="${p.SERVER_NAME}"/>
</replacetokens>
</filterchain>
</fileset>
<concat>
Thanks for the help!
I think basically you shouldn't load build.xml files containing properties as standard property files as they are not property files (I mean key=value per line files). You should import them if you need the stuff from them.
I suggest you doing such things with a Groovy snippet.
<!-- this is only a sketch, not a working solution -->
<path id="gr">
<pathelement location="/path/to/groovy-all.jar"/>
</path>
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="gr"/>
<groovy>
def b1 = new XmlParser().parse(new File("project1/build.xml")));
def b2 = new XmlParser().parse(new File("project2/build.xml")));
def f = new File("output.xml");
def ip1 = b2.property.find { it.name == 'IP'}.text();
def ip2 = ..
// get out all the stuff you need from the build.xml files with GPath
f.write("<VirtualHost ${ip1}>");
f.write(" DocumentRoot ${r1}");
f.write(" ServerName ${s1}");
f.write("<VirtualHost>");
</groovy>
Related
How to rename many files and folders with Ant? For files I know I can do it like this; question
How to do the same thing for folders?
For e.g.
Set of folders (Input)
com.google.appengine.eclipse.sdkbundle_1.5.2.r37v201107211953
com.google.gdt.eclipse.designer.doc.user_2.3.2.r37x201107161328
com.google.gdt.eclipse.designer.hosted.2_0.webkit_win32_2.3.2.r37x201107161253
org.eclipse.acceleo.common_3.1.0.v20110607-0602.jar
Output:
com.google.appengine.eclipse.sdkbundle_1.5.2
com.google.gdt.eclipse.designer.doc.user_2.3.2
com.google.gdt.eclipse.designer.hosted.2_0.webkit_win32_2.3.2
org.eclipse.acceleo.common_3.1.0.jar
For complex operations I use the groovy ANT task.
The following example will rename your files and directories, using regular expressions:
<project name="demo" default="rename">
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.0.6/groovy-all-2.0.6.jar"/>
</target>
<target name="rename">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<fileset id="filesToBeRenamed" dir="build"/>
<dirset id="dirsToBeRenamed" dir="build"/>
<groovy>
project.references.filesToBeRenamed.each {
String origName = it
String newName = origName.replaceAll(/_[0-9\.]+[a-z0-9\-]+/, "")
if (origName != newName) {
ant.move(file:origName, tofile:newName, verbose:"true")
}
}
project.references.dirsToBeRenamed.each {
String origName = it
String newName = origName.replaceAll(/_[0-9\.]+[a-z0-9\-]+/, "")
if (origName != newName) {
ant.move(file:origName, tofile:newName, verbose:"true")
}
}
</groovy>
</target>
</project>
NOTES:
The "bootstrap" target only needs to be run once. It will download the groovy jar from Maven central
This will move the directory and all of its sub-directories and files.
<move todir="${toDir}">
<fileset dir="${fromDir}"/>
</move>
Take a look at the Ant-Contrib tasks. One is the <for> task. This will allow you to specify multiple directories, directory patterns, etc. This way, you can loop through the directories and files.
You can copy the files and directories to another location and use the Mapper to map the file names. (<move> task will also work with mappers.)
I recommend you download the Ant-Contrib Jar file to the directory ${basedir}/antlib/ac in your project. Then do this in the beginning of your build file:
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${basedir}/antilb/ac"/>
</classdef>
<taskdef>
This will define the ant-contrib tasks and allow you to use them. If you're using a version control system and check everything in, someone can checkout your project and do a build without having to install Ant-Contrib first.
Suppose I have
/Root
/A
/to_delete
/not_to_delete
/B
/to_delete
/not_to_delete
/C
/to_delete
/not_to_delete
How to delete those folders called "to_delete" in Ant?
Please check this :
http://ant.apache.org/manual/Tasks/delete.html
If you don't want to specify A, B, C you will have to do some nasty trict for recursively searcing all subdirectories. I have done this with a custom java script.
If you can specify A,B,C though you just need something :
<delete includeEmptyDirs="true">
<fileset dir="root" includes="**/to_delete/"/>
</delete>
Please try the below code and it works to remove the dir and sub dirs as well.
<delete includeEmptyDirs="true">
<fileset dir="${dir.to.delete}">
<include name = "**" />
<exclude name = "**/.svn" /> <!-- in case you want to skip .svn folders to avoid SVN conflicts -->
</fileset>
</delete>
I have used the Heat tool to generate a wxs file based on a folder whose contents I want to install. This gives me a large file like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="dir1FC8A0605F7DF8B33E3EECB0A1270FA2" Name="DirectoryName" />
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="ComponentGroupId">
<Component Id="cmp1FB67A60B41F3170889B7E5739A23560" Directory="dir1FC8A0605F7DF8B33E3EECB0A1270FA2" Guid="{2DC3B790-D29C-4090-B4CF-5C27687C6ABE}">
<File Id="filF1E1262E52254B1846C7CB2393126A6F" KeyPath="yes" Source="PathToFile" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
In my main Wix file, Product.wxs, I have a feature that references the above ComponentGroup that was created by Heat. The feature looks something like this:
<Feature Id="FeatureId" Title="FeatureTitle" Level="1" AllowAdvertise="no" Absent="disallow" Description="Feature description.">
<ComponentGroupRef Id="ComponentGroupId" />
</Feature>
This is working but when I run my installer, the files within the component group are placed in the root of the C drive (i.e. C:\DirectoryName) but I would like them to go into Program Files (e.g. C:\Program Files\DirectoryName).
Any ideas?
Thanks,
Alan
You can pass the Id of the directory you want to reference to heat with the -dr argument like
heat -dr AutogeneratedComponentsDir
Or DirectoryRefId attribute if you are using the HeatDirectory task in msbuild.
Then just define the location of that directory in your main Product.wxs.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="YourProduct">
<Directory Id="AutogeneratedComponentsDir"/>
</Directory>
</Directory>
</Directory>
I need an Apache Ant target that deletes all files in a directory but does not touch subdirectories.
In my current approach I have to explicitly name the subdirectories I want to skip (atm just "src/").
<delete>
<fileset dir="${dist.dir}" excludes="src/" />
</delete>
But I don't like it. That way I would have to modify the target everytime something changes in the subdirectory structure.
Any ideas?
This should work:
<delete>
<fileset dir="${dist.dir}">
<include name="*"/>
</fileset>
</delete>
The * wildcard should only delete the files at the top level, not directories or subdirectories. If you wanted it to be recursive, you'd need to use **/* instead.
I've inherited an Ant build system that contains many resource
set definitions like this:
<files id="app1.lib.jars">
<include name="${java}/jre/lib/jsse.jar"/>
<include name="${work.lib}/jtidy.jar"/>
...
</files>
<files id="app2.lib.jars">
<include name="${work.lib}/itext.jar"/>
<include name="${work.lib}/commons-httpclient.jar"/>
...
</files>
<files id="app3.lib.jars">
<include name="${work.lib}/jdom.jar"/>
<include name="${ant.lib}/ant.jar"/>
...
</files>
There are perhaps a dozen of these, and each can contain anywhere from
5 to 50 files. The problem is that I'm reworking this system to use
Ivy for dependency management, and in the process some of the
references now point to non-existent files. Unfortunately, Ant does
not provide any help finding these bad pointers. When these resource
collections are used to define a classpath any <include...> tags
pointing to missing files are silently ignored.
I thought I could force an error by using the collections as the
source of a <copy...>, but even with failonerror="true" it just
ignored the bad references.
The command-line -v (verbose) and -d (debug) option didn't help
either. The output acknowledged that some were missing but didn't
actually show them
[echo] app1.lib.jars
[copy] C:\dev\src\tomcat6\work\java\jre\lib\jsse.jar omitted as C:\dev\src\tomcat6\work\verify\jsse.jar is up to date.
[copy] C:\dev\src\tomcat6\work\lib\axis-ant.jar omitted as C:\dev\src\tomcat6\work\verify\axis-ant.jar is up to date.
...
[copy] No sources found.
[echo] app2.lib.jars
...
For a one-time solution I extracted all the filenames from the
resource sets in the Ant file and compared that to a directory listing
of the result of copying all the files (in Ant) into a temporary
directory, after appropriate sorting.
Question: Is there a way to get Ant to tell me when a resource points
to a missing file, preferably at the time the resource is defined?
Here's an illustration of one method. Key points
Convert your files to filelists - these can contain names of files that don't exist in the file system, unlike filesets and files, that ignore entries that don't exist
Use a restrict to check for existence
Use a fail to error when something is missing
You'll need to add the "antlib:org.apache.tools.ant.types.resources.selectors" namespace to the project to use the resource selectors shown below. You'll hit snags with Ant versions older than 1.7.0.
<project name="so" default="checkfiles" basedir="."
xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
<filelist id="app1.lib.jars">
<file name="${java}/jre/lib/jsse.jar"/>
<file name="${work.lib}/jtidy.jar"/>
...
</filelist>
<restrict id="missing.app1.lib.jars">
<filelist refid="app1.lib.jars"/>
<rsel:not>
<rsel:exists/>
</rsel:not>
</restrict>
<property name="missing.files" refid="missing.app1.lib.jars" />
<fail message="These files are missing: ${missing.files}">
<condition>
<length string="${missing.files}" when="greater" length="0" />
</condition>
</fail>
<pathconvert property="found.files" refid="app1.lib.jars" />
<echo message="Found files ${found.files}" />
Alternatively, you could use the 'copy' task, as you suggest, but with filelists instead of files.
The copy should fail when it tries to process the first resource that doesn't exist.