| sourceSets { |
| main { |
| resources { |
| // Stub files, message.properties, etc. |
| srcDirs += ['src/main/java'] |
| } |
| } |
| testannotations |
| } |
| |
| |
| sourcesJar { |
| // The resources duplicate content from the src directory. |
| duplicatesStrategy = DuplicatesStrategy.EXCLUDE |
| } |
| |
| dependencies { |
| implementation project(':javacutil') |
| implementation project(':dataflow') |
| implementation project(':framework') |
| // AFU is an "includedBuild" imported in checker-framework/settings.gradle, so the version number doesn't matter. |
| // https://docs.gradle.org/current/userguide/composite_builds.html#settings_defined_composite |
| implementation('org.checkerframework:annotation-file-utilities:*') { |
| exclude group: 'com.google.errorprone', module: 'javac' |
| } |
| implementation project(':checker-qual') |
| implementation project(':checker-util') |
| |
| // External dependencies: |
| // If you add an external dependency, you must shadow its packages. |
| // See the comment in ../build.gradle in the shadowJar block. |
| |
| // As of 2019-12-16, the version of reflection-util in the Annotation |
| // File Utilities takes priority over this version, in the fat jar |
| // file. :-( So update it and re-build it locally when updating this. |
| implementation 'org.plumelib:reflection-util:1.0.3' |
| implementation 'org.plumelib:plume-util:1.5.3' |
| |
| // Dependencies added to "shadow" appear as dependencies in Maven Central. |
| shadow project(':checker-qual') |
| shadow project(':checker-util') |
| |
| // Called Methods Checker AutoValue + Lombok support |
| testImplementation "com.google.auto.value:auto-value-annotations:1.7.4" |
| testImplementation "com.google.auto.value:auto-value:1.7.4" |
| testImplementation "com.ryanharter.auto.value:auto-value-parcel:0.2.8" |
| testImplementation "org.projectlombok:lombok:1.18.20" |
| // Called Methods Checker support for detecting misuses of AWS APIs |
| testImplementation "com.amazonaws:aws-java-sdk-ec2" |
| testImplementation "com.amazonaws:aws-java-sdk-kms" |
| // The AWS SDK is used for testing the Called Methods Checker. |
| testImplementation platform("com.amazonaws:aws-java-sdk-bom:1.11.964") |
| |
| testImplementation group: 'junit', name: 'junit', version: '4.13.2' |
| testImplementation project(':framework-test') |
| testImplementation sourceSets.testannotations.output |
| |
| testannotationsImplementation project(':checker-qual') |
| } |
| |
| jar { |
| manifest { |
| attributes("Main-Class": "org.checkerframework.framework.util.CheckerMain") |
| } |
| } |
| |
| task copyJarsToDist(dependsOn: shadowJar, group: 'Build') { |
| description 'Builds or downloads jars required by CheckerMain and puts them in checker/dist.' |
| dependsOn project(':checker-qual').tasks.jar |
| doLast { |
| copy { |
| from file(project(':checker-qual').tasks.getByName("jar").archivePath) |
| into "${projectDir}/dist" |
| rename { String fileName -> |
| // remove version number on checker-qual.jar |
| fileName.replace(fileName, "checker-qual.jar") |
| } |
| } |
| |
| copy { |
| from file(project(':checker-util').tasks.getByName("jar").archivePath) |
| into "${projectDir}/dist" |
| rename { String fileName -> |
| // remove version number on checker-util.jar |
| fileName.replace(fileName, "checker-util.jar") |
| } |
| } |
| |
| copy { |
| from configurations.javacJar |
| into "${projectDir}/dist" |
| rename { String fileName -> |
| fileName.replace(fileName, "javac.jar") |
| } |
| } |
| } |
| } |
| |
| assemble.dependsOn copyJarsToDist |
| |
| task allSourcesJar(type: Jar, group: 'Build') { |
| description 'Creates a sources jar that includes sources for all Checker Framework classes in checker.jar' |
| destinationDirectory = file("${projectDir}/dist") |
| archiveFileName = "checker-source.jar" |
| archiveClassifier = "sources" |
| from (sourceSets.main.java, project(':framework').sourceSets.main.allJava, |
| project(':dataflow').sourceSets.main.allJava, project(':javacutil').sourceSets.main.allJava, |
| project(':checker-qual').sourceSets.main.allJava, project(':checker-util').sourceSets.main.allJava) |
| } |
| |
| task allJavadocJar(type: Jar, group: 'Build') { |
| description 'Creates javadoc jar including Javadoc for all of the Checker Framework' |
| dependsOn rootProject.tasks.allJavadoc |
| destinationDirectory = file("${projectDir}/dist") |
| archiveFileName = "checker-javadoc.jar" |
| archiveClassifier = "javadoc" |
| from rootProject.tasks.allJavadoc.destinationDir |
| } |
| |
| // Shadowing Test Sources and Dependencies |
| import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar |
| |
| task checkerJar(type: ShadowJar, dependsOn: compileJava, group: 'Build') { |
| description "Builds checker-${project.version}.jar with all dependencies except checker-qual and checker-util." |
| includeEmptyDirs = false |
| archivesBaseName = 'checker' |
| archiveClassifier = '' |
| |
| from shadowJar.source |
| configurations = shadowJar.configurations |
| // To see what files are incorporated into the shadow jar file: |
| // doLast { println sourceSets.main.runtimeClasspath.asPath } |
| manifest { |
| attributes("Main-Class": "org.checkerframework.framework.util.CheckerMain") |
| } |
| exclude 'org/checkerframework/**/qual/*' |
| exclude 'org/checkerframework/checker/*/util/*' |
| relocators = shadowJar.getRelocators() |
| } |
| |
| jar { |
| dependsOn(checkerJar) |
| // Never build the skinny jar. |
| onlyIf {false} |
| archiveClassifier = 'skinny' |
| } |
| |
| shadowJar { |
| description 'Creates checker-VERSION-all.jar and copies it to dist/checker.jar.' |
| // To see what files are incorporated into the shadow jar file: |
| // doFirst { println sourceSets.main.runtimeClasspath.asPath } |
| doLast{ |
| copy { |
| from archiveFile.get() |
| into file("${projectDir}/dist") |
| rename 'checker.*', 'checker.jar' |
| } |
| } |
| } |
| |
| artifacts { |
| // Don't add this here or else the Javadoc and the sources jar is built during the assemble task. |
| // archives allJavadocJar |
| // archives allSourcesJar |
| archives shadowJar |
| archives checkerJar |
| } |
| |
| clean { |
| delete "${projectDir}/dist" |
| delete "tests/calledmethods-delomboked" |
| delete("tests/wpi-testchecker/annotated") |
| delete("tests/wpi-testchecker/inference-output") |
| delete("tests/wpi-nullness/annotated") |
| delete("tests/wpi-nullness/inference-output") |
| } |
| |
| // Add non-junit tests |
| createCheckTypeTask(project.name,, "CompilerMessages", |
| 'org.checkerframework.checker.compilermsgs.CompilerMessagesChecker') |
| checkCompilerMessages { |
| doFirst { |
| options.compilerArgs += [ |
| '-Apropfiles=' + sourceSets.main.resources.filter { file -> file.name.equals('messages.properties') }.asPath + ":" |
| + project(':framework').sourceSets.main.resources.filter { file -> file.name.equals('messages.properties') }.asPath |
| ] |
| } |
| } |
| |
| task nullnessExtraTests(type: Exec, dependsOn: copyJarsToDist, group: 'Verification') { |
| description 'Run extra tests for the Nullness Checker.' |
| executable 'make' |
| environment JAVAC: "${projectDir}/bin/javac", JAVAP: 'javap' |
| args = ['-C', 'tests/nullness-extra/'] |
| } |
| |
| task commandLineTests(type: Exec, dependsOn: copyJarsToDist, group: 'Verification') { |
| description 'Run tests that need a special command line.' |
| executable 'make' |
| environment JAVAC: "${projectDir}/bin/javac" |
| args = ['-C', 'tests/command-line/'] |
| } |
| |
| task tutorialTests(dependsOn: copyJarsToDist, group: 'Verification') { |
| description 'Test that the tutorial is working as expected.' |
| doLast { |
| ant.ant(dir: "${rootDir}/docs/tutorial/tests", useNativeBasedir: 'true', inheritAll: 'false') { |
| target(name: 'check-tutorial') |
| } |
| } |
| } |
| |
| task exampleTests(type: Exec, dependsOn: copyJarsToDist, group: 'Verification') { |
| description 'Run tests for the example programs.' |
| executable 'make' |
| environment JAVAC: "${projectDir}/bin/javac" |
| args = ['-C', '../docs/examples'] |
| } |
| |
| task demosTests(dependsOn: copyJarsToDist, group: 'Verification') { |
| description 'Test that the demos are working as expected.' |
| doLast { |
| if (JavaVersion.current() == JavaVersion.VERSION_1_8) { |
| File demosDir = new File(projectDir, '../../checker-framework.demos'); |
| if (!demosDir.exists()) { |
| exec { |
| workingDir file(demosDir.toString() + '/../') |
| executable 'git' |
| args = ['clone', '--depth', '1', 'https://github.com/typetools/checker-framework.demos.git'] |
| } |
| } else { |
| exec { |
| workingDir demosDir |
| executable 'git' |
| args = ['pull', 'https://github.com/typetools/checker-framework.demos.git'] |
| ignoreExitValue = true |
| } |
| } |
| ant.properties.put('checker.lib', file("${projectDir}/dist/checker.jar").absolutePath) |
| ant.ant(dir: demosDir.toString()) |
| } else { |
| println("Skipping demosTests because they only work with Java 8.") |
| } |
| } |
| } |
| |
| task allNullnessTests(type: Test, group: 'Verification') { |
| description 'Run all Junit tests for the Nullness Checker.' |
| include '**/Nullness*.class' |
| } |
| |
| task allCalledMethodsTests(type: Test, group: 'Verification') { |
| description 'Run all Junit tests for the Called Methods Checker.' |
| include '**/CalledMethods*.class' |
| dependsOn 'delombok' |
| } |
| |
| // These are tests that should only be run with JDK 11. |
| task jtregJdk11Tests(dependsOn: ':downloadJtreg', group: 'Verification') { |
| description 'Run the jtreg tests made for JDK 11.' |
| dependsOn('compileJava') |
| dependsOn('compileTestJava') |
| dependsOn('shadowJar') |
| |
| String jtregOutput = "${buildDir}/jtregJdk11" |
| String name = 'all' |
| doLast { |
| if (isJava8) { |
| println "This test is only run with JDK 11." |
| return; |
| } |
| exec { |
| executable "${jtregHome}/bin/jtreg" |
| args = [ |
| "-dir:${projectDir}/jtregJdk11", |
| "-workDir:${jtregOutput}/${name}/work", |
| "-reportDir:${jtregOutput}/${name}/report", |
| "-verbose:summary", |
| "-javacoptions:-g", |
| "-keywords:!ignore", |
| "-samevm", |
| "-javacoptions:-classpath ${tasks.shadowJar.archiveFile.get()}:${sourceSets.test.output.asPath}", |
| "-vmoptions:-classpath ${tasks.shadowJar.archiveFile.get()}:${sourceSets.test.output.asPath}", |
| "-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", |
| "-javacoptions:-classpath ${sourceSets.testannotations.output.asPath}", |
| // Location of jtreg tests |
| '.' |
| ] |
| } |
| |
| |
| } |
| } |
| |
| // JSpecify tests are excluded by default. To run them: |
| // ./gradlew NullnessJSpecifySamplesTest |
| test { |
| exclude '**/org/checkerframework/checker/test/junit/NullnessJSpecifySamplesTest.class' |
| } |
| |
| task delombok { |
| description 'Delomboks the source code tree in tests/calledmethods-lombok' |
| |
| def srcDelomboked = 'tests/calledmethods-delomboked' |
| def srcJava = 'tests/calledmethods-lombok' |
| |
| inputs.files file(srcJava) |
| outputs.dir file(srcDelomboked) |
| |
| // Because there are Checker Framework annotations in the test source. |
| dependsOn project(':checker-qual').tasks.jar |
| |
| doLast { |
| def collection = files(configurations.testCompileClasspath) |
| ant.taskdef(name: 'delombok', classname: 'lombok.delombok.ant.Tasks$Delombok', |
| classpath: collection.asPath) |
| ant.delombok(from: srcJava, to: srcDelomboked, classpath: collection.asPath) |
| } |
| } |
| |
| tasks.test.dependsOn("delombok") |
| |
| /// |
| /// Whole-program inference tests |
| /// |
| |
| test { |
| useJUnit { |
| // These are run in task wholeProgramInferenceTests. |
| excludeCategories 'org.checkerframework.checker.test.junit.wpirunners.WholeProgramInferenceTestCheckerJaifsTest' |
| excludeCategories 'org.checkerframework.checker.test.junit.wpirunners.WholeProgramInferenceTestCheckerStubsTest' |
| excludeCategories 'org.checkerframework.checker.test.junit.wpirunners.WholeProgramInferenceTestCheckerAjavaTest' |
| excludeCategories 'org.checkerframework.checker.test.junit.wpirunners.WholeProgramInferenceNullnessJaifsTest' |
| } |
| } |
| |
| task testWpiTestCheckerStubs(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceTestCheckerStubTests instead. This runs the wpi-testchecker tests with -Ainfer=stubs to generate stub files' |
| |
| dependsOn(compileTestJava) |
| doFirst { |
| delete("tests/wpi-testchecker/annotated") |
| delete("${buildDir}/wpi-testchecker/") |
| } |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerStubsTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and the expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| |
| doLast { |
| copyNonannotatedToAnnotatedDirectory("wpi-testchecker") |
| // The stub file format doesn't support annotations on anonymous inner classes, so |
| // this test also expects errors on UsesAnonymous.java. |
| delete('tests/wpi-testchecker/annotated/UsesAnonymous.java') |
| copy { |
| from file('tests/wpi-testchecker/non-annotated/UsesAnonymous.java') |
| into file('tests/wpi-testchecker/annotated') |
| } |
| } |
| } |
| |
| task testWpiTestCheckerStubsValidate(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceTestCheckerStubTests instead. This re-runs the wpi-testchecker tests using the stub files generated by testWpiTestCheckerStubs' |
| |
| dependsOn(testWpiTestCheckerStubs) |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerStubsValidationTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and the expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| } |
| |
| task testWpiTestCheckerAjava(type: Test) { |
| description 'Internal task. Users sholud run wholeProgramInferenceTestCheckerAjavaTests instead. This runs the wpi-testchecker tests with -Ainfer=ajava to generate stub files' |
| |
| dependsOn(compileTestJava) |
| doFirst { |
| delete("tests/wpi-testchecker/annotated") |
| delete("${buildDir}/wpi-testchecker/") |
| } |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerAjavaTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and the expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| |
| doLast { |
| copyNonannotatedToAnnotatedDirectory("wpi-testchecker") |
| } |
| } |
| |
| task testWpiTestCheckerAjavaValidate(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceTestCheckerAjavaTests instead. This re-runs the wpi-testchecker tests using the ajava files generated by testWpiTestCheckerAjava' |
| |
| dependsOn(testWpiTestCheckerAjava) |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerAjavaValidationTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and the expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| } |
| |
| // Copies directories as needed by WPI tests. |
| // Formal parameter testdir is, for example, "wpi-testchecker". |
| // Does work in directory "tests/${testdir}/". |
| // 1. Copies whole-program inference test source code from the non-annotated/ to the annotated/ directory. |
| // 2. Copies WPI output, such as .jaif or .stub files, to the inferference-output/ directory. |
| void copyNonannotatedToAnnotatedDirectory(String testdir) { |
| // Copying all test files to another directory, removing all expected errors that should not |
| // occur after inserting inferred annotations from .jaif files. |
| copy { |
| from files("tests/${testdir}/non-annotated") |
| into file("tests/${testdir}/annotated") |
| filter { String line -> |
| line.contains('// :: error:') || line.contains('// :: warning:') ? null : line |
| } |
| } |
| // The only file for which expected errors are maintained is ExpectedErrors.java, so we copy it over. |
| delete("tests/${testdir}/annotated/ExpectedErrors.java") |
| copy { |
| from file("tests/${testdir}/non-annotated/ExpectedErrors.java") |
| into file("tests/${testdir}/annotated") |
| } |
| |
| delete("tests/${testdir}/inference-output") |
| file("build/whole-program-inference").renameTo(file("tests/${testdir}/inference-output")) |
| } |
| |
| // This task is similar to the wholeProgramInferenceTestCheckerJaifTests task below, but it doesn't |
| // run the insert-annotations-to-source tool. Instead, it tests the -Ainfer=stubs feature |
| // and the -AmergeStubsWithSource feature to do WPI using stub files. |
| task wholeProgramInferenceTestCheckerStubTests(dependsOn: 'shadowJar', group: 'Verification') { |
| description 'Run tests for whole-program inference using stub files' |
| dependsOn(testWpiTestCheckerStubsValidate) |
| outputs.upToDateWhen { false } |
| } |
| |
| // Like wholeProgramInferenceTestCheckerStubTests, but with ajava files instead |
| task wholeProgramInferenceTestCheckerAjavaTests(dependsOn: 'shadowJar', group: 'Verification') { |
| description 'Run tests for whole-program inference using ajava files' |
| dependsOn(testWpiTestCheckerAjavaValidate) |
| outputs.upToDateWhen { false } |
| } |
| |
| task testWpiTestCheckerJaifs(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceNullnessJaifTests instead. This runs the wpi-testchecker tests with -Ainfer=jaifs to generate .jaif files' |
| |
| dependsOn(compileTestJava) |
| dependsOn(':checker-qual:jar') // For the Value Checker annotations. |
| doFirst { |
| delete("tests/wpi-testchecker/annotated") |
| } |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerJaifsTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| |
| doLast { |
| copyNonannotatedToAnnotatedDirectory("wpi-testchecker") |
| |
| // JAIF-based WPI fails these tests, which was added for stub-based WPI. |
| // See issue here: https://github.com/typetools/checker-framework/issues/3009 |
| delete('tests/wpi-testchecker/annotated/ConflictingAnnotationsTest.java') |
| delete('tests/wpi-testchecker/annotated/MultiDimensionalArrays.java') |
| |
| // Inserting annotations from .jaif files in-place. |
| String jaifsDir = "tests/wpi-testchecker/inference-output"; |
| List<File> jaifs = fileTree(jaifsDir).matching { |
| include '*.jaif' |
| }.asList() |
| if (jaifs.isEmpty()) { |
| throw new GradleException("no .jaif files found in ${jaifsDir}") |
| } |
| String javasDir = "tests/wpi-testchecker/annotated/"; |
| List<File> javas = fileTree(javasDir).matching { |
| include '*.java' |
| }.asList() |
| if (javas.isEmpty()) { |
| throw new GradleException("no .java files found in ${javasDir}") |
| } |
| exec { |
| executable "${afu}/scripts/insert-annotations-to-source" |
| // Script argument -cp must precede Java program argument -i. |
| // checker-qual is needed for Constant Value Checker annotations. |
| args = ['-cp', "${sourceSets.test.output.asPath}:${project(':checker-qual').tasks.jar.archivePath}"] |
| args += ['-i'] |
| for (File jaif : jaifs) { |
| args += [jaif.toString()] |
| } |
| for (File javaFile : javas) { |
| args += [javaFile.toString()] |
| } |
| } |
| } |
| } |
| |
| task testWpiTestCheckerJaifsValidate(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceNullnessJaifTests instead. This re-runs the wpi-testchecker tests using the .jaif files generated by testWpiTestCheckerJaifs' |
| |
| dependsOn(testWpiTestCheckerJaifs) |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceTestCheckerJaifsValidationTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| } |
| |
| task wholeProgramInferenceTestCheckerJaifTests(dependsOn: 'shadowJar', group: 'Verification') { |
| description 'Run tests for whole-program inference using .jaif files' |
| dependsOn(testWpiTestCheckerJaifsValidate) |
| outputs.upToDateWhen { false } |
| } |
| |
| |
| task testWpiNullnessJaifs(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceNullnessJaifTests instead. This runs the wpi-nullness tests with -Ainfer=jaifs to generate .jaif files' |
| |
| dependsOn(compileTestJava) |
| doFirst { |
| delete("tests/wpi-nullness/annotated") |
| } |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceNullnessJaifsTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| |
| doLast { |
| copyNonannotatedToAnnotatedDirectory("wpi-nullness") |
| |
| // JAIF-based WPI fails these tests, which was added for stub-based WPI. |
| // See issue here: https://github.com/typetools/checker-framework/issues/3009 |
| delete('tests/wpi-nullness/annotated/ConflictingAnnotationsTest.java') |
| delete('tests/wpi-nullness/annotated/MultiDimensionalArrays.java') |
| |
| // Inserting annotations from .jaif files in-place. |
| String jaifsDir = "tests/wpi-nullness/inference-output"; |
| List<File> jaifs = fileTree(jaifsDir).matching { |
| include '*.jaif' |
| }.asList() |
| if (jaifs.isEmpty()) { |
| throw new GradleException("no .jaif files found in ${jaifsDir}") |
| } |
| String javasDir = "tests/wpi-nullness/annotated/"; |
| List<File> javas = fileTree(javasDir).matching { |
| include '*.java' |
| }.asList() |
| if (javas.isEmpty()) { |
| throw new GradleException("no .java files found in ${javasDir}") |
| } |
| exec { |
| executable "${afu}/scripts/insert-annotations-to-source" |
| // Script argument -cp must precede Java program argument -i. |
| args = ['-cp', "${sourceSets.test.output.asPath}"] |
| args += ['-i'] |
| for (File jaif : jaifs) { |
| args += [jaif.toString()] |
| } |
| for (File javaFile : javas) { |
| args += [javaFile.toString()] |
| } |
| } |
| } |
| } |
| |
| task testWpiNullnessJaifsValidate(type: Test) { |
| description 'Internal task. Users should run wholeProgramInferenceNullnessJaifTests instead. This re-runs the wpi-nullness tests using the .jaif files generated by testWpiNullnessJaifs' |
| |
| dependsOn(testWpiNullnessJaifs) |
| outputs.upToDateWhen { false } |
| include '**/WholeProgramInferenceNullnessJaifsValidationTest.class' |
| testLogging { |
| // Always run the tests |
| outputs.upToDateWhen { false } |
| |
| // Show the found unexpected diagnostics and expected diagnostics not found. |
| exceptionFormat "full" |
| events "passed", "skipped", "failed" |
| } |
| } |
| |
| task wholeProgramInferenceNullnessJaifTests(dependsOn: 'shadowJar', group: 'Verification') { |
| description 'Run tests for whole-program inference using .jaif files' |
| dependsOn(testWpiNullnessJaifsValidate) |
| outputs.upToDateWhen { false } |
| } |
| |
| |
| // Empty task that just runs both the jaif and stub WPI tests. |
| // It is run as part of the inferenceTests task. |
| task wholeProgramInferenceTests(group: 'Verification') { |
| description "Run tests for all whole program inference modes." |
| dependsOn('wholeProgramInferenceTestCheckerJaifTests') |
| dependsOn('wholeProgramInferenceTestCheckerStubTests') |
| dependsOn('wholeProgramInferenceTestCheckerAjavaTests') |
| dependsOn('wholeProgramInferenceNullnessJaifTests') |
| } |
| |
| // This is run as part of the inferenceTests task. |
| task wpiManyTests(group: "Verification") { |
| description 'Tests the wpi-many.sh script (and indirectly the wpi.sh script). Requires an Internet connection.' |
| dependsOn(copyJarsToDist) |
| // This test must always be re-run when requested. |
| outputs.upToDateWhen { false } |
| |
| doFirst { |
| delete("${project.projectDir}/build/wpi-many-tests-results/") |
| // wpi-many.sh is run in skip mode so that logs are preserved, but |
| // we don't actually want to skip previously-failing tests when we |
| // re-run the tests locally. |
| delete fileTree("${project.projectDir}/build/wpi-many-tests") { |
| include '**/.cannot-run-wpi' |
| } |
| } |
| |
| doLast { |
| // Run wpi-many.sh |
| def typecheckFilesDir = "${project.projectDir}/build/wpi-many-tests-results/" |
| try { |
| exec { |
| commandLine 'bin/wpi-many.sh', |
| '-i', "${project.projectDir}/tests/wpi-many/testin.txt", |
| '-o', "${project.projectDir}/build/wpi-many-tests", |
| '-s', |
| '--', '--checker', 'nullness,interning,lock,regex,signature' |
| } |
| } catch (Exception e) { |
| println("Failure: Running wpi-many.sh failed with a non-zero exit code.") |
| File wpiOut = new File("${typecheckFilesDir}/wpi-out") |
| if (wpiOut.exists()) { |
| println("========= Output from last run of wpi.sh (${typecheckFilesDir}/wpi-out): ========") |
| exec { |
| commandLine 'cat', "${typecheckFilesDir}/wpi-out" |
| } |
| println("========= End of output from last run of wpi.sh (${typecheckFilesDir}/wpi-out): ========") |
| throw e |
| } |
| } |
| // collect the logs from running WPI |
| def typecheckFiles = fileTree(typecheckFilesDir).matching { |
| include "**/*-typecheck.out" |
| } |
| if (typecheckFiles.size() == 0) { |
| println("Failure: No *-typecheck.out files in ${typecheckFilesDir}") |
| println("========= Output from last run of wpi.sh (${typecheckFilesDir}/wpi-out): ========") |
| exec { |
| commandLine 'cat', "${typecheckFilesDir}/wpi-out" |
| } |
| println("========= End of output from last run of wpi.sh (${typecheckFilesDir}/wpi-out): ========") |
| def logFiles = fileTree(typecheckFilesDir).matching { |
| include "**/*.log" |
| } |
| logFiles.visit { FileVisitDetails details -> |
| def filename = "${typecheckFilesDir}" + details.getName() |
| println("======== printing contents of ${filename} ========") |
| details.getFile().eachLine { line -> println(line) } |
| println("======== end of contents of ${filename} ========") |
| } |
| throw new GradleException("Failure: No *-typecheck.out files in ${project.projectDir}/build/wpi-many-tests-results/") |
| } |
| |
| // check that WPI causes the expected builds to succeed |
| typecheckFiles.visit { FileVisitDetails details -> |
| def filename = "${project.projectDir}/build/wpi-many-tests-results/" + details.getName() |
| def file = details.getFile() |
| if (file.length() == 0) { |
| throw new GradleException("Failure: WPI produced empty typecheck file " + filename) |
| } |
| file.eachLine { line -> |
| if ( |
| // Ignore the line that WPI echoes with the javac command being run. |
| line.startsWith("Running ") |
| // Warnings about bad path elements aren't related to WPI and are ignored. |
| || line.startsWith("warning: [path]") |
| // Ignore the summary line that reports the total number of warnings. |
| || line.endsWith("warnings")) { |
| return; |
| } |
| if (!line.trim().equals("")) { |
| throw new GradleException("Failure: WPI scripts produced an unexpected output in " + filename + ". " + |
| "Failing line is the following: " + line) |
| } |
| } |
| } |
| } |
| } |
| |
| // This is run as part of the inferenceTests task. |
| task wpiPlumeLibTests(group: "Verification") { |
| description 'Tests whole-program inference on the plume-lib projects. Requires an Internet connection.' |
| dependsOn(copyJarsToDist) |
| |
| // This test must always be re-run when requested. |
| outputs.upToDateWhen { false } |
| |
| doLast { |
| exec { |
| commandLine 'bin-devel/wpi-plumelib/test-wpi-plumelib.sh' |
| ignoreExitValue = false |
| } |
| } |
| } |
| |
| apply from: rootProject.file("gradle-mvn-push.gradle") |
| |
| /** Adds information to the publication for uploading to Maven repositories. */ |
| final checkerPom(publication) { |
| sharedPublicationConfiguration(publication) |
| // Don't use publication.from components.java which would publish the skinny jar as checker.jar. |
| publication.pom { |
| name = 'Checker Framework' |
| description = 'The Checker Framework enhances Java\'s type system to\n' + |
| 'make it more powerful and useful. This lets software developers\n' + |
| 'detect and prevent errors in their Java programs.\n' + |
| 'The Checker Framework includes compiler plug-ins ("checkers")\n' + |
| 'that find bugs or verify their absence. It also permits you to\n' + |
| 'write your own compiler plug-ins.' |
| licenses { |
| license { |
| name = 'GNU General Public License, version 2 (GPL2), with the classpath exception' |
| url = 'http://www.gnu.org/software/classpath/license.html' |
| distribution = 'repo' |
| } |
| } |
| } |
| } |
| publishing { |
| publications { |
| checker(MavenPublication) { |
| project.shadow.component it |
| checkerPom it |
| artifact checkerJar |
| artifact allSourcesJar |
| artifact allJavadocJar |
| } |
| } |
| } |
| signing { |
| sign publishing.publications.checker |
| } |