Ivy - output the results of a resolve to an ivy file
Asked Answered
D

3

7

Having resolved my ivy.xml file, I'd like to create a new resolved-ivy.xml file consisting of all of the transitive dependencies found in the resolve. Is it possible to do this?

This is different to a deliver, which (I believe) only writes out the immediate dependencies from your ivy.xml, not the transitive dependencies. The deliver Ant task does have a delivertarget attribute, which looks in the documentation like it should do this. In practice it works only for modules in the same organisation (so not generally for all dependencies) and generates a file per module.

It's also different from the ivy-report XML file that is generated during the resolve, but not hugely different. If what I'm trying is not possible then I'll just hack at this file directly, I suppose.

The context here is trying to enable repeatable reproducible builds, including in the presence of changes (new libraries, versions) to the repository. There are posts around the interwebs that try to do this, and none I've found can do it properly.

  • Additions to the Ivy repository can change resolve results, in particular if any dependencies anywhere in the repository (not just your project) have range dependencies. Example: A depends on B;[2.0,4.0] and B;3.1 is later added to the repository.
  • Idea is to resolve as normal, write the resolve as a flattened Ivy file, save that in your project's VCS for that tag (or whatever) and subsequently resolve against that file with transitive="false". Assuming that existing items in the repository do not change, this allows repeatable builds.
  • If anyone has any better ideas for doing this, I'm all ears. At the moment I'm expecting to have to hack some combination of the ResolveEngine to make the ResolveReport available, then add a custom DeliverEngine to use it.
Dorcus answered 4/5, 2012 at 7:36 Comment(0)
K
1

The feature you are looking for was added in Ivy 2.4: fixdeps. It reads an ivy.xml file, which in this case serves as an specification, and output an equivalent file, e.g. ivy-resolved.xml, with all transitive dependencies resolved.

Katzen answered 16/7, 2018 at 15:23 Comment(1)
Well it was two years late for when I needed it, but it's nice to see this feature now exists properly.Dorcus
E
3

artifactreport> might help.

Use the deliver task to create an ivy.xml with the dynamic version constraints replaced by the static version constraint (i.e [2.0,3.0[ becomes 2.2.1):

<ivy:deliver conf="*(public)" deliverpattern="${dist.dir}/ivy.xml"/>

Then use the resolve task on that file to prepare for artifactreport.

<ivy:resolve file="${dist.dir}/ivy.xml"
             conf="*(public)"
             refresh="true"
             type="ivy" />

Finally, artifactreport will do the transient dependency resolution.

<ivy:artifactreport tofile="${dist.dir}/artifactreport.xml" />

artifactreport.xml will look like

<modules>
<module organisation="com.googlecode.flyway" name="flyway" rev="1.7" status="release"/>
<module organisation="org.postgresql" name="postgresql-jdbc" rev="9.0" status="release"/>
<module organisation="org.hibernate" name="hibernate" rev="3.3.2" status="release"/>
<module organisation="org.apache.commons" name="commons-daemon" rev="1.0.2" status="release"/>
...

Use XSLT to produce the ivy.xml form.

Environmentalist answered 16/11, 2012 at 17:31 Comment(0)
P
1

Under normal circumstances I would say this is over-kill. The problem you're trying to work-around is that your repository is unreliable..... Perhaps you should consider using a repository manager to manage your repository?

(Artifacts published to Maven Central are deliberately never changed, this ensures that people using the repository do not encounter build instability).

Having said all this, if you can't completely trust the repository module configuration then what you're attempting to do is possible using the ivy artifactreport task. It generates an XML report, which can be transformed, using XSLT into an new ivy file.

Example

$ tree
.
|-- build.xml
|-- ivy.xml
`-- src
    `-- main
        `-- xsl
            `-- artifactreport.xsl

build.xml

<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">

    <target name="init">
        <ivy:resolve/>
    </target>

    <target name="build" depends="init">
        <ivy:artifactreport tofile="build/reports/artifacts.xml"/>

        <xslt style="src/main/xsl/artifactreport.xsl" in="build/reports/artifacts.xml" out="build/ivy.xml"/>
    </target>

</project>

artifactreport.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <ivy-module version="2.0">
            <info organisation="com.myspotontheweb" module="demo"/>

            <dependencies>
                <xsl:apply-templates select="modules/module"/>
            </dependencies>

        </ivy-module>
    </xsl:template>

    <xsl:template match="module">
        <dependency org="{@organisation}" name="{@name}" rev="{@rev}"/>
    </xsl:template>

</xsl:stylesheet>
Pearce answered 5/5, 2012 at 0:29 Comment(2)
I'm not talking about changing artefacts, which we prohibit for exactly this reason. I'm talking about additions to the repository which affect version resolution. Suppose one of my dependencies depends on CoolLib [10.0, 12.0), and a maintenance version 11.1 is added to the repository. I don't want my build (which may be a fixed tagged release) to change when this happens, even though clearly the new version satisfies my constraints. artifactreport may work for this; I was really hoping not to have to munge Ivy files manually.Dorcus
Ahhh, now I understand. I don't use revision ranges for this reason. Occasionally, I'll use dynamic revisions like "latest.release", combined with an ivy deliver task to resolve the actual revision of the published ivy file.Landing
K
1

The feature you are looking for was added in Ivy 2.4: fixdeps. It reads an ivy.xml file, which in this case serves as an specification, and output an equivalent file, e.g. ivy-resolved.xml, with all transitive dependencies resolved.

Katzen answered 16/7, 2018 at 15:23 Comment(1)
Well it was two years late for when I needed it, but it's nice to see this feature now exists properly.Dorcus

© 2022 - 2024 — McMap. All rights reserved.