Extract resources from plugin jar


(Jamie Magee) #1

I’m writing a custom plugin to wrap the configuration and configuration files of spotless. I’m fetching the configuration files from the jar using TextResourceFactory#fromArchiveEntry, and this mostly works, except for running ./gradlew clean build. I get the following error:

Execution failed for task ':service:spotlessJava'.
> java.nio.file.NoSuchFileException: <LONG_PATH_HERE>.jar_8ebdb69772c25439b9fe2e881f138f06/spotless/spotless.importorder

Running with just ./gradlew build works fine, so I assume that clean is removing these extracted files. What’s the easiest way to defer extraction of the files, until after the clean task is run. I’m currently using this function

fun resource(project: Project, filePath: String): File {
     val jarPath = FileUtils::class.java.getResource("").file.split('!')[0]
     return project.resources.text.fromArchiveEntry(jarPath, filePath).asFile()
}

(James Justinic) #2

The file is written when you call asFile(), which I expect you’re doing as part of apply your plugin, so at configuration time. You need to not ask for an actual File until execution time.

The best case is that your target plugin accepts a TextResource and doesn’t try to convert it to a File until it’s needed by the task. I believe spotless can accept a TextResource, but will eagerly will convert the TextResource to a File as soon as you set it.

Instead, you will need to create a configuration task that does nothing more than execute your resource function shown, and then set the resulting file on all of the Spotless tasks. The Spotless tasks will also need to depend on this task.


(Jamie Magee) #3

Thanks for the reply. Do you have an example of this anywhere that I could take a look at?


(James Justinic) #4

Unfortunately, I don’t think the conventional examples are going to help you due to the way that the spotless plugin builds up tasks from the extension. The concept is the same, just the API for the task is slightly lower level than what is available for you to configure on the extension. You’ll end up needing to know a few more implementation details like ImportOrderStep.forJava():

task configureImportOrder {
   doLast {
       File importOrderFile = resource(project, "path/to/file")
       FormatterStep step = ImportOrderStep.forJava().createFrom(importOrderFile)
       spotlessJava.addStep(step);
   }
}

spotlessJava.dependsOn configureImportOrder