用于构建"调试"和"发布"JAR文件的Idiomatic Gradle脚本

Pod*_*Pod 8 java jar release-management gradle

我正在尝试创建一个Gradle构建脚本,该脚本将.jar在"发布"或"调试"模式下构建Java 文件,并且在参数化脚本时遇到问题.

问题是:使用Java插件在Gradle脚本中执行此操作的惯用方法什么? (或者,如果没有惯用的方法,什么是真正有用的hacky解决方案?)

我不介意参数化的方法,只要命令行和IDE调用可以轻松地在两个输出选项之间进行选择.jar文件将在其他项目中用作库,例如Android应用程序和JavaFX应用程序,因此我希望参数化方法可以从他们自己的Gradle脚本调用/依赖.

理想情况下,我想'模仿'Android gradle插件具有每个任务的调试/发布版本的能力,即

$ ./gradlew build    
$ ./gradlew assembleRelease
$ ./gradlew checkDebug
Run Code Online (Sandbox Code Playgroud)

但即使是顶级buildDebug和buildRelease也不合适.


我试过的东西

本节与该问题无关.

初始点

我有以下gradle文件/项目:

group 'TestGradleProjectGroup'
apply plugin: 'java'
sourceCompatibility = 1.8

version '1.0-release'
compileJava {
    options.debug = false
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,并生成jar文件:

$ ls TestGradleModule/build/libs/
TestGradleModule-1.0-release.jar
Run Code Online (Sandbox Code Playgroud)

当检查提取的类时javap,它不包含任何调试信息.欢呼.不,我们需要一种方法来制作调试版本.

添加调试和发布任务

version '1.0-release'
compileJava {
    options.debug = false
}

task buildRelease(type: GradleBuild, dependsOn: build) {
    project.version = '1.0-release'
    compileJava {
        options.debug = false
    }
}

task buildDebug(type: GradleBuild, dependsOn: build) {
    project.version = '1.0-debug'
    compileJava {
        options.debug = true
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为总是构建调试项目,即使buildRelease是命令行上给出的任务.我想这是因为这两个任务的代码都是在配置时运行(Gradle构建生命周期),而我只想运行一个.所以我想我想在执行时运行它们?

添加一些doLast任务

version '1.0-release'
compileJava {
    options.debug = false
}

task buildRelease(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-release'
        compileJava {
            options.debug = false

        }
    }
}

task buildDebug(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-debug'
        compileJava {
            options.debug = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这更糟糕.输出文件始终是1.0版本,这是因为顶层的"默认".如果我发表评论然后没有制作版本化的jar,而是制作默认值TestGradleModule.jar.似乎doLast块的内容对compileJava任务的影响完全没用(但是没有关于这个的警告?).我想这些修改为时已晚,无法在执行时完成,或者还有其他需要完成的事情,以便compileJava任务以不同方式"配置"?

使用配置?

我注意到Java插件的手册包含对buildConfigNameand 的引用uploadConfigName,并声称它们依赖于"在配置ConfigName中生成工件的任务.".鉴于我在配置时未能对参数化进行参数化,插件执行此操作的能力看起来很有希望:

group 'TestGradleProjectGroup'
apply plugin: 'java'
sourceCompatibility = 1.8

configurations {
    debug
    release
}

version '1.0-release'
compileJava {
    options.debug = false
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}
Run Code Online (Sandbox Code Playgroud)

但:

  1. 正如我所料,这并没有增加buildReleasebuildDebug输出./gradlew tasks --all.但我可以完成这些任务.
  2. 它只是似乎让buildReleasebuildDebug,不是如assembleRelease
  3. buildRelease 在运行时似乎没有任何依赖,因此没有任何有用的效果.

迭代任务?

作为最后的尝试,我试图创建所有适当的任务并链接所有的依赖项.我尝试迭代任务并添加依赖项:

gradle.taskGraph.whenReady { taskGraph ->

    taskGraph.allTasks.each { taskIter ->

        println("iterating" + taskIter)

        def releaseTask = project.task(taskIter.name + "Release")
        def debugTask = project.task(taskIter.name + "Debug")

        taskIter.dependsOn += [releaseTask, debugTask].toSet()
        println("new taskIter.dependsOn:" + taskIter.dependsOn)

        /*
            set debug mode here,
            copy over effects of task to debug/release
            disable effects of task
        */
    }
}
Run Code Online (Sandbox Code Playgroud)

  1. 这似乎没有正确地创建任务,它们无法从命令行访问,并且运行"build"没有运行"buildRelease"等.
  2. 我还必须将所有"操作"从当前的现有任务"移动"到调试和释放任务中,以避免重复每个操作的影响.我不知道该怎么做.

简而言之,我不知道我在做什么.作为最后的手段,我可​​以手动创建所有任务,但这似乎打败了使用java插件的点,并且非常垃圾?

tkr*_*use 7

您是否需要通过一次 gradle 运行来创建这两个 jar?如果没有,它可能就像使用 gradle 的一些附加参数一样简单,例如

compileJava {
    options.debug = project.hasProperty('debugBuild')
}

gradle assemble -PdebugBuild
Run Code Online (Sandbox Code Playgroud)

请参阅此处的文档:https://docs.gradle.org/current/userguide/build_environment.html#sec :gradle_properties_and_system_properties

也不是说你可以在 gradle 论坛中获得更好的帮助。


bey*_*iii 5

经过数小时的搜寻...

“构建脚本基础” Gradle教程的“通过DAG配置”部分描述了一种执行此操作的方法,即

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#configure-by-dag

引用本教程

“ Gradle有一个配置阶段和一个执行阶段。在配置阶段之后,Gradle知道应该执行的所有任务。Gradle为您提供了一个使用此信息的钩子。为此,一个用例是检查发布是否任务是要执行的任务之一。据此,您可以为某些变量分配不同的值。”

这是gradle.taskGraph.whenReady{}使用buildRelease()buildDebug()任务的应用示例...

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(buildRelease)) {
        compileJava.options.debug = false
        project.version = '1.0-release'
    } else if (taskGraph.hasTask(buildDebug)) {
        compileJava.options.debug = true
        project.version = '1.0-debug'
    }
}

task buildRelease(type: GradleBuild, dependsOn: build) {
}

task buildDebug(type: GradleBuild, dependsOn: build) {
}
Run Code Online (Sandbox Code Playgroud)

IMO,Gradle是一个总要学习的熊。我肯定会错过好机会。