Copy task cannot unzip dependent artifacts

Trying to implement a mechanism for a java script project to specify dependencies for testing. The javascript of each project is archived in a zip, that project can declare dependencies and unzip to execute as necessary.

Consider the project (samples/java/multiproject/api) that produces 3 artifacts: 2 jars and a zip. A second project (someproject) depends on the zip from the latter project. ‘someproject’ needs to unzip dependent artifacts prior to using them.

So using the multiproject sample as a starting point, added a new configuration named ‘testJavaScript’. Created a new project named ‘someproject’ and a task named ‘testJavaScript’ that unzips any dependency declared by the ‘testJavaScript’ configuration. The following warning is displayed when executing the associated task. The task works only if I run the build (or assemble) task prior to the testJavaScript task. What am I misunderstanding - is my expectation that the zip should be created wrong?

D:\TRAINING\GRADLE\gradle-1.11\samples\java\multiproject>gradle testJavaScript :buildSrc:compileJava UP-TO-DATE :buildSrc:compileGroovy UP-TO-DATE :buildSrc:processResources UP-TO-DATE :buildSrc:classes UP-TO-DATE :buildSrc:jar UP-TO-DATE :buildSrc:assemble UP-TO-DATE :buildSrc:compileTestJava UP-TO-DATE :buildSrc:compileTestGroovy UP-TO-DATE :buildSrc:processTestResources UP-TO-DATE :buildSrc:testClasses UP-TO-DATE :buildSrc:test UP-TO-DATE :buildSrc:check UP-TO-DATE :buildSrc:build UP-TO-DATE :api:clean UP-TO-DATE :services:clean UP-TO-DATE :shared:clean UP-TO-DATE :someproject:clean UP-TO-DATE :services:shared:clean UP-TO-DATE :services:webservice:clean UP-TO-DATE :someproject:testJavaScript The specified zip file ZIP ‘D:\TRAINING\GRADLE\gradle-1.11\samples\java\multiproject2\api\build\ libs\api-1.0.jar’ does not exist and will be silently ignored. This behaviour has been deprecate d and is scheduled to be removed in Gradle 2.0 The specified zip file ZIP ‘D:\TRAINING\GRADLE\gradle-1.11\samples\java\multiproject2\api\build\ distributions\api-1.0.zip’ does not exist and will be silently ignored. This behaviour has been deprecated and is scheduled to be removed in Gradle 2.0 :someproject:testJavaScript UP-TO-DATE

BUILD SUCCESSFUL

Total time: 5.11 secs

Added someproject to settings.gradle (samples\java\multiproject). Added testJavaScript configuration to build.gradle (samples\java\multiproject) samples\java\multiproject\someproject\build.gradle dependencies {

testJavaScript project(path: ‘:api’, configuration: ‘archives’) }

task testJavaScript(type:Copy) {

from {

configurations.testJavaScript.collect { zipTree(it) }

}

into ‘build/deps’ }

Can you post the ‘:api’ project build script? My guess is you are declaring your artifacts in such a way as Gradle can not infer what tasks are responsible for building those artifacts.

This is a copy of what is distributed in gradle-1.11\samples\java\multiproject\api\build.gradle

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath ‘commons-math:commons-math:1.1’

} }

configurations {

spi }

dependencies {

compile project(’:shared’)

compile module(“commons-lang:commons-lang:2.4”) {

dependency(“commons-io:commons-io:1.2”)

} }

// Just a smoke test that using this option does not lead to any exception compileJava.options.compilerArgs = [’-Xlint:unchecked’]

task spiJar(type: Jar) {

appendix = ‘spi’

from sourceSets.main.output

include ‘org/gradle/api/’ }

artifacts {

spi spiJar }

task dist(type: Zip) {

dependsOn spiJar

from ‘src/dist’

into(‘libs’) {

from spiJar.archivePath

from configurations.runtime

} }

artifacts {

archives dist }

// We want to test if commons-math was properly added to the build script classpath org.apache.commons.math.fraction.Fraction lhs = new org.apache.commons.math.fraction.Fraction(1, 3); org.gradle.buildsrc.BuildSrcClass bsc = new org.gradle.buildsrc.BuildSrcClass()

task checkProjectDependency(dependsOn: project(’:shared’).jar) << {

File cachedSharedJarDir = new File(gradle.gradleUserHomeDir, “cache/multiproject/shared/jars”)

copy {

from project(’:shared’).jar.archivePath

into cachedSharedJarDir

}

File sharedJar = configurations.compile.files.find { File file -> file.name.startsWith(‘shared’)}

assert sharedJar.absolutePath == project(’:shared’).jar.archivePath.absolutePath }

I believe by using the ‘collect()’ method to build a new collection of 'FileTree’s, the build dependencies of the original configuration are being lost. You’ll simply have to explicitly tell Gradle that your task depends on the configuration.

task testJavaScript(type: Copy, dependsOn: configurations.testJavaScript)

Ok - thanks.

It appears to work differently (i.e .without the explicit dependsOn) if specified as a third-party dependency like -> testJavaScript group: rootProject.name, name: “api”, version: “$versionNum-$snapshot”, classifier: ‘spi’, ext: ‘zip’

When we specify dependencies, we have a method that determines if the project is local; if it is, we use project(), otherwise we use the repository syntax for the dependency (sometimes known as elastic-dependency).

Yes. If you specify an external module dependency (ie. group:name:version) then we simply need to resolve the configuration (which downloads the necessary files from the remote repository). If it is a project dependency, Gradle needs to know what tasks from the dependent project to execute in order to create the needed artifacts. Directly adding a ‘Configuration’ to a ‘CopySpec’ implies that task dependency. However, since you were effectively creating a new collection to add to your ‘CopySpec’, the dependency could not be inferred, thus the necessity for the explicit dependency.