@@ -42,7 +42,9 @@ def majorVersionToInt(majorVersionString) {
42
42
}
43
43
44
44
ext {
45
- release = false
45
+ // Whether to use EISOP formatting.
46
+ // Can also be achieved by having a project property with the same name.
47
+ eisopFormatting = true
46
48
47
49
// On a Java 8 JVM, use error-prone javac and source/target 8.
48
50
// On a Java 9+ JVM, use the host javac, default source/target, and required module flags.
@@ -76,11 +78,12 @@ ext {
76
78
versions = [
77
79
autoValue : ' 1.11.0' ,
78
80
errorprone : ' 2.36.0' ,
81
+ googleJavaFormat : ' 1.25.2' ,
79
82
hashmapUtil : ' 0.0.1' ,
80
83
junit : ' 4.13.2' ,
81
84
lombok : ' 1.18.36' ,
82
85
// plume-util includes a version of reflection-util. When updating ensure the versions are consistent.
83
- plumeUtil : ' 1.9.0 ' ,
86
+ plumeUtil : ' 1.9.3 ' ,
84
87
reflectionUtil : ' 1.1.3' ,
85
88
]
86
89
}
@@ -145,21 +148,21 @@ if (currentRuntimeJavaVersion >= 11) {
145
148
// > Could not create task ':spotlessJava'.
146
149
// > Add a step with [com.google.googlejavaformat:google-java-format:1.15.0] into the `spotlessPredeclare` block in the root project.
147
150
java {
148
- googleJavaFormat()
151
+ googleJavaFormat(versions . googleJavaFormat )
149
152
}
150
153
groovyGradle {
151
154
greclipse()
152
155
}
153
156
}
154
157
}
155
158
156
- allprojects {
159
+ allprojects { currentProj ->
157
160
// Increment the minor version (second number) rather than just the patch
158
161
// level (third number) if:
159
162
// * any new checkers have been added, or
160
163
// * backward-incompatible changes have been made to APIs or elsewhere.
161
164
// To make a snapshot release: ./gradlew publish
162
- version = ' 3.42.0-eisop6-SNAPSHOT '
165
+ version = ' 3.43.0 '
163
166
164
167
tasks. withType(JavaCompile ). configureEach {
165
168
options. fork = true
@@ -245,31 +248,42 @@ allprojects {
245
248
246
249
if (currentRuntimeJavaVersion >= 11 ) {
247
250
apply plugin : ' com.diffplug.spotless'
251
+ // patterns of files to skip for individual sub-projects
252
+ def perProjectDoNotFormat = [
253
+ ' checker' : [
254
+ ' bin-devel/.git-scripts/**' ,
255
+ ' bin-devel/.plume-scripts/**' ,
256
+ ' dist/**' ,
257
+ ' tests/ainfer-*/annotated/*' ,
258
+ ' tests/build/**' ,
259
+ ' tests/calledmethods-delomboked/*' ,
260
+ ' tests/nullness-javac-errors/*' ,
261
+ ],
262
+ ' dataflow' : [' manual/examples/' ],
263
+ ' framework' : [
264
+ ' tests/build/**' ,
265
+ ' tests/returnsreceiverdelomboked/*' ,
266
+ ],
267
+ ]
248
268
spotless {
249
269
// If you add any formatters to this block that require dependencies, then you must also
250
270
// add them to spotlessPredeclare block.
251
- def doNotFormat = [
252
- ' checker/bin-devel/.git-scripts/**' ,
253
- ' checker/bin-devel/.plume-scripts/**' ,
254
- ' checker/tests/ainfer-*/annotated/*' ,
255
- ' dataflow/manual/examples/' ,
256
- ' **/nullness-javac-errors/*' ,
257
- ' **/calledmethods-delomboked/*' ,
258
- ' **/returnsreceiverdelomboked/*' ,
259
- ' **/build/**' ,
260
- ' */dist/**' ,
261
- ]
262
- if (currentRuntimeJavaVersion < 14 ) {
263
- doNotFormat + = [' **/*record*/' ]
264
- }
265
- if (currentRuntimeJavaVersion < 16 ) {
266
- // TODO: directories should be renamed `-switchexpr` or some such,
267
- // as they only contain examples for switch expressions, which were
268
- // added in Java 14, not Java 17.
269
- doNotFormat + = [' **/java17/' ]
270
- }
271
- if (currentRuntimeJavaVersion < 21 ) {
272
- doNotFormat + = [' **/java21/' ]
271
+
272
+ // Always skip formatting of files under build directory
273
+ def doNotFormat = [' build/**' ]
274
+ if (currentProj != project. rootProject) {
275
+ if (perProjectDoNotFormat. containsKey(currentProj. name)) {
276
+ doNotFormat + = perProjectDoNotFormat[currentProj. name]
277
+ }
278
+ if (currentRuntimeJavaVersion < 16 ) {
279
+ doNotFormat + = [
280
+ ' tests/**/java17/' ,
281
+ ' tests/*record*/'
282
+ ]
283
+ }
284
+ if (currentRuntimeJavaVersion < 21 ) {
285
+ doNotFormat + = [' tests/**/java21/' ]
286
+ }
273
287
}
274
288
275
289
format ' misc' , {
@@ -283,40 +297,64 @@ allprojects {
283
297
}
284
298
285
299
java {
286
- def targets = [
287
- // add target folders here
288
- ' checker' ,
289
- ' checker-qual' ,
290
- ' checker-util' ,
291
- ' dataflow' ,
292
- ' docs/examples' ,
293
- ' docs/tutorial' ,
294
- ' framework' ,
295
- ' framework-test' ,
296
- ' javacutil' ,
297
- ]
298
- targets = targets. collectMany {
299
- [
300
- // must call toString() to convert GString to String
301
- " ${ it} /**/*.java" . toString(),
302
- " ${ it} /**/*.ajava" . toString()
300
+ if (currentProj == currentProj. rootProject) {
301
+ // format .java files outside of Gradle sub-projects
302
+ def targets = [
303
+ ' docs/examples' ,
304
+ ' docs/tutorial' ,
303
305
]
306
+ targets = targets. collectMany {
307
+ [
308
+ // must call toString() to convert GString to String
309
+ " ${ it} /**/*.java" . toString(),
310
+ // Not .ajava files because formatting would remove import statements.
311
+ ]
312
+ }
313
+ target targets
314
+ } else {
315
+ // not the root project; format all .java files in the sub-project
316
+ target ' **/*.java' , ' **/*.ajava'
304
317
}
305
- target targets
306
318
targetExclude doNotFormat
307
319
308
- googleJavaFormat(). aosp()
309
- importOrder(' com' , ' jdk' , ' lib' , ' lombok' , ' org' , ' java' , ' javax' )
320
+ if (eisopFormatting || project. hasProperty(' eisopFormatting' )) {
321
+ googleJavaFormat(versions. googleJavaFormat). aosp()
322
+ importOrder(' com' , ' jdk' , ' lib' , ' lombok' , ' org' , ' java' , ' javax' )
323
+ } else {
324
+ googleJavaFormat(versions. googleJavaFormat) // the formatter to apply to Java files
325
+ }
310
326
formatAnnotations(). addTypeAnnotation(" PolyInitialized" ). addTypeAnnotation(" PolyVP" ). addTypeAnnotation(" ReceiverDependentQual" )
311
327
}
312
328
313
- groovyGradle {
314
- target ' **/*.gradle'
315
- targetExclude doNotFormat
316
- greclipse() // which formatter Spotless should use to format .gradle files.
317
- leadingTabsToSpaces(4 )
318
- trimTrailingWhitespace()
319
- // endWithNewline() // Don't want to end empty files with a newline
329
+ // Only define a groovyGradle task on the root project, for simplicity in setting the target pattern
330
+ if (currentProj == currentProj. rootProject) {
331
+ groovyGradle {
332
+ target ' **/*.gradle'
333
+ targetExclude doNotFormat
334
+ greclipse() // which formatter Spotless should use to format .gradle files.
335
+ if (eisopFormatting || project. hasProperty(' eisopFormatting' )) {
336
+ indentWithSpaces(4 )
337
+ } else {
338
+ indentWithSpaces(2 )
339
+ }
340
+ trimTrailingWhitespace()
341
+ // endWithNewline() // Don't want to end empty files with a newline
342
+ }
343
+ }
344
+
345
+ // a useful task for debugging; prints exactly which files are getting formatted by spotless
346
+ tasks. register(' printSpotlessTaskInputs' ) {
347
+ doLast {
348
+ project. tasks. forEach { task ->
349
+ if (task. name. contains(' spotless' )) {
350
+ println " Inputs for task '${ task.name} ':"
351
+
352
+ task. inputs. files. each { inputFile ->
353
+ println " Input: $inputFile "
354
+ }
355
+ }
356
+ }
357
+ }
320
358
}
321
359
}
322
360
}
@@ -510,8 +548,6 @@ allprojects {
510
548
options. errorprone. errorproneArgs = [
511
549
// Many compiler classes are interned.
512
550
' -Xep:ReferenceEquality:OFF' ,
513
- // These might be worth fixing.
514
- ' -Xep:DefaultCharset:OFF' ,
515
551
// Not useful to suggest Splitter; maybe clean up.
516
552
' -Xep:StringSplitter:OFF' ,
517
553
// Too broad, rejects seemingly-correct code.
@@ -531,6 +567,10 @@ allprojects {
531
567
' -Xep:ExtendsObject:OFF' ,
532
568
// For Visitors it is convenient to just pass a Void parameter.
533
569
' -Xep:VoidUsed:OFF' ,
570
+ // The Checker Framework is the only nullness tool we care about.
571
+ ' -Xep:NullableWildcard:OFF' ,
572
+ // In the visitor pattern, it is natural to forward a Void reference.
573
+ ' -Xep:VoidUsed:OFF' ,
534
574
// -Werror halts the build if Error Prone issues a warning, which ensures that
535
575
// the errors get fixed. On the downside, Error Prone (or maybe the compiler?)
536
576
// stops as soon as it issues one warning, rather than outputting them all.
@@ -676,9 +716,14 @@ task allJavadoc(type: Javadoc, group: 'Documentation') {
676
716
}
677
717
678
718
classpath = configurations. allProjects
719
+
679
720
if (isJava8) {
680
721
classpath + = configurations. javacJar
681
722
}
723
+
724
+ // disable interpreting module-info.java files until all sub-modules support them
725
+ modularity. inferModulePath = false
726
+
682
727
doLast {
683
728
copy {
684
729
from ' docs/logo/Checkmark/CFCheckmark_favicon.png'
@@ -736,6 +781,8 @@ def createJavadocTask(taskName, taskDescription, memberLevel) {
736
781
}
737
782
738
783
classpath = configurations. allProjects
784
+ // disable interpreting module-info.java files until all sub-modules support them
785
+ modularity. inferModulePath = false
739
786
740
787
destinationDir. deleteDir()
741
788
options. memberLevel = memberLevel
@@ -931,6 +978,7 @@ subprojects {
931
978
// For an example work-around see NullnessAnnotatedTypeFactory#NONNULL_ALIASES.
932
979
933
980
// Relocate packages that might conflict with user's classpath.
981
+ relocate ' com.github.javaparser' , ' org.checkerframework.com.github.javaparser'
934
982
relocate ' org.apache' , ' org.checkerframework.org.apache'
935
983
relocate ' org.relaxng' , ' org.checkerframework.org.relaxng'
936
984
relocate ' org.plumelib' , ' org.checkerframework.org.plumelib'
@@ -944,13 +992,6 @@ subprojects {
944
992
945
993
exclude ' **/module-info.class'
946
994
947
- doFirst {
948
- if (release) {
949
- // Only relocate JavaParser during a release:
950
- relocate ' com.github.javaparser' , ' org.checkerframework.com.github.javaparser'
951
- }
952
- }
953
-
954
995
minimize()
955
996
}
956
997
@@ -984,7 +1025,7 @@ subprojects {
984
1025
manifest {
985
1026
attributes(' Implementation-Version' : " ${ project.version} " )
986
1027
attributes(' Implementation-URL' : ' https://eisop.github.io/' )
987
- if (! archiveFileName. get(). endsWith(' source.jar' )) {
1028
+ if (! archiveFileName. get(). endsWith(' source.jar' ) && ! archiveFileName . get() . startsWith( ' checker-qual ' ) ) {
988
1029
attributes(' Automatic-Module-Name' : ' org.checkerframework.' + project. name. replaceAll(' -' , ' .' ))
989
1030
}
990
1031
if (archiveFileName. get(). startsWith(' checker-qual' ) || archiveFileName. get(). startsWith(' checker-util' )) {
@@ -1150,7 +1191,25 @@ subprojects {
1150
1191
jvmArgs + = compilerArgsForRunningCF
1151
1192
}
1152
1193
1153
- maxParallelForks = Integer . MAX_VALUE
1194
+ // Run tests in parallel, except on CI where it seems to lead to flaky failures.
1195
+ // The TF_BUILD environment variable is set to 'True' for jobs running on Azure Pipelines.
1196
+ if (! System . getenv(' TF_BUILD' )?. equals(' True' )) {
1197
+ // Not running under Azure Pipelines CI.
1198
+
1199
+ // This uses Gradle's recommended value for `maxParallelForks`:
1200
+ // https://docs.gradle.org/current/userguide/performance.html#optimize_java_projects
1201
+ maxParallelForks = Runtime . runtime. availableProcessors(). intdiv(2 ) ?: 1
1202
+ } else {
1203
+ // Running under Azure Pipelines CI.
1204
+
1205
+ // Azure seems to time out when a task doesn't produce periodic output.
1206
+ if (project. name. is(' checker' )) {
1207
+ testLogging {
1208
+ events " started" , " skipped" , " failed"
1209
+ displayGranularity 3
1210
+ }
1211
+ }
1212
+ }
1154
1213
1155
1214
if (project. name. is(' checker' )) {
1156
1215
dependsOn(' assembleForJavac' )
@@ -1290,17 +1349,13 @@ task buildAll(group: 'Build') {
1290
1349
dependsOn(" ${ subproject.name} :sourcesJar" )
1291
1350
}
1292
1351
dependsOn(' framework:allJavadocJar' , ' framework:allSourcesJar' , ' checker:allJavadocJar' , ' checker:allSourcesJar' , ' checker-qual:jar' , ' checker-util:jar' )
1352
+ dependsOn(' checker:assembleForJavac' )
1293
1353
}
1294
1354
1295
1355
task releaseBuild(group : ' Build' ) {
1296
- description = ' Build everything required for a release'
1356
+ description = ' Cleans, then builds everything required for a release'
1297
1357
dependsOn(clean)
1298
- doFirst {
1299
- release = true
1300
- }
1301
- // Use finalizedBy rather than dependsOn so that release is set to true before any of the tasks are run.
1302
- finalizedBy(buildAll)
1303
- finalizedBy(' checker:assembleForJavac' )
1358
+ dependsOn(buildAll)
1304
1359
}
1305
1360
1306
1361
// No group so it does not show up in the output of `gradlew tasks`
0 commit comments