ivy cleancache but specific folders - ant

We have some internal jars in a remote repository and do not build them very often.The resolver looks like this: view-snapshots is a local repo and hub-releases is a shared repo.
<chain name="hub-internal-library-chain" returnFirst="true">
<resolver ref="view-snapshots"/>
<resolver ref="hub-releases"/>
</chain>
By default,if a developer publishes anything it goes to view-snapshots cache.We need to keep the flag
return first-"true"
for performance issues.So the issue I want to delete some specific files in cache(local) and repository(local).I am a newbie to ivy,any help will be appreciated.
Thanks
PS: I have already had a look at this question which is similar to mine.But its not solved yet.
http://grokbase.com/t/ant/ivy-user/105d2bxpyy/refreshing-ivy-cache-after-changing-a-published-version

There is no dedicated code in Ivy which delete the entries of only one module in a cache.
But it is quite easy to do with regular Ant tasks. Assuming you have the default cache with the default pattern, here a piece of build.xml which will delete the cache of the module foo of the company com.acme:
<delete dir="${user.home}/.ivy2/cache/com.acme/foo" />

This the solution that works for me :
<target name="clear-entries" if="clean-selected-cache" depends="clear-cache,clear- repository">
<echo>Clearing cache and repository entries for internal libraries</echo>
</target>
<target name="clear-cache">
<delete verbose="true">
<fileset dir="${ivy.view-local.cache.root}">
<includesfile name="path.to.file/clear-cache.includes.txt"/>
</fileset>
</delete>
</target>
<target name="clear-repository">
<delete verbose="true">
<fileset dir="${ivy.view-local.repository.root}">
<includesfile name="path.to.file/clear-cache.includes.txt"/>
</fileset>
</delete>
</target>
You can easily add the specific folder you want to delete from cache and from repository in clear-cache.includes.txt.

Related

Exclude files in ant-migration tool while deploying

I am new to salesforce. We are using ant-migration tool. There are a few classes/dashboards/triggers that we are trying to exclude using file sets. All of the below folders are inside src.
<property file="build.properties"/>
<property name="src.dir" value="../src"/>
<fileset dir="${src.dir}" casesensitive="yes">
<echo message="Inside file set"/>
<exclude name="**/classes/Abs*.cls"/>
</fileset>
<target name="deploy">
<sf:deploy
username="${sf.username}.${org}"
password="${sf.password}${sf.securitytoken}"
serverurl="${sf.serverurl}"
checkOnly="${checkOnly}"
maxPoll="${maxPoll}"
deployRoot="${src.dir}"
allowMissingFiles="${allowMissingFiles}"
ignoreWarnings="${ignoreWarnings}"
testLevel="${testLevel}" />
</target>
It looks like I am unable to exclude the same.
Never used filesets, sorry.
My Ant pulls project's structure from Git to temp directory so in the build.xml we just delete stuff which we know is pain to deploy. We still want these files in the repo for ease of use / repo completeness.
<target name="deploy_target">
...
<delete file="${src.dir}/workflows/Reply.workflow" />
<delete file="${src.dir}/workflows/Question.workflow" />
<delete file="${src.dir}/layouts/SocialPost-Social Post Layout.layout" />
<delete file="${src.dir}/layouts/CommunityMemberLayout-Community Member Layout.layout" />
</target>

Delete a folder using starts with in ANT

I am comparing 2 folders A and B, and wanted to delete folders and jars present in B which are not present in folder A.
I have written the logic to get needed files to delete, but i do not wanted to delete the directory and jars starting with "com.ibm".
For that I have written delete task as below:
<delete>
<dirset dir="D://mypath/plugins<Filename to delete> excludes="**/com.ibm.*/**" />
</delete>
I have tried the excludes with the scenarios like:
excludes="**/com.ibm.*/**"
excludes="**/com.ibm.*"
excludes="com.ibm.*"
excludes="com.ibm.*/**"
But nothing works for me (It is not deleting any folders/files). Any help would be highly appreciated. Thanks !
you should use fileset instead and specify includeemptydirs="true" of delete.
<project default="init" name="My Project">
<target name="init">
<delete verbose="true" includeemptydirs="true">
<fileset dir="/home/guest/Desktop/plugins" defaultexcludes="no">
<exclude name="com.ibm.*"/>
<exclude name="com.ibm.*/**"/>
</fileset>
</delete>
</target>
</project>

ANT: ways to include libraries and license issues

I have been trying to use Ant to compile and ready a project for distribution. I have encountered several problems along the way that I have been finally able to solve but the solution leaves me very unsatisfied. First, let me explain the set-up of the project and its dependencies.
I have a project, lets call it Primary which depends on a couple of libraries such as the fantastic Guava. It also depends on another project of mine, lets call it Secondary. The Secondary project also features some dependencies, for example, JDOM2. I have referenced the Jar I build with Ant in Primary.
Let me give you the interesting bits of the build.xml so you can get a picture of what I am doing:
<project name="Primary" default="all" basedir=".">
<property name='build' location='dist' />
<property name='application.version' value='1.0'/>
<property name='application.name' value='Primary'/>
<property name='distribution' value='${application.name}-${application.version}'/>
<path id='compile.classpath'>
<fileset dir='libs'>
<include name='*.jar'/>
</fileset>
</path>
<target name='compile' description='Compile source files.'>
<javac includeantruntime="false" srcdir="src" destdir="bin">
<classpath refid='compile.classpath'/>
</javac>
<target>
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<jar destfile='${build}/${distribution}.jar'>
<fileset dir="bin"/>
<zipgroupfileset dir="libs" includes="*.jar"/>
</jar>
</target>
The Secodnary project's build.xml is nearly identical except that it features a manifest as it needs to run:
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<jar destfile='${dist}/${distribution}.jar' basedir="${build}" >
<fileset dir="${build}"/>
<zipgroupfileset dir="libs" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="lu.tudor.ssi.kiss.climate.ClimateChange"/>
</manifest>
</jar>
</target>
After I got it working, trying for many hours to not include that dependencies as class files but as Jars, I don't have the time or insight to go back and try to figure out what I did wrong. Furthermore, I believe that including these libraries as class files is bad practice as it could give rise to licensing issues while not packaging them and merely including them in a directory along the build Jar would most probably not (And if it would you could choose not to distribute them yourself).
I think my inability to correctly assemble the class path, I always received NoClassDefFoundError for classes or libraries in the Primary project when launching Second's Jar, is that I am not very experienced with Ant. Would I require to specify a class path for both projects? Specifying the class path as . should have allowed me to simply add all dependencies to the same folder as Secondary's Jar, should it not?
You may use the MANIFEST.MF "Class-Path: " to cross-reference your jars.
If they are all in the same directory this will probably work as follows (using it in both projects!):
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<pathconvert property="manifest.classpath" pathsep=" ">
<path refid="compile.classpath" />
<flattenmapper />
</pathconvert>
<jar destfile='${build}/${distribution}.jar'>
<fileset dir="bin"/>
<manifest>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
</target>
This way you can tell the java runtime environment that your jar needs others to work, expecting them to be in the same directory as the jar you are trying to run.
As a result your primary.jar should have secondary.jar in it's classpath and secondary.jar should have guava.jar in it's classpath.
Another way to create the string may be ants manifestclasspath task (https://ant.apache.org/manual/Tasks/manifestclasspath.html) that can handle subdirectories.
If you are goin to use more and more libraries, you may want to have a closer look at ivy or even maven.

Creating an ear-File with ant

I am new to ant i referred many sites , i need to build.xml for my project which consists
of two modules i have application.xml file which represents corresponding war file
so my question is it sufficient to add the application.xml file
<ear destfile="${dist.dir}/${ant.project.name}.ear" appxml="${conf.dir}/application.xml">
<metainf dir="${build.dir}/META-INF"/>
<fileset dir="${dist.dir}" includes="*.jar,*.war"/>
</ear>
whether this will refer the corresponding war files or i need to compile the whole scenario please let me know. how solve this.
I'm not 100% sure what you're asking.
In order to use the <ear> task, you already need to have compiled the required jars and wars.
If those jars and wars have already been built, you simply refer to them in your <ear> task as you did in your example. The application.xml must already exist before you build your ear. The application.xml doesn't build the jars and wars, you have to do that.
If you haven't already built the wars and jars, you need to do that first. A general outline of a build.xml looks something like this:
<project name="foo" basedir="." default="package">
<!-- Some standard properties you've defined -->
<property name="target.dir" value="${basedir}/target"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<!-- Compile properties that allow overrides -->
<property name="javac.nowarn" value="false"/>
<property name="javac.listfiles" value="false"/>
<property name="javac.srcdir" value="source"/>
<property name="javac.distdir" value="${target.dir}/classes"/>
<target name="clean"
description="cleans everything nice and shiny">
<delete dir="${target.dir}"/>
</target>
<target name="compile"
description="Compiles everything">
<mkdir dir="${javac.distdir}"/>
<javac srcdir="${javac.srcdir}"
destdir="${javac.destdir}"
[...]
[...]/>
</target>
<target name="package.jar"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package.jar2"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname2.jar"
[...]
[...]/>
</target>
<target name="package.war"
depends="compile"
description="Package jarfile">
<war destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package"
depends="package.jar"
description="Make the ear">
<ear destfile="${target.dir}/earfile.ear"
[...]/>
</target>
</project>
Basically, it consists of a bunch of targets and each target does one task. You can have targets depend upon other targets. For example, this particular build.xml will automatically run the package task. The package task depends upon the package.jar task which depends upon the compile task. Thus, the build.xml file will first call compile, then package.jar, then package.
The important thing to remember is that you don't specify the order of the events. You let Ant figure that out, and you let Ant figure out what you need to do. Let's say you've modified a java source file. Ant knows that it has to recompile only that one file. It also knows that it might have to rebuild the jarfile that contains that classfile. And, it then knows it has to rebuild the ear. Most tasks can figure it out on their own, and you don't do a clean for each build. (You notice that the clean target isn't called by package or compile. You have to call it manually).
The only other thing I recommend is that you try to keep your work area clean. Any files you create should be put into the ${target.dir} directory. That way, when you do a clean, you only have to delete that one directory.
I hope this answer your question.

How to use ivy to build a war with out copying jars to a lib directory

My goal is have my ant build script build a war file and include the jars that ivy knows this project depends on. The best code I could come up with at the moment is the following
<mkdir dir="dist/lib"/>
<ivy:retrieve pattern="dist/lib/[artifact].[ext]" sync="true"/>
<war destfile="dist/${ivy.module}.war" basedir="build" includes="**/*.class"
webxml="${war.webxml}">
<fileset dir="${war.web}"/>
<lib dir="dist/lib"/>
</war>
The problem with this code is it copies the jars twice. Once in to my dist/lib directory and again in to the war when it's created. It works but I can't shake the feeling there is a better way.
What I would like to do is something more like the following
<ivy:cachepath pathid="locpathref.classpath"/>
<war destfile="dist/${ivy.module}.war" basedir="build" includes="**/*.class"
webxml="${war.webxml}">
<fileset dir="${war.web}"/>
<lib refid="locpathref.classpath"/>
</war>
The problem is that the lib tag does not take in a refid of any kind. Any ideas or am I stuck with an extra set of file copies?
The problem here is that the lib tag is a custom fileset that targets it's files into the war archive's lib sub directory. It might be possible to write a custom war task but I don't think it's worth the effort.
If want to improve the manner in which ivy manages your war's dependencies might I suggest using configurations?
Create a configuration describing the run-time dependencies:
<ivy-module version="2.0">
<info organisation="apache" module="hello-ivy"/>
<configurations>
<conf name="build" description="Libraries needed to for compilation"/>
<conf name="war" extends="build" description="Libraries that should be included in the war file" />
</configurations>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->*,!sources,!javadoc"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0" conf="build->*,!sources,!javadoc"/>
</dependencies>
</ivy-module>
Afterwards you retrieve them into a dedicated directory (using a pattern) which can be simply included using the war task's lib tag:
<ivy:retrieve pattern="${lib.dir}/[conf]/[artifact].[ext]"/>
<war destfile="${war.file}" webxml="${resources.dir}/web.xml">
<fileset dir="${resources.dir}" excludes="web.xml"/>
<lib dir="${lib.dir}/war"/>
</war>
The advantage of this approach is that you use the ivy conf attribute of each project dependency to ultimately decide if the jar gets included within the war file or not. The build file no longer cares.
In conclusion I understand that the point of your post was concern for multiple copies of your jar files... Using my suggested approach will further multiple your copies, but I would submit that this is not an issue provided you have a clean target to remove them afterwards.
If you're using Ant 1.8, you can use the technique described here:
http://www.beilers.com/2010/06/ivy-dependency-management-lessons-learned-and-ant-1-8-mapped-resources/
EXAMPLE:
<war destfile="${war.full.path}" webxml="WebContent/WEB-INF/web.xml" manifest="${manifest.path}">
<fileset dir="WebContent">
</fileset>
<classes dir="${build.dir}"/>
<mappedresources>
<restrict>
<path refid="classpath.CORE"/>
<type type="file"/>
</restrict>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="WEB-INF/lib/*"/>
</chainedmapper>
</mappedresources>
<zipfileset dir="src" prefix="WEB-INF/classes">
<include name="**/resources/**/*.properties" />
<include name="**/resources/**/*.xml" />
</zipfileset>
</war>

Resources