Using Spotless to auto-format Gradle Verification Metadata

Featured image for sharing metadata for article

I've previously written about Spotless being great.

I've recently started working with some codebases that use Gradle Dependency Verification which produces an XML file used for ensuring that the files downloaded by each user of the project are the same, to i.e. reduce risk of malicious artifacts being added to the build.

The gradle/verification-metadata.xml is meant to be generated by Gradle itself, but sometimes you need to manually edit things i.e. to add artifacts that have a checksum for an architecture you're not currently on.

One problem with this is that inevitably there could be differences in editor, formatting options and whitespace usage that leads to inconsistently formatted XML files.

Therefore, I moved us over to using Spotless to manage this, using:

plugins {
    id("com.diffplug.spotless") version $spotlessVersion
}

spotless {
    format("xml") {
        target("gradle/verification-metadata.xml")
        eclipseWtp(com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep.XML)
        endWithNewline()
        trimTrailingWhitespace()
    }
}

However, by working with this config, we found that the format of the resulting XML was wildly different to Gradle's, which ended up meaning that any edits - manual, or produced by Gradle - would need to have Spotless run on top of it.

That's a sub-par experience, so we wanted to improve it by seeing if we could get Spotless to create the same format that Gradle would.

Having fought this today, I definitely wanted to write it as a form of blogumentation, so future me (and maybe others) can avoid the pain.

This was a particularly painful issue as we're using Spotless' XML formatter via the Eclipse Web Tools Platform, in which Spotless delegates the hard job of formatting XML to Eclipse's tooling, and any style overrides would be defined in an Eclipse-specific configuration file.

However, because the Eclipse Web Tools Platform formatting is generally built for humans to interact with it as an IDE, this means that the settings are mostly meant to be driven through a UI, not to be well-documented for users. And without an Eclipse editor to play around with these settings and then export the configuration metadata, I was without a straightforward way to work this out.

(Towards the end I started downloading Eclipse, as I was finding it particularly awkward, until I found the source code)

To find out how this worked, I was able to piece together a couple of results on GitHub, then hit the search engines for some very specific searches, which then landed me on the source code for the XML formatter options, which ended up giving me the names of the various configuration items that the Eclipse tooling could use to tune the output.

This led to the following gradle/spotless-gradle-verification-metadata-xml.prefs:

# Tested with Gradle 7.6.x

indentationChar=space
# for some reason, Gradle produces a 3-spaced XML file
indentationSize=3

# make sure that long lines aren't split
lineWidth=2048

# make sure that XML attrs are always on the same line
splitMultiAttrs=false
# Gradle likes to end lines like ` origin="Generated by Gradle"/>`
spaceBeforeEmptyCloseTag=false

And this required being wired in like so:

 plugins {
     id("com.diffplug.spotless") version $spotlessVersion
 }

 spotless {
     format("xml") {
         target("gradle/verification-metadata.xml")
-        eclipseWtp(com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep.XML)
+        eclipseWtp(com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep.XML).configFile("gradle/spotless-gradle-verification-metadata-xml.prefs")
         endWithNewline()
         trimTrailingWhitespace()
     }
 }

This now means Spotless will perform the same resulting output as running ./gradlew --write-verification-metadata sha256 help, regardless of whether a human's mangled the XML or not.

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #gradle #spotless.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.