Define an artifact to be used as a dependency in another project

独自空忆成欢 提交于 2019-12-10 15:29:42

问题


TL;DR

I'm trying to configure two Gradle projects in a way that one project uses files built by the other one. The first project is added to the second one by includeBuild and the file is defined in the second project as a dependency.

Project testA

settings.gradle:

rootProject.name = 'testA'

build.gradle:

group = 'org.test'
version = '0.0.0.1_test'

task someZip (type: Zip) {
    from './settings.gradle'
    archiveName = 'xxx.zip'
    destinationDir = file("${buildDir}/test")
}

artifacts {
    //TODO add something here?
}

Project testB

settings.gradle:

rootProject.name = 'testB'

if (System.getenv('LOCAL_COMPILATION') == 'true') {
    includeBuild '../testA'
}

build.gradle:

if (System.getenv('LOCAL_COMPILATION') != 'true') {
    repositories {
        maven { url '192.168.1.100' }
    }
}

configurations {
    magic
}

dependencies {
    magic 'org.test:xxx:0.0.0.+@zip'
}

task ultimateZip (type: Zip) {
    from configurations.magic
    archiveName = 'ultimate.zip'
    destinationDir = file("${buildDir}/ultimate-test")
}

Description

You may noticed that the example has an option use a maven repository. I wanted to highlight that eventually there will be a possibility to do that. Using Maven repository is not the point of this question, though, other than the solution should not interfere with that. (In other words you can assume that System.getenv('LOCAL_COMPILATION') == 'true'.)

The question is how to define the artifact in a way that the other project is able to recognize it.

The preferred solution should be similar to what the Java plugin does because I'm using jar dependencies in my projects and they are working both through includeBuild and through a repository.


回答1:


The following setup should work (tested with Gradle 5.5.1). It mostly corresponds to your original setup with the exception of the changes indicated by XXX.

Project testA

settings.gradle:

rootProject.name = 'testA'

build.gradle:

group = 'org.test'
version = '0.0.0.1_test'

task someZip (type: Zip) {
    from './settings.gradle'
    archiveName = 'xxx.zip'
    destinationDir = file("${buildDir}/test")
}

// XXX (replaced your empty "artifacts" block)
configurations.create('default')
def myArtifact = artifacts.add('default', someZip) {
    name = 'xxx'
}

// XXX (only added to show that publishing works)
apply plugin: 'maven-publish'
publishing {
    repositories {
        maven { url = 'file:///tmp/my-repo' }
    }
    publications {
        myPub(MavenPublication) {
            artifactId myArtifact.name
            artifact myArtifact
        }
    }
}

Project testB

settings.gradle:

rootProject.name = 'testB'

if (System.getenv('LOCAL_COMPILATION') == 'true') {
    // XXX (added a dependency substitution to let Gradle know that
    //      "org.test:xxx" corresponds to the testA project)
    includeBuild('../testA') {
        dependencySubstitution {
            substitute module('org.test:xxx') with project(':')
        }
    }
}

build.gradle:

if (System.getenv('LOCAL_COMPILATION') != 'true') {
    repositories {
        // XXX (only changed to show that resolution still works after
        //      publishing)
        maven { url = 'file:///tmp/my-repo' }
    }
}

configurations {
    magic
}

dependencies {
    magic 'org.test:xxx:0.0.0.+@zip'
}

task ultimateZip (type: Zip) {
    from configurations.magic
    archiveName = 'ultimate.zip'
    destinationDir = file("${buildDir}/ultimate-test")
}

As requested in the comments, here’s some more explanation on the created default configuration and the added artifact in project testA.

Composite builds in Gradle currently have the limitation that substituted project dependencies “will always point to the default configuration of the target project”. In your example this means that testA needs to publish in the default configuration. We thus first create the default configuration. Note that some plugins (like java) already create this configuration; you don’t need to create it yourself when using such plugins.

It doesn’t seem to be mentioned explicitly anywhere but as you seem to have found out yourself already, the PublishedArtifacts of a project (as declared with project.artifacts) are important for Gradle to figure out the dependency wiring in composite builds. Hence, we make sure to declare such a PublishedArtifact in testA using this API. The artifact (e.g., its extension) is configured based on the properties of the someZip task. The name seems to not be taken from the someZip task in your example because you manually set archiveName; hence we need to explicitly declare it. If you use archiveBaseName = 'xxx' in someZip instead, then you don’t need the closure when adding the artifact.



来源:https://stackoverflow.com/questions/57110795/define-an-artifact-to-be-used-as-a-dependency-in-another-project

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!