spotless icon indicating copy to clipboard operation
spotless copied to clipboard

Apply license header to `package-info.java` and `module-info.java`

Open jacek99 opened this issue 5 years ago • 10 comments

We added spotless with the Google Java style:

spotless {
    java {
        googleJavaFormat("1.7")
        licenseHeaderFile "${project.rootDir}/company.license.java"
    }
}

and it formatted all code...but left all the package-info.java classes untouched when we run spotlessJavaApply

is that expected behaviour or a bug? How can we force the format to include those files as well?

jacek99 avatar Feb 28 '20 17:02 jacek99

I believe google-java-format is applied to these files, it's only the license header step which is not.

https://github.com/diffplug/spotless/blob/45d2122c792927ec4ac7402ee7b10a5d495097d0/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java#L191-L193

https://github.com/diffplug/spotless/blob/45d2122c792927ec4ac7402ee7b10a5d495097d0/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java#L39-L40

In order to fix this, we would need a smarter delimiter for detecting the start of these files:

https://github.com/diffplug/spotless/blob/45d2122c792927ec4ac7402ee7b10a5d495097d0/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java#L47-L49

The trick is that we'll need a different delimiter depending on what the filename is. This is possible, but most of our steps are filename-agnostic.

Workaround

You can do something like this (untested):

spotless {
    java {
        googleJavaFormat("1.7")
        licenseHeaderFile "${project.rootDir}/company.license.java"
    }
    format 'javaMisc', {
        target 'src/**/package-info.java', 'src/**/module-info.java'
        licenseHeaderFile "${project.rootDir}/company.license.java", 'some-delimiter-i-dont-know-what'
    }
}

nedtwigg avatar Feb 28 '20 18:02 nedtwigg

I'm actually not sure if google-java-format has any specific support for package-info.java and module-info.java files.

A quick search on GitHub suggests that it doesn't crash when formatting module-info.java files and perhaps package-info.java ones as well, but not necessarily that they're formatted neatly or at all, which your experience seems to confirm.

Thus I'd suggest that you keep an eye here for module-info.java support. As for package-info.java support, I'm not entirely sure...

@nedtwigg I admit I fail to see how your example above would allow (package|module)-info.java files to be formatted with google-java-format. Would you mind clarifying for me?

jbduncan avatar Feb 28 '20 18:02 jbduncan

I fail to see how your example above would allow (package|module)-info.java files to be formatted with google-java-format.

Most of our users don't realize that the "steps" are independent - it feels like they're configuring one step. -info.java files have very little java content - their most noticeable part is their javadoc / license header.

In @jacek99's original example, google-java-format is already being applied to -info.java files, and it's easy to miss that your single "package blah;" declaration had some whitespace trimmed by google-java-format, when what you expected was a license header.

That's why I focused this issue to say "Spotless does delegate out to your formatter, but it is a known limitation that the license header part will not happen, this is why, and this is how you can fix it or work around it".

nedtwigg avatar Feb 28 '20 19:02 nedtwigg

In @jacek99's original example, google-java-format is already being applied to -info.java files, and it's easy to miss that your single "package blah;" declaration had some whitespace trimmed by google-java-format, when what you expected was a license header.

Ahh, okay, I'd completely misunderstood what was happening here; I thought the problem was that google-java-format wasn't being applied to those files by default!

Thanks for clarifying @nedtwigg. :)

jbduncan avatar Mar 06 '20 08:03 jbduncan

Just to confirm that @nedtwigg's workaround works simply by using package as delimiter:

spotless {
    java {
        ...
    }
    format 'javaMisc', {
        target 'src/**/package-info.java', 'src/**/module-info.java'
        licenseHeaderFile rootProject.file('config/spotless.license.java'), 'package '
    }
}

alvarosanchez avatar Jun 01 '20 11:06 alvarosanchez

Actually I take that back. It does apply the license, but also remove the Javadoc

alvarosanchez avatar Jun 01 '20 11:06 alvarosanchez

Using '\\/\\*\\*' as delimiter seems to do the trick, but I guess it won't work with packages without Javadoc

alvarosanchez avatar Jun 01 '20 11:06 alvarosanchez

As best we could tell, there wasn’t a single regex that worked for all cases, you need a full Java parser, which is why it has gone unsupported so long.

nedtwigg avatar Jun 01 '20 13:06 nedtwigg

I am using eclipse.xml formatting rules. Any workaround to apply the header to package-info.java or module-info.java?

deepakdaneva avatar Oct 27 '23 18:10 deepakdaneva