如何将一个Gradle项目中的工件作为资源包含在另一个项目中?

4xrmg8kj  于 9个月前  发布在  其他
关注(0)|答案(3)|浏览(107)

给定一个像这样的项目文件结构:

git-root
 ├── ServerApp
 │    ├── build.gradle
 │    └── src
 │        └── ...
 └── ClientJAR
     ├── build.gradle
     └── src
         └── ...

字符串
ServerApp需要包含ClientJAR的构建工件(默认工件)作为其资源之一。在传统意义上,ServerAppClientJAR之间没有 * 依赖关系 *-两个项目都不引用对方的代码。
如图所示,两个Gradle项目在一个git repo中是兄弟项目。更改该结构(例如,使其成为容器/复合构建)只是最后的手段;我正在寻找一个保持该结构完整的解决方案。

背景/背景

目的是ServerApp构建的应用程序有一个端点,可以用来下载ClientJAR项目中构建的工件。最明显的实现方式(对我来说)是在构建时将ClientJAR的工件作为资源嵌入到ServerApp(这是一个Sping Boot 应用程序)中。
我尝试过使用includeFlat并将ClientJAR声明为ServerApp中的依赖项,但这导致“普通”ClientJAR对象化工件被包含在ServerApp的库中,这不是我所需要的。我需要bootJar工件(目前是在ClientJAR中调用gradlew build的结果)。
有没有一种干净的方法来“嵌入”一个兄弟节点呢?甚至一个具体的例子,一个构建调用另一个(兄弟节点),然后将其输出复制到/build/resources文件夹中也是一个合理的选择(我认为)。

ztigrdn8

ztigrdn81#

我仍然在测试和检查,但下面是我使用自定义GradleBuildCopy任务的组合所做的工作。
ServerApp中,我添加了以下自定义任务:

task buildClient(type: GradleBuild) {
    buildFile = '../ClientJAR/build.gradle'
    tasks = ['clean', 'build']
}

task copyClient(type: Copy, dependsOn: buildClient) {
    from ('../ClientJAR/build/libs/') {
        include 'client-*.jar'
        rename { 'client.jar' }
    }
    into "$buildDir/resources/main"
}

字符串
我还声明了processResources应该依赖于copyClient

processResources {
    dependsOn copyClient
}


这样,client.jar就像预期的那样在ServerApp/build/resources/main/中结束(以及在最终的 Boot WAR工件中)。

kadbb459

kadbb4592#

你可以通过三个步骤来做到这一点:
1.将项目的构建链接在一起,以便它们可以相互引用;
1.根据ClientJAR配置在ServerApp构建中获得所需的配置;以及
1.将目录复制到资源中需要它的位置。

1.将项目的build链接在一起

正如你已经做过的那样,你可以使用includeFlat来实现这一点:

// ServerApp/settings.gradle

includeFlat("ClientJAR")

字符串

2.通过新配置获取消费项目中的CDN

Gradle有关于以这种方式共享工件的说明。总结一下,你可以通过四个步骤来完成:
(a)向生产者项目添加新的耗材配置(ClientJAR):

// ClientJAR/build.gradle

configurations {
   bootJarConsumable {
      canBeConsumed = true
      canBeResolved = false
   }
}


(b)使用生成bootJar(假定称为bootJarTaskName)的Jar任务向其添加所需的工件:

// ClientJAR/build.gradle

artifacts {
   bootJarConsumable(tasks.named('bootJarTaskName'))
}


(c)向ServerJAR添加新配置以加载

// ServerApp/build.gradle

configurations {
   bootJarResolvable {
      canBeConsumed = false
      canBeResolved = true
   }
}


(d)通过依赖于新的配置,依赖于消费项目中的工件:

// ServerApp/build.gradle

dependencies {
   bootJarResolvable project(path: ':ClientJAR', configuration: 'bootJarConsumable')
}

3.将目录复制到资源中需要的位置

然后ServerApp可以访问该文件,但它不在所需的位置。您可以编写一个任务来执行最后的复制步骤:

// ServerApp/build.gradle

tasks.register('copyToResources', Copy) {
    from configurations.named('bootJarResolvable')
    into sourceSets.main.resources.sourceDirectories.singleFile
}


最后,您需要确保processResources任务依赖于此,以便在运行ServerApp构建时所有内容都将运行:

// ServerApp/build.gradle

processResources {
    dependsOn copyToResources
}

0md85ypi

0md85ypi3#

这里有一个变体,可以使用复合构建正确解决它:
ServerAppsettings.gradle.kts中:

includeBuild("../ClientJar")

字符串
ServerAppbuild.gradle.kts中:

val clientJarBucket by configurations.dependencyScope("clientJarBucket")

dependencies {
    clientJarBucket("com.example:ClientJAR") {
        isTransitive = false
    }
}

val clientJar by configurations.resolvable("clientJar") {
    extendsFrom(clientJarBucket)
}

val syncClientJar by tasks.registering(Sync::class) {
    from(clientJar)
    into(temporaryDir)
}

sourceSets {
    main {
        resources {
            srcDir(syncClientJar)
        }
    }
}


这里有一个使用工具API正确解决它的变体,尽管我可能更喜欢上面更集成的方法,例如它可以更好地更新,通过驱动另一个构建,您几乎总是必须完全运行它:
ServerAppbuild.gradle.kts中:

val buildClientJar by tasks.registering {
    outputs.dir(temporaryDir)
    doLast {
        GradleConnector
            .newConnector()
            .forProjectDirectory(file("../ClientJAR"))
            .connect()
            .use {
                it
                    .newBuild()
                    .forTasks("jar")
                    .setStandardOutput(System.out)
                    .setStandardError(System.err)
                    .run()
            }
        sync {
            from("../ClientJAR/build/libs/ClientJAR.jar")
            into(temporaryDir)
        }
    }
}

sourceSets {
    main {
        resources {
            srcDir(buildClientJar)
        }
    }
}

相关问题