Hi Allan,

good to hear from you :)

On Aug 9, 2008, at 4:44 AM, Allan Lewis wrote:


Hi,

I have a multi-project build, and at the end, I'd like to to gather up all of the JARs and other artifacts and piece them into a release ZIP file. How do I create a task that will only be called once (from the root project)
after the libs task has created for the rest of my tasks?  I've tried
creating a new task in the top-level Gradle buildfile, but the problem I'm
facing is that the new task is getting called for each suproject.

Here a solution based on a sample multi-project build. You can find this sample build in GRADLE_HOME/samples/javaproject.

You need to replace the build.gradle file of the javaproject with this one:

dependsOnChildren()
project('services').dependsOnChildren() // The services project has no build file. To keep things simple we configure it from here.

project.group = 'org.gradle'
project.version = '1.0'

allprojects {
    usePlugin('java')
    dependencies {
        addMavenRepo()
        testCompile('junit:junit:4.4')
    }
    manifest.mainAttributes(provider: 'gradle')
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
}

createTask('ueberZip') {
        List archiveFiles = []
        subprojects.each { Project project ->
                project.libs.archiveTasks.each { archiveTask ->
                        archiveFiles << archiveTask.archivePath
                }
        }
        archive_zip.files(archiveFiles as File[])
}

dists.zip().dependsOn 'ueberZip'

It is interesting to look on the dependencies of this multi-project build. At configuration time the subprojects depends on the root project. This means the root project build file must be evaluated before the subproject build files. Otherwise evaluating the build file of for example the api subproject would throw an exception, as line 11 (libs.jar(appendix: 'spi')) assumes that the Java plugin has been applied and thus the libs task is available. You don't have to do anything to make Gradle works this way as it the default that the parent project build files get evaluated before the child project build files (but this is customizable behavior).

At execution time we have an opposite situation. We want that the subproject tasks to be executed (to produce there archives) before we execute the root project tasks. In other situations we might need a different behavior. For example the root project is supposed to produce something which is needed by the subprojects. To express our requirements we must declare in the rootproject: dependsOnChildren(). As this is a nested mulit-project build we have to do the same for the services project.

Then we create a zip task for the root-project. We add all the archives from the libs bundles of the subprojects to it. We need to do this of course after the subproject build files have been evaluated (where possibly archive tasks are created). Therefore we do this at execution time in an action.

I hope this makes sense.

The example above does not work with 0.2 although the general approach would be the same. We use the modified Bundle API in 0.3 to do things here. I'm out of office from tonight until next Friday. You can expect the 0.3 release to happen short after I return. As the 0.3 release is almost done, I gonna upload a 0.3-snapshot today with an uptodate user's guide. Of course you might as well use HEAD.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to