java - 为每种应用程序创建多个 shadowJars
问题描述
我正在尝试使用 gradle 并尝试设置一个系统来构建应用程序的不同风格(品牌),这些风格主要因配置而异。到目前为止,我有两个版本的构建脚本 - 都不起作用。
Version 1新增
First flavor特定资源文件夹,实现覆盖部分默认资源。任务规则定义了每种风味的任务,这应该(理想情况下)触发整个 jar 的构建。flavor-res
sourcesets
这工作正常并生成所需的罐子,一次一种口味,比如
gradle clean flavorOne
但shadowJar
任务只运行一次,如果我这样做
gradle clean flavorOne flavorTwo
精简脚本:
sourceSets {
main {
...
resources {
srcDirs = ['src/main/resources', "${project.buildDir}/flavor-res/"]
}
}
}
shadowJar { classifier = 'SNAPSHOT' }
tasks.addRule("Pattern: flavor<Name>") { String taskName ->
if (taskName.startsWith("flavor")) {
String flavorName = (taskName - "flavor")
String flavorOutDir = "${project.buildDir}/${flavorName}"
// Set output folder and jar name
task("${taskName}Configure") {
outputs.dir(flavorOutDir)
doFirst {
archivesBaseName = flavorName
project.buildDir = flavorOutDir
}
}
// Copy res to folder used in sourcesets
task("${taskName}CopyResources") {
mustRunAfter = ["${taskName}Configure"]
outputs.dir("${project.buildDir}/flavor-res")
doFirst {
copy {
from "flavors/${flavorName}/"
into "${project.buildDir}/flavor-res/"
}
}
}
shadowJar.mustRunAfter = ["${taskName}Configure", "${taskName}CopyResources"]
// Define task that depends on shadowJar
task(taskName, dependsOn: ["${taskName}Configure", "${taskName}CopyResources",
shadowJar]) {
println "Configuring ${taskName}"
}
}
感觉到它可能不起作用,因为更改检测不知何故不起作用,我尝试了另一种方法。这是脚本的简化版本
版本 2
修改了规则,shadowJar
为每种风味定义了一个动态任务。
/* Removed sourceSets in this version */
shadowJar { classifier = 'SNAPSHOT' }
tasks.addRule("Pattern: flavor<Name>") { String taskName ->
if (taskName.startsWith("flavor")) {
String flavorName = (taskName - "flavor")
String flavorOutDir = "${project.buildDir}/${flavorName}"
// Set resources for main sourceset
task("${taskName}Configure") {
outputs.dir(flavorOutDir)
doFirst {
archivesBaseName = flavorName
sourceSets.main.resources.srcDirs = ['src/main/resources', "${flavorOutDir}/flavor-res"]
project.buildDir = flavorOutDir
}
}
task("${taskName}CopyResources") {
outputs.dir("${flavorOutDir}/flavor-res")
dependsOn "${taskName}Configure"
doFirst {
copy {
from "flavors/${flavorName}/"
into "${project.buildDir}/flavor-res/"
}
}
}
// This should shadowJar for each flavor - but generate jars dont have the required artifacts.
task ("${taskName}Build", type: ShadowJar) {
from sourceSets.main.output
configurations = [ configurations.runtime ]
classifier = 'SNAPSHOT'
dependsOn "${taskName}CopyResources"
}
task(taskName, dependsOn: ["${taskName}Build"]) {
}
}
}
但是,现在,生成的 jar 格式不正确。第一种风味仅获得主要的工件,但没有显示罐子。第二个罐子只有清单,没有别的。
实现这一目标的正确方法是什么。
PS:不,它不是安卓应用程序(味道只是品牌的代名词)。
解决方案
我决定重新创建一个风味构建脚本,因为它可以简化为您现在所拥有的。该ShadowJar
任务可以自己处理复制所有类和资源,无需定义单独的。我还采用了一些将应用于shadowJar
任务的默认配置并将其应用于自定义ShadowJar
任务以获得相同的行为。
我首先构建了一个快速测试项目结构,可以在这里找到: 测试结构
然后我想出了以下脚本:
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
id 'java'
id "com.github.johnrengelman.shadow" version "2.0.4"
}
group 'your-group'
version 'dev-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
// Example dependency
compile group: 'com.google.guava', name: 'guava', version: '19.0'
}
tasks.addRule("Pattern: flavor<Name>") { def taskName ->
if (!taskName.startsWith("flavor")) {
return
}
def flavorName = taskName - "flavor"
// Define the shadow task
def shadowTask = task ("${flavorName}ShadowJar", type: ShadowJar) {
classifier = flavorName
// Add our flavor resources, first to prioritize these resources
from file("src/main/flavors/${flavorName}")
// Include our project classes
from project.sourceSets.main.output
// Don't include duplicate resources, only the first ones added, in
// this case the flavored resources will override the default ones
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
// Some defaults taken from the default shadowJar task
// https://github.com/johnrengelman/shadow/blob/master/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy#L48
configurations = [ project.configurations.runtime ]
manifest.inheritFrom project.tasks.jar.manifest
exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
}
// Define the flavor task
task ("${taskName}", dependsOn: shadowTask) {}
}
推荐阅读
- laravel - 将登录用户属性作为集合获取?
- javascript - 在 createcontext 中缺少一些案例
- python-3.x - 如何在 QGridLayout 中突出显示单元格
- php - 将数据导出到excel表时如何将数据库的行值转换为列值?
- php - Google Cloud PHP Translate 使用什么版本的翻译 API?
- php - 通过模块升级创建自定义客户属性 (UpgradeData.php)
- ios - 等待网络调用完成
- python - 当axis = 0时,Keras BatchNormalization仅适用于恒定批次暗淡?
- firefox - 如何从 Firefox 插件中读取配置文件首选项?
- javascript - 从本地存储中删除整个阵列