在 Gradle 插件中配置 Gradle 插件

Configure Gradle Plugin inside Gradle plugin

我想创建一个自定义 Gradle 插件来封装 Checkstyle 和 PMD 配置。因此,其他项目可以只应用一个自定义插件,而无需担心任何额外的配置。

我应用了checkstyle插件。

plugins {
    id 'java-gradle-plugin'
    id 'checkstyle'
}

然后我将它应用到我的自定义插件中。

public class CustomPlugin implements Plugin<Project> {
    public void apply(Project project) {
        project.getPluginManager().apply(CheckstylePlugin.class);
    }
}

当我尝试构建项目时出现错误。

Unable to find: config/checkstyle/checkstyle.xml

如何覆盖其他插件的属性?例如,我想更改默认的 checkstyle.xml 路径。我可以在插件项目本身的 build.gradle 中手动完成。但是在这种情况下,其他应用该插件的项目不会默认定义这个配置(我测试过)。

编辑 1:

我设法用 ChecktyleExtension 配置 checkstyle 插件。

public class MetricCodingRulesGradlePluginPlugin implements Plugin<Project> {
    public void apply(Project project) {
        project.getPluginManager().apply("checkstyle");
        project.getExtensions().configure(CheckstyleExtension.class, checkstyleExtension -> {
            checkstyleExtension.setConfigFile(new File("style/checkstyle.xml"));
        });
    }
}

checkstyle.xml放在插件项目中。当我尝试在任何其他项目中应用它时,checkstyle 在当前项目目录而不是插件目录中搜索它。有可能克服这个问题吗?我不希望该插件的用户将任何其他文件放入他们的项目中。

编辑 2:

我将配置文件放入 resources 文件夹并尝试读取内容。

public class MetricCodingRulesGradlePluginPlugin implements Plugin<Project> {
    public void apply(Project project) {
        project.getPluginManager().apply("checkstyle");
        project.getExtensions().configure(CheckstyleExtension.class, checkstyleExtension -> {
            URL url = getClass().getClassLoader().getResource("style/checkstyle.xml");
            System.out.println("URL: " + url);
            try {
                checkstyleExtension.setConfigFile(
                    Paths.get(url.toURI())
                        .toFile()
                );
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }
        });
    }
}

当我将插件应用到另一个项目时,出现以下错误:

URL: jar:file:/Users/user/.gradle/caches/jars-9/8f4176a8ae146bf601f1214b287eb805/my-plugin-0.0.1-SNAPSHOT.jar!/style/checkstyle.xml

Caused by: java.nio.file.FileSystemNotFoundException
    at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
    at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)

Java 由于某种原因无法从 jar 存档中读取文件。有什么方法可以克服这个错误吗?

您需要将 checkstyle.xml 捆绑在插件的 resources 文件夹中,这样当您发布它时,您始终可以从插件代码中访问它。

基本上,您需要将配置放在插件的src/main/resources/checkstyle.xml下,然后像这样访问它:

URL resourceURL = getClass().getClassLoader().getResource("checkstyle.xml");
if (resourceURL != null) {
  File resourceFile = File(resourceURL.getFile());
  checkstyleExtension.setConfigFile(resourceFile);
} 

另外请记住,如果您将插件作为 .jar 发布,您需要事先将 checkstyle.xml 解压到一个临时文件中。大致:

File temp = File.createTempFile(".checkstyle", ".xml")
try (FileOutputStream out = new FileOutputStream(temp)) {
  try (InputStream resourceStream = getClass().getClassLoader().getResourceAsStream("checkstyle.xml")) {
    byte[] buffer = new byte[1024];
    int bytes = resourceStream.read(buffer);
    while (bytes >= 0) {
      out.write(buffer, 0, bytes);
      bytes = resourceStream.read(buffer);
    }
  }
}