Skip to content

Commit

Permalink
Use Spotless for code formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mernst authored Sep 20, 2022
1 parent eb72335 commit 15f7719
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 162 deletions.
147 changes: 0 additions & 147 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ ext {
stubparser = "${parentDir}/stubparser"
stubparserJar = "${stubparser}/javaparser-core/target/stubparser-3.24.3.jar"

formatScriptsHome = "${project(':checker').projectDir}/bin-devel/.run-google-java-format"
plumeScriptsHome = "${project(':checker').projectDir}/bin-devel/.plume-scripts"
htmlToolsHome = "${project(':checker').projectDir}/bin-devel/.html-tools"

Expand Down Expand Up @@ -457,74 +456,6 @@ def createCheckTypeTask(projectName, taskName, checker, args = []) {
}
}

/**
* Returns a list of all the Java files that should be formatted for the given project. These are:
*
* All Java files in the main sourceSet.
* All Java files in the tests directory that compile.
*
* @param projectName name of the project to format
* @return a list of all Java files that should be formatted for projectName
*/
List<String> getJavaFilesToFormat(projectName) {
List<File> javaFiles = new ArrayList<>();
project(':' + projectName).sourceSets.forEach { set ->
javaFiles.addAll(set.java.files)
}

// Collect all Java files in tests directory
fileTree("${project(projectName).projectDir}/tests").visit { details ->
// If you change this, also change checker/bin-devel/git.pre-commit
if (!details.path.contains("nullness-javac-errors")
&& !details.path.contains("calledmethods-delomboked")
&& !details.path.contains("returnsreceiverdelomboked")
&& !details.path.contains("build")
&& (isJava17compatible || !details.path.contains("-records"))
&& (isJava17compatible || !details.path.contains("java17"))
&& details.name.endsWith('.java')) {
javaFiles.add(details.file)
}
}

// Collect all Java files in jtreg directory
fileTree("${project(projectName).projectDir}/jtreg").visit { details ->
if (!details.path.contains("nullness-javac-errors") && details.name.endsWith('.java')) {
javaFiles.add(details.file)
}
}

// Collect all Java files in jtregJdk11 directory
fileTree("${project(projectName).projectDir}/jtregJdk11").visit { details ->
if (!details.path.contains("nullness-javac-errors") && details.name.endsWith('.java')) {
javaFiles.add(details.file)
}
}

List<String> args = new ArrayList<>(javaFiles.size());
for (File f : javaFiles) {
args += project(projectName).relativePath(f)
}
return args
}

task writeListOfJavaFilesToFormat(group: 'Format') {
description "Writes a list of Java files subject to formatting, to ${buildDir}/javafiles.txt"
doLast {
mkdir buildDir
File list = new File("${buildDir}/javafiles.txt");
list.createNewFile();
FileWriter fileWriter = new FileWriter(list)
subprojects.forEach {
if (!it.name.startsWith("checker-qual-android")) {
for (String fileName : getJavaFilesToFormat(it.name)) {
fileWriter.write(fileName)
fileWriter.write(System.lineSeparator())
}
}
}
}
}

task htmlValidate(type: Exec, group: 'Format') {
description 'Validate that HTML files are well-formed'
executable 'html5validator'
Expand Down Expand Up @@ -635,43 +566,6 @@ task manual(group: 'Documentation') {
}
}

// See alternate implementation getCodeFormatScriptsInGradle below.
// No group so it does not show up in the output of `gradlew tasks`
task getCodeFormatScripts() {
description 'Obtain or update the run-google-java-format scripts'
if (file(formatScriptsHome).exists()) {
exec {
workingDir formatScriptsHome
executable 'git'
args = ['pull', '-q']
ignoreExitValue = true
}
} else {
exec {
workingDir "${formatScriptsHome}/../"
executable 'git'
args = ['clone', '-q', '--depth', '1', 'https://github.com/plume-lib/run-google-java-format.git', '.run-google-java-format']
}
}
}

// This implementation is preferable to the above because it does work in Gradle rather than in bash.
// However, it fails in the presence of worktrees: https://github.com/ajoberstar/grgit/issues/97 .
// No group so it does not show up in the output of `gradlew tasks`
task getCodeFormatScriptsInGradle {
description "Obtain the run-google-java-format scripts"
doLast {
if (! new File(formatScriptsHome).exists()) {
// There is no support for the --depth argument:
// https://github.com/ajoberstar/grgit/issues/155 https://bugs.eclipse.org/bugs/show_bug.cgi?id=475615
def rgjfGit = Grgit.clone(dir: formatScriptsHome, uri: 'https://github.com/plume-lib/run-google-java-format.git')
} else {
def rgjfGit = Grgit.open(dir: formatScriptsHome)
rgjfGit.pull()
}
}
}

// No group so it does not show up in the output of `gradlew tasks`
task getPlumeScripts() {
description 'Obtain or update plume-scripts'
Expand Down Expand Up @@ -753,46 +647,6 @@ subprojects {
}
}

task checkFormat(type: Exec, dependsOn: [getCodeFormatScripts, pythonIsInstalled], group: 'Format') {
description 'Check whether the source code is properly formatted'
// checker-qual-android project has no source, so skip
onlyIf {!project.name.startsWith('checker-qual-android') }
executable 'python3'

doFirst {
if (isJava8) {
println 'The checkFormat task cannot be run on Java 8. Please use Java 11+.'
return
}
args += "${formatScriptsHome}/check-google-java-format.py"
args += getJavaFilesToFormat(project.name)
// Since the scripts are downloaded from third-party Github, the environment variable
// is the only way to add the necessary open:
environment('JDK_JAVA_OPTIONS', '--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED')
}
ignoreExitValue = true
doLast {
if (!executionResult.isPresent() || executionResult.get().getExitValue() != 0) {
throw new RuntimeException('Found improper formatting, try running: ./gradlew reformat"')
}
}
}

task reformat(type: Exec, dependsOn: [getCodeFormatScripts, pythonIsInstalled], group: 'Format') {
description 'Format the Java source code'
// checker-qual-android project has no source, so skip
onlyIf {!project.name.startsWith('checker-qual-android') }
executable 'python3'
doFirst {
if (isJava8) {
println 'The reformat task cannot be run on Java 8. Please use Java 11+.'
return
}
args += "${formatScriptsHome}/run-google-java-format.py"
args += getJavaFilesToFormat(project.name)
}
}

shadowJar {
// If you add an external dependency, then do the following:
// 1. Before adding the dependency, run ./gradlew copyJarsToDist.
Expand Down Expand Up @@ -1082,7 +936,6 @@ task checkBasicStyle(group: 'Format') {
'.html-tools',
'.idea',
'.plume-scripts',
'.run-google-java-format',
'annotated',
'api',
'plume-bib',
Expand Down
15 changes: 4 additions & 11 deletions checker/bin-devel/git.pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,13 @@
# Fail if any command fails
set -e

# On commit we only need to check files that changed.
# Need to keep checked files in sync with getJavaFilesToFormat in build.gradle.
# Otherwise `./gradlew reformat` might not reformat a file that this
# hook complains about.
# Check formatting. This is slow (3+ seconds).
# Could instead do "spotlessApply", but then the changes don't appear in this commit.
./gradlew spotlessCheck -q

CHANGED_JAVA_FILES=$(git diff --staged --name-only --diff-filter=ACM | grep '\.java$' | grep -v '/jdk/' | grep -v 'stubparser/' | grep -v '/nullness-javac-errors/' | grep -v 'dataflow/manual/examples/' | grep -v '/java17/' | grep -v 'records/') || true
# echo "CHANGED_JAVA_FILES=${CHANGED_JAVA_FILES}"
if [ -n "$CHANGED_JAVA_FILES" ]; then
./gradlew getCodeFormatScripts -q
## For debugging:
# echo "CHANGED_JAVA_FILES: ${CHANGED_JAVA_FILES}"

# shellcheck disable=SC2086
python3 checker/bin-devel/.run-google-java-format/check-google-java-format.py ${CHANGED_JAVA_FILES} || (echo "Problem in pre-commit. Try running: ./gradlew reformat" && /bin/false)

BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" = "master" ]; then
git diff --staged > /tmp/diff.txt
Expand Down
2 changes: 1 addition & 1 deletion checker/bin-devel/test-misc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PLUME_SCRIPTS="$SCRIPTDIR/.plume-scripts"
status=0

## Code style and formatting
./gradlew checkBasicStyle checkFormat --console=plain --warning-mode=all
./gradlew checkBasicStyle spotlessCheck --console=plain --warning-mode=all
if grep -n -r --exclude-dir=build --exclude-dir=examples --exclude-dir=jtreg --exclude-dir=tests --exclude="*.astub" --exclude="*.tex" '^\(import static \|import .*\*;$\)'; then
echo "Don't use static import or wildcard import"
exit 1
Expand Down
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Deprecated `TreeUtils.constructor()` in favor of `TreeUtils.elementFromUse()`.
Use `TreeUtils.elementFromDeclaration` and `TreeUtils.elementFromUse` in
preference to `TreeUtils.elementFromTree`, when possible.

Use Spotless for formatting; the relevant commands are `./gradlew spotlessCheck`
and `./gradlew spotlessApply`.

**Closed issues:**


Expand Down
5 changes: 3 additions & 2 deletions docs/developer/developer-manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ <h2 id="Build_tasks">Build tasks</h2>
<li> <code>build</code>: <code>assemble</code>, plus runs all JUnit tests.
<li> <code>copyJarsToDist</code>: builds only the jars required to use checker/bin/javac; faster than assemble.
<li> <code>allTests</code>: runs all tests.
<li> <code>reformat</code>: reformats Java files.
<li> <code>spotlessApply</code>: reformats Java files.
<li> <code>spotlessCheck</code>: checks formatting of Java files.
<li> <code>NameOfJUnitTest</code>: runs the JUnit test with that name; for example, <code>NullnessTest</code>.
<li> <code>task</code>: lists tasks; use <code>--all</code> to see all tasks.
</ul>
Expand Down Expand Up @@ -191,7 +192,7 @@ <h2 id="code-style">Code style</h2>
</p>

<p>
From the command line, you can format your code by running <code>./gradlew reformat</code>.
From the command line, you can format your code by running <code>./gradlew spotlessApply</code>.
You
can <a href="https://github.com/google/google-java-format#using-the-formatter">configure
your IDE</a> (Eclipse or IntelliJ) to use the formatting.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ protected CheckerFrameworkWPIPerDirectoryTest(
* typechecked ends with. Usually, this takes the form "all-systems/ProblematicFile.java".
*/
protected void doNotTypecheck(
@UnderInitialization(CheckerFrameworkPerDirectoryTest.class) CheckerFrameworkWPIPerDirectoryTest this,
@UnderInitialization(CheckerFrameworkPerDirectoryTest.class) CheckerFrameworkWPIPerDirectoryTest this,
String endswith) {
int removeIndex = -1;
for (int i = 0; i < testFiles.size(); i++) {
Expand Down

0 comments on commit 15f7719

Please sign in to comment.