Reputation: 26894
I need to build a custom Ant script that builds a project based on CI output. We use Atlassian Bamboo as CI server.
Normally our projects have a dependency to our platform module, managed via Ivy/Artifactory.
Our typical dependencies.xml
file contains a dependency to that module, transitively. And other potential dependencies. As an example, our core module depends on lots of Spring packages, but not on Spring Boot. If a project needs Spring Boot too, it will define its dependency in its dependencies.xml
file along with <depencency org="com.acme" name="core-platform"...
My goal now is to exclude com.acme#core-platform
from resolution, because I am making a different task that uses Bamboo output artifact to take the latest build of the core module and its dependencies without going through Artifactory.
This is very important because during a build I may like to change the version of a dependent package (e.g. upgrade Spring 4.3.1 to 4.3.3) and test with the proper Spring. If I simply resolve dependencies to com.acme#core-platform#latest.release
, which is released on Artifactory, I won't take 4.3.3 of Spring which was committed to Git and available in core-platform
's currently-building dependencies.xml
.
So let's say I have this dependency list as an example
com.acme#core-platform#${version}
org.hibernate#hibernate-java8#5.1.0.Final
org.springframework.boot#spring-boot-starter-web#1.3.1.RELEASE
commons-collections#commons-collections#3.2.2
.... others
Full dependency is
<dependencies>
<dependency org="com.acme" name="core-platform" rev="${version}" transitive="true" conf="runtime->runtime" changing="true"/>
<dependency org="com.acme" name="core-platform" rev="${version}" transitive="true" conf="compile->compile" changing="true"/>
<dependency org="com.acme" name="core-platform" rev="${version}" transitive="true" conf="provided->provided" changing="true"/>
<dependency org="com.acme" name="core-platform" rev="${version}" transitive="true" conf="junit->junit" changing="true"/>
<dependency org="com.acme" name="core-platform" rev="${version}" transitive="true" conf="test->test" changing="true"/>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-java8 -->
<dependency org="org.hibernate" name="hibernate-java8" rev="5.1.0.Final" transitive="false" />
<dependency org="org.springframework.boot" name="spring-boot-starter-web" rev="1.3.1.RELEASE" transitive="false" />
<dependency org="org.springframework.boot" name="spring-boot-starter-tomcat" rev="1.3.1.RELEASE" transitive="false" />
<dependency org="org.springframework.boot" name="spring-boot-starter-validation" rev="1.3.1.RELEASE" transitive="false" />
<dependency org="commons-collections" name="commons-collections" rev="3.2.2" transitive="false" />
<!-- jackson2 libs -->
<dependency org="com.fasterxml.jackson.datatype" name="jackson-datatype-jdk8" rev="2.8.1" transitive="false" conf="runtime->*"/>
<dependency org="com.fasterxml.jackson.datatype" name="jackson-datatype-jsr310" rev="2.8.1" transitive="false" conf="runtime->*"/>
<exclude module="joda-time" />
<exclude module="jackson-datatype-joda" />
</dependencies>
I simply want to take Hibernates' Java8, commons-collections, etc.
acme
modules by regex. Feasible but trickyivy:retrieve
with attributes file
and element exclude
, because that would have helped a loooooootAny ideas?
Upvotes: 0
Views: 1988
Reputation: 77991
It is hard to understand your requirement. I suspect that your problem could be solved by creating an additional configuration and use configuration mappings to control the downloads.
This build creates two directories. The first contains the log4j dependency without transitive dependencies, the second includes the remote module's optional dependencies. If you look at the remote POM you'll see they have a different scope.
├── build.xml
├── ivy.xml
├── lib1
│ └── log4j-1.2.17.jar
└── lib2
├── activation-1.1.jar
├── geronimo-jms_1.1_spec-1.0.jar
├── log4j-1.2.17.jar
└── mail-1.4.3.jar
<project name="demo" default="resolve" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="resolve">
<ivy:resolve/>
<ivy:retrieve pattern="lib1/[artifact]-[revision](-[classifier]).[ext]" conf="noDependencies"/>
<ivy:retrieve pattern="lib2/[artifact]-[revision](-[classifier]).[ext]" conf="withDependencies"/>
</target>
</project>
Notes:
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="noDependencies" description="File grouping that has no transitive dependencies"/>
<conf name="withDependencies" description="File grouping that contains dependencies"/>
</configurations>
<dependencies>
<dependency org="log4j" name="log4j" rev="1.2.17" conf="noDependencies->master; withDependencies->master,optional"/>
</dependencies>
</ivy-module>
Notes:
The following answer explains how ivy interprets Maven modules. It creates configurations that can be used to decide which files should be downloaded:
Upvotes: 1
Reputation: 26894
Ok, looks like the replace trick is very easy too.
<!-- DEPS START -->
and <!-- DEPS END -->
(or any of choice) between the parts of the dependencies.xml file to ignoreHack via Ant
<copy file="dependencies.xml" tofile="ci/hacked-dependencies.xml" overwrite="true">
<filterchain>
<replacestring from="<!-- DEPS START -->" to="<!--" />
<replacestring from="<!-- DEPS END -->" to="-->" />
</filterchain>
</copy>
Example
<!-- DEPS START -->
<dependency org="com.acme" name="core-platfrom" rev="${version}" transitive="true" conf="runtime->runtime"/>
<!-- DEPS END -->
Upvotes: -1