【问题标题】:Getting the resource path of the java project from a custom gradle plugin从自定义的gradle插件获取java项目的资源路径
【发布时间】:2021-11-15 12:30:39
【问题描述】:

尝试在 java 中创建自定义 gradle 插件,我如何从任务类中获取资源路径?

public class MyCustomPlugin implements Plugin<Project> {

  @Override
  public void apply(Project project) {
    project.getTasks().register("doStuff", CustomTask.class);
  }
}
public class CustomTask extends DefaultTask {

  // How do I get java project resources dir from here?
  @Inject
  public CustomTask(ProjectLayout projectLayout) {
    directoryProperty = projectLayout.getBuildDirectory();
  }

  @TaskAction
  public void execute() {
    ...
  }



}

【问题讨论】:

    标签: java gradle build.gradle gradle-plugin


    【解决方案1】:

    我建议不要在任务中获取目录,因为提供它的插件可能不会被应用。相反,我会在您注册任务的插件中执行此操作,这样您还可以确保实际应用了必要的插件。如果在没有为输入分配值的情况下使用任务,Gradle 将显示错误,说明没有分配任何内容。

    kotlin-dsl:

    @CacheableTask
    abstract class CustomTask : DefaultTask() {
        @get:InputFiles
        abstract val resources: FileCollection
        //...
    }
    

    如果@InputFiles 是您的用例的正确注释,我无法回答,因为我不知道您想对该资源做什么。有关可用注释及其作用的更多信息,请参阅 Gradle 文档。

    plugins {
        java
    }
    
    tasks.register<CustomTask>("customTask") {
        resources.set(sourceSets.main.map { it.resources })
    }
    

    注意map {},它确保我们的任务依赖于processResources 任务,这是自动为我们完成的,因为我们坚持使用 Gradle 的提供者 API 来处理所有事情。

    请注意,资源默认位于一个目录中,但并非必须如此。这就是资源被定义为SourceDirectorySet 而不是Provider&lt;Directory&gt; 的原因。对于源自SourceSetContainer 的任何内容也是如此。用 Java 源代码更容易解​​释:假设你有 Java 和 Kotlin,那么你将有 src/main/javasrc/main/kotlin,因此有 2 个目录。前者有一个**/*.java 包含过滤器,而后者有一个**/*.kt 包含过滤器。如果我们只想获得所有来源,那么我们使用sourceSets.main.map { it.java.sourceDirectories },如果我们想获得两者之一,它就会变得复杂。 ?

    【讨论】:

      【解决方案2】:

      您可以通过project.sourceSets访问源代码。

      @Inject
        public CustomTask(Project project) {
          directoryProperty = project.projectLayout.getBuildDirectory();
          sourceSet = project.sourceSets.main
        }
      

      另请参阅此处的参考文档:https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_project_layout

      【讨论】:

        【解决方案3】:

        首先,您必须确保这是一个 Java 项目:或者从您的插件 (project.getPluginManager().apply("java")) 应用 "java" 插件,或者仅在用户应用了 "java" 插件时才注册任务(project.getPluginManager().withPlugin("java", ignored -&gt; { project.getTasks().register(…); });)。

        然后您可以从主源集中获取资源:

        SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
        // Use named() instead of get() if you prefer/need to use providers
        SourceSet mainSourceSet = sourceSets.get(SourceSet.MAIN_SOURCE_SET_NAME);
        SourceDirectorySet resources = mainSourceSet.getResources();
        

        顺便说一句,最好的做法是让任务只声明它们的输入和输出(例如,我需要一组目录或文件作为输入,我的输出将是一个单独的文件,或者在一个单独的目录中)并且有default 值的实际接线由插件完成。
        您可以让插件无条件地注册任务,然后在应用"java" 插件时有条件地配置其对项目资源的输入;或有条件地注册任务或无条件地应用"java" 插件,如上所示。

        【讨论】:

          猜你喜欢
          • 2016-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-21
          相关资源
          最近更新 更多