gradle自定义任务类使其自身不可编译

gradle自定义任务类使其自身不可编译,gradle,plugins,multi-project,build-script,gradle-multi-project-build,Gradle,Plugins,Multi Project,Build Script,Gradle Multi Project Build,我正试图编写一个定制的Gradle任务类,并在另一个子项目中使用它。我在将构建绑定在一起时遇到问题 在本例中,我将子项目命名为“a”(对于应用程序)和“p”(对于插件,尽管我没有使用插件对象,只是为构建脚本提供了一个任务类) 格雷德尔酒店 include 'p' include 'a' p/build.gradle apply plugin: 'java' apply plugin: 'groovy' apply plugin: 'maven-publish' group 'test' ve

我正试图编写一个定制的Gradle任务类,并在另一个子项目中使用它。我在将构建绑定在一起时遇到问题

在本例中,我将子项目命名为“a”(对于应用程序)和“p”(对于插件,尽管我没有使用插件对象,只是为构建脚本提供了一个任务类)

格雷德尔酒店

include 'p'
include 'a'
p/build.gradle

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'maven-publish'

group 'test'
version '1.0'

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}
buildscript {

    repositories {
        mavenLocal()
    }

    dependencies {
        classpath 'test:p:1.0'
    }

}

group = 'test'
version = '1.0'

apply plugin: 'java'

task myTask(type: p.MyTask) {
}
p/src/main/groovy/p/MyTask.groovy

package p

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

class MyTask extends DefaultTask {
    @TaskAction
    void run() {
        System.out.println('yay!');
    }
}
a/build.gradle

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'maven-publish'

group 'test'
version '1.0'

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}
buildscript {

    repositories {
        mavenLocal()
    }

    dependencies {
        classpath 'test:p:1.0'
    }

}

group = 'test'
version = '1.0'

apply plugin: 'java'

task myTask(type: p.MyTask) {
}
“插件”是通过在p文件夹中运行来构建的:

../gradlew clean build publishToMavenLocal
在文件夹中:

../gradlew myTask
打印“耶!”

然而,在开发过程中,错误会发生。当我在MyTask中模拟错误时:

MyTask() {
    throw new RuntimeException("an error");
}
并构建插件(在文件夹p中):

正如预期的那样,它失败了

现在,我通过再次删除损坏的构造函数来“修复”错误,并在文件夹p中重建:

../gradlew clean build publishToMavenLocal
../gradlew clean build publishToMavenLocal
但是这个命令失败了,并且出现了同样的错误

据我了解,原因是:

  • 坏掉的插件在我本地的maven repo中
  • 尝试构建插件时会检测父文件夹中的settings.gradle
  • gradle尝试配置从settings.gradle引用的所有项目
  • 这将加载损坏的插件
  • 构建失败
为了验证,我注释掉了settings.gradle中的include行,它再次工作。恢复settings.gradle,它仍然可以工作,因为现在“修复”插件在我的maven repo中,重建插件只会用工作版本再次覆盖它

底线是,我的自定义任务类(或自定义插件,或任何其他构建脚本代码)中的bug有可能使它们自身不可编译,解决方法是编辑或临时重命名settings.gradle。项目越复杂,就越麻烦:如果插件代码本身包含多个子项目,重命名就不起作用,甚至注释掉也会变成“注释掉正确的行”


解决此问题的预期方法是什么?

单个(多)项目的复杂逻辑最好组织在。在大多数情况下,您可以将其视为一个普通的子项目,但仅限于构建类路径。您在此处创建的插件和任务可自动用于多项目中的所有项目


如果出于某种原因,您宁愿继续使用本地Maven存储库,您可以考虑发布带有版本号的插件稳定版本,以便更容易回滚。

问题发生在开发插件时,而不是稳定版本。buildSrc的问题在于它就像一个子项目,但插件本身非常复杂,足以由多个子项目组成。您可以在
buildSrc
中拥有子项目(尽管根项目必须依赖于它们)。您还可以将构建逻辑提取到独立项目中,并将其作为复合(包含)构建引入,这就是
buildSrc
所包含的内容。我通常用我自己的插件来做狗粮。关键是,如果要将其发布到存储库,则应使用版本号,以便在出现故障时始终可以回滚。如果无法回滚到最新的稳定状态,可以在快照上使用时间戳。但是我仍然发现第一个
buildSrc
/composite构建更易于维护。我怀疑一个composite构建最适合我的情况。你暗示buildSrc以一种更特别的方式做同样的事情,这有助于我更好地搜索这方面的资源,所以这种回答+评论的组合解决了我的问题。