views:

125

answers:

1

Hey folks,

I'm using ant+ivy+nexus to build and publish my java OSGi projects (just good old jars if you're unfamiliar with OSGi). After the usual mind-melting period one has when engaging with new tech I've got a mostly functional system. But, I now have two dimensions of artifact variation: snapshot/release and main/test.

The main/test dimension speaks for itself really. The snapshot/release is essential for publishing into nexus in a maven-friendly way. (Extremely useful for integration with open-source OSGi runtimes). So, I have the following artifacts on a per-project basis, and I have many many projects:

  • project-revision.xml (bp)
  • project-test-revision.xml (b)
  • project-revision-SNAPSHOT.xml (bp)
  • project-test-revision-SNAPSHOT.xml (b)

b = successfully building p = successfully publishing (I haven't yet got the test stuff publishing correctly)

It's taken me a while to get that far without duplicating code everywhere in my build scripts, but I've managed it... with one big caveat. For the SNAPSHOT branch I append "-SNAPSHOT" to all revisions. In ant I manage to achieve this programatically, but for ivy I'm using a duplicated ivy.xml; ivy-SNAPSHOT.xml. This has

<info ... revision="x.x-SNAPSHOT">

Notice the -SNAPSHOT. Without this I could never get my

<ivy:deliver>
<ivy:resolve>
<ivy:publish>

chain of commands to correctly publish artifact and maven pom. (Remember I have a requirement to make this maven friendly... I'll be damned if I actually end up using maven to build it mind!)

Now I'm stuck introducing the test/main dimension. I'm ideally looking to publish

project-test-revision(-SNAPSHOT).jar

(Note the optional snapshot). I really don't want to do this by specifying

<info ... module="project-test" ... >

as opposed to <info ... module="project" ... > in yet another ivy file. If I went this route (like I've already started) then I simply end up with loads of ivy-Option1-Option2...-OptionN.xml files. With each new two-value variation doubling the number of build and ivy files. That's crap. There's got to be a better way. I just can't find it.

If you have managed to successfully get ivy publishing artifacts with embellished names from one ivy file, would you mind posting the configuration snippets that achieve this? Would be extremely useful. (Don't forget maven won't know about configurations so I need to get the variations into the filename and pom).

Many thanks

Alastair

A: 

Ok, update: I've now got the artifact publishing. I struggled a little while I had the test conf extending the default conf. I'd get a complaint during publishing that the default configuration artifacts weren't present... something I don't care about while only publishing the test case. By making them independent but overlapping I get back fine-grain control of what to publish.

BUT!!!!! There's no viable test pom - that's NOT publishing yet. Well, actually it does publish, but it contains data for the non-test case. So this is still not maven friendly. If anyone has suggestions on this that'd be great.

either way, the code I'm now using, in case it helps you too:

ivy.xml:

<info
    organisation="MY_ORGANISATION"
    module="MY_PROJECT"
    status="integration"
    revision="1.0-SNAPSHOT">
</info>
<configurations>
    <conf name="default" description="Default compilation configuration; main classes only" visibility="public"/>
    <conf name="test" description="Test-inclusive compilation configuration. Don't forget to also add Default compilation configuration where needed. This does not extend default conf" visibility="public"/>
</configurations>
<publications>
    <artifact name="MY_PROJECT type="jar" ext="jar" conf="default"/>  
    <artifact name="MY_PROJECT type="pom" ext="pom" conf="default"/>        
    <artifact name="MY_PROJECT-test" type="jar" ext="jar" conf="test"/>         
    <artifact name="MY_PROJECT-test" type="pom" ext="pom" conf="test"/>         
</publications>  
<dependencies>
    <dependency org="MY_ORGANISATION" name="ANOTHER_PROJECT" rev="1.0-SNAPSHOT" transitive="true" conf="*"/>
    <dependency org="junit" name="junit" rev="[4,)" transitive="true" conf="test->*"/>
</dependencies>

build.xml:

<property name="project.generated.ivy.file" value="SNAPSHOT_OR_RELEASE_IVY_XML_FILE" />
<property name="ivy.publish.status" value="RELEASE_OR_INTEGRATION" />
<property name="project.qualifier" value="-SNAPSHOT_OR_EMPTY" />
<property name="ivy.configuration" value="DEFAULT_OR_TEST" />

<target name="publish" depends="init-publish">                  
    <ivy:deliver 
      deliverpattern="${project.generated.ivy.file}" 
      organisation="${project.organisation}" 
      module="${project.artifact}" 
      status="${ivy.publish.status}" 
      revision="${project.revision}${project.qualifier}" 
          pubrevision="${project.revision}${project.qualifier}" 
          conf="${ivy.configuration}"
/>  

<ivy:resolve conf="${ivy.configuration}" />

<ivy:makepom 
    ivyfile="${project.generated.ivy.file}" 
    pomfile="${project.pom.file}"
/>

<ivy:publish 
    resolver="${ivy.omnicache.publisher}" 
    module="${project.artifact}"
    organisation="${project.organisation}"
    revision="${project.revision}${project.qualifier}"
    pubrevision="${project.revision}${project.qualifier}"
    pubdate="now" 
    overwrite="true"  
    publishivy="true" 
    status="${ivy.publish.status}"
    artifactspattern="${project.artifact.dir}/[artifact]-[revision](-[classifier]).[ext]"
    conf="${ivy.configuration}"                 
/>
        </target> 
Uberpuppy