Home > OS >  Configure Gradle Plugin inside Gradle plugin
Configure Gradle Plugin inside Gradle plugin

Time:02-21

I want to create a custom Gradle plugin that will encapsulate Checkstyle and PMD configurations. So, other projects can just apply one custom plugin without bothering about any additional configurations.

I applied checkstyle plugin.

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

And then I applied it inside my custom plugin.

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

When I try to build the project I get an error.

Unable to find: config/checkstyle/checkstyle.xml

How can I override other plugin's properties? For example, I want to change the default checkstyle.xml path. I can do it manually inside build.gradle of the plugin project itself. But in this case, other projects that apply the plugin won't have this configurations defined by default (I tested it).

EDIT 1:

I managed to configure checkstyle plugin with ChecktyleExtension.

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 is placed in the plugin project. When I try to apply it within any other project, checkstyle searches it inside the current project directory but not the plugin's one. Is it possible to overcome this issue? I don't want users of that plugin to put any additional files inside their project.

EDIT 2:

I put the config files to resources folder and tried to read the content.

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);
            }
        });
    }
}

When I apply the plugin to another project, I get the following error:

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 cannot read the file from the jar archive for some reason. Any approaches to overcome this error?

CodePudding user response:

You'd need to bundle the checkstyle.xml within your plugin's resources folder, so when you ship it, you can always access it from within the plugin code.

Basically, you need to put the config under src/main/resources/checkstyle.xml of the plugin and then access it like this:

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

Also remember, if you ship your plugin as a .jar, you'd need to unpack the checkstyle.xml into a temp file beforehand. Roughly:

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);
    }
  }
}
  • Related