1- import com.diffplug.gradle.spotless.SpotlessExtension
21import org.gradle.api.tasks.testing.logging.TestExceptionFormat
32
43plugins {
54 `java- library`
6- id(" com.diffplug.spotless" )
75}
86
97repositories {
@@ -15,15 +13,6 @@ configure<JavaPluginExtension> {
1513 withSourcesJar()
1614}
1715
18- configure<SpotlessExtension > {
19- java {
20- importOrder()
21- removeUnusedImports()
22- palantirJavaFormat()
23- toggleOffOn()
24- }
25- }
26-
2716java {
2817 toolchain {
2918 languageVersion.set(JavaLanguageVersion .of(21 ))
@@ -62,3 +51,86 @@ tasks.withType<Test>().configureEach {
6251 exceptionFormat = TestExceptionFormat .FULL
6352 }
6453}
54+
55+ val palantir by configurations.creating
56+ dependencies {
57+ palantir(" com.palantir.javaformat:palantir-java-format:2.73.0" )
58+ }
59+
60+ fun registerPalantir (
61+ name : String ,
62+ description : String ,
63+ ) {
64+ val javaName = " ${name} Java"
65+ tasks.register<JavaExec >(javaName) {
66+ group = " Verification"
67+ this .description = description
68+
69+ classpath = palantir
70+ mainClass = " com.palantir.javaformat.java.Main"
71+
72+ // Avoid an `IllegalAccessError` on Java 9+.
73+ jvmArgs(
74+ " --add-exports" , " jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" ,
75+ " --add-exports" , " jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" ,
76+ " --add-exports" , " jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" ,
77+ " --add-exports" , " jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" ,
78+ " --add-exports" , " jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" ,
79+ )
80+
81+ // Use paths relative to the current module.
82+ val argumentFile =
83+ project.layout.buildDirectory.file(" palantir-$name -args.txt" ).get().asFile
84+ val lastRunTimeFile =
85+ project.layout.buildDirectory.file(" palantir-$name -last-run.txt" ).get().asFile
86+
87+ // Read the time when this task was last executed for this module (if ever).
88+ val lastRunTime = lastRunTimeFile.takeIf { it.exists() }?.readText()?.toLongOrNull() ? : 0L
89+
90+ // Use a `fileTree` relative to the module's source directory.
91+ val javaFiles = project.fileTree(" src" ) { include(" **/*.java" ) }
92+
93+ // Determine if any files need to be formatted or linted and continue only if there is at least
94+ // one file.
95+ onlyIf { javaFiles.any { it.lastModified() > lastRunTime } }
96+
97+ inputs.files(javaFiles)
98+
99+ doFirst {
100+ // Create the argument file and set the preferred formatting style.
101+ argumentFile.parentFile.mkdirs()
102+ argumentFile.writeText(" --palantir\n " )
103+
104+ if (name == " lint" ) {
105+ // For lint, do a dry run, so no files are modified. Set the exit code to 1 (instead of
106+ // the default 0) if any files need to be formatted, indicating that linting has failed.
107+ argumentFile.appendText(" --dry-run\n " )
108+ argumentFile.appendText(" --set-exit-if-changed\n " )
109+ } else {
110+ // `--dry-run` and `--replace` (for in-place formatting) are mutually exclusive.
111+ argumentFile.appendText(" --replace\n " )
112+ }
113+
114+ // Write the modified files to the argument file.
115+ javaFiles.filter { it.lastModified() > lastRunTime }
116+ .forEach { argumentFile.appendText(" ${it.absolutePath} \n " ) }
117+ }
118+
119+ doLast {
120+ // Record the last execution time for later up-to-date checking.
121+ lastRunTimeFile.writeText(System .currentTimeMillis().toString())
122+ }
123+
124+ // Pass the argument file using the @ symbol
125+ args = listOf (" @${argumentFile.absolutePath} " )
126+
127+ outputs.upToDateWhen { javaFiles.none { it.lastModified() > lastRunTime } }
128+ }
129+
130+ tasks.named(name) {
131+ dependsOn(tasks.named(javaName))
132+ }
133+ }
134+
135+ registerPalantir(name = " format" , description = " Formats all Java source files." )
136+ registerPalantir(name = " lint" , description = " Verifies all Java source files are formatted." )
0 commit comments