Gradle parallel with inter-project artifact dependencies


(Dimitar Dimitrov) #1

I am having a few projects, where one project repackages the distribution of another.

I’ve structured this in a custom plugin as follows:

    def distributions = project.extensions.findByType(DistributionContainer)
    def embed = project.configurations.create("embed")
    
    def configDistribution = distributions.create("config") { Distribution d ->
        d.contents.from {
            embed.resolvedConfiguration.files.collect {
                it.name.endsWith('.tar') ?  project.tarTree(it) : project.zipTree(it)
            }
        }
    }

    Task configDistTar = project.tasks.getByName(configDistribution.name + 'DistTar')
    project.artifacts.add('default', configDistTar)

This gets applied to every project, so any project can aggregate the distribution content of another by referencing it in the embed configuration.

It all works, but if I build org.gradle.parallel=true, the dependency between projects is not respected.

I would have expected that the distribution copy spec would try to resolve the configuration, which references an artifact, built by a task in different project.

Instead, when I do gradle clean ass I get spurious errors such as:

Could not read ‘…\build\distributions…tar’ as it does not exist.


(Stefan Oehme) #2

You are using contents.from with a closure that is completely opaque to Gradle. So it doesn’t know that you are resolving a Configuration in there which would have needed the task dependencies to be run first. You’ll need to manually add the embed configuration as a dependency to the distribution tasks.


(Dimitar Dimitrov) #3

Indeed… do you see any other way to achieve the same result without having to add explicit dependencies?

Also is there an api to get the dist tasks without relying on naming conventions?


(Stefan Oehme) #4

There’s no good alternative I’m afraid. We could probably add a method like transformFiles that people could use instead of Groovy’s collect {}.