Skip to content

Commit

Permalink
Merge pull request #563 from benkard/mulk/feature/google-java-format-1.8
Browse files Browse the repository at this point in the history
Support google-java-format 1.8+
  • Loading branch information
nedtwigg authored May 3, 2020
2 parents 608af5c + 0104f6d commit de2d9b6
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 31 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: java
jdk:
- openjdk8
- openjdk11
env:
- NODE_VERSION="6.10.2"
before_install:
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Support for google-java-format 1.8 (including test infrastructure for Java 11). ([#562](https://github.com/diffplug/spotless/issues/562))

## [1.28.1] - 2020-04-02
### Fixed
Expand Down
1 change: 1 addition & 0 deletions gradle/java-publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ task sourcesJar(type: Jar) {
// Thus, no javadoc warnings.
javadoc {
options.addStringOption('Xdoclint:none', '-quiet')
enabled = org.gradle.api.JavaVersion.current() == org.gradle.api.JavaVersion.VERSION_1_8
}

// use markdown in javadoc
Expand Down
2 changes: 2 additions & 0 deletions gradle/java-setup.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ spotbugs {
}
// HTML instead of XML
tasks.withType(spotBugsTaskType()) {
// only run on Java 8 (no benefit to running twice)
enabled = org.gradle.api.JavaVersion.current() == org.gradle.api.JavaVersion.VERSION_1_8
reports {
xml.enabled = false
html.enabled = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.diffplug.spotless.JarState;
import com.diffplug.spotless.LineEnding;
import com.diffplug.spotless.Provisioner;
import com.diffplug.spotless.ThrowingEx.Function;

/** Wraps up [google-java-format](https://github.com/google/google-java-format) as a FormatterStep. */
public class GoogleJavaFormatStep {
Expand Down Expand Up @@ -124,17 +125,14 @@ FormatterFunc createFormat() throws Exception {
Object formatter = formatterClazz.getConstructor(optionsClass).newInstance(options);
Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class);

Class<?> removeUnusedClass = classLoader.loadClass(REMOVE_UNUSED_CLASS);
Class<?> removeJavadocOnlyClass = classLoader.loadClass(REMOVE_UNUSED_IMPORT_JavadocOnlyImports);
Object removeJavadocConstant = Enum.valueOf((Class<Enum>) removeJavadocOnlyClass, REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep);
Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class, removeJavadocOnlyClass);
Function<String, String> removeUnused = constructRemoveUnusedFunction(classLoader);

Class<?> importOrdererClass = classLoader.loadClass(IMPORT_ORDERER_CLASS);
Method importOrdererMethod = importOrdererClass.getMethod(IMPORT_ORDERER_METHOD, String.class);

return input -> {
String formatted = (String) formatterMethod.invoke(formatter, input);
String removedUnused = (String) removeUnusedMethod.invoke(null, formatted, removeJavadocConstant);
String removedUnused = removeUnused.apply(formatted);
String sortedImports = (String) importOrdererMethod.invoke(null, removedUnused);
return fixWindowsBug(sortedImports, version);
};
Expand All @@ -144,15 +142,33 @@ FormatterFunc createFormat() throws Exception {
FormatterFunc createRemoveUnusedImportsOnly() throws Exception {
ClassLoader classLoader = jarState.getClassLoader();

Function<String, String> removeUnused = constructRemoveUnusedFunction(classLoader);

return input -> fixWindowsBug(removeUnused.apply(input), version);
}

private static Function<String, String> constructRemoveUnusedFunction(ClassLoader classLoader)
throws NoSuchMethodException, ClassNotFoundException {
Class<?> removeUnusedClass = classLoader.loadClass(REMOVE_UNUSED_CLASS);
Class<?> removeJavadocOnlyClass = classLoader.loadClass(REMOVE_UNUSED_IMPORT_JavadocOnlyImports);
Object removeJavadocConstant = Enum.valueOf((Class<Enum>) removeJavadocOnlyClass, REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep);
Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class, removeJavadocOnlyClass);
Class<?> removeJavadocOnlyClass;
try {
// google-java-format 1.7 or lower
removeJavadocOnlyClass = classLoader.loadClass(REMOVE_UNUSED_IMPORT_JavadocOnlyImports);
} catch (ClassNotFoundException e) {
// google-java-format 1.8+
removeJavadocOnlyClass = null;
}

return input -> {
String removeUnused = (String) removeUnusedMethod.invoke(null, input, removeJavadocConstant);
return fixWindowsBug(removeUnused, version);
};
Function<String, String> removeUnused;
if (removeJavadocOnlyClass != null) {
Object removeJavadocConstant = Enum.valueOf((Class<Enum>) removeJavadocOnlyClass, REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep);
Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class, removeJavadocOnlyClass);
removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x, removeJavadocConstant);
} else {
Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class);
removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x);
}
return removeUnused;
}
}

Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]

## [3.28.1] - 2020-04-02
### Added
* Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562))
### Fixed
* Eclipse-WTP formatter (web tools platform, not java) handles some character encodings incorrectly on OS with non-unicode default file encoding [#545](https://github.com/diffplug/spotless/issues/545). Fixed for Eclipse-WTP formatter Eclipse version 4.13.0 (default version).

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright 2016 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.diffplug.gradle.spotless;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.assertj.core.api.Assertions;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Test;

import com.diffplug.common.base.CharMatcher;
import com.diffplug.common.base.Splitter;
import com.diffplug.common.base.StringPrinter;
import com.diffplug.spotless.JreVersion;
import com.diffplug.spotless.LineEnding;

/** Tests the desired behavior from https://github.com/diffplug/spotless/issues/46. */
public class ErrorShouldRethrowJre11 extends GradleIntegrationTest {
private void writeBuild(String... toInsert) throws IOException {
List<String> lines = new ArrayList<>();
lines.add("plugins {");
lines.add(" id 'com.diffplug.gradle.spotless'");
lines.add(" id 'java'");
lines.add("}");
lines.add("spotless {");
lines.add(" format 'misc', {");
lines.add(" lineEndings 'UNIX'");
lines.add(" target file('README.md')");
lines.add(" custom 'no swearing', {");
lines.add(" if (it.toLowerCase(Locale.ROOT).contains('fubar')) {");
lines.add(" throw new RuntimeException('No swearing!');");
lines.add(" }");
lines.add(" }");
lines.addAll(Arrays.asList(toInsert));
setFile("build.gradle").toContent(String.join("\n", lines));
}

@Test
public void passesIfNoException() throws Exception {
writeBuild(
" } // format",
"} // spotless");
setFile("README.md").toContent("This code is fun.");
runWithSuccess("> Task :spotlessMisc");
}

@Test
public void anyExceptionShouldFail() throws Exception {
writeBuild(
" } // format",
"} // spotless");
setFile("README.md").toContent("This code is fubar.");
runWithFailure(
"> Task :spotlessMisc FAILED\n" +
"Step 'no swearing' found problem in 'README.md':\n" +
"No swearing!\n" +
"java.lang.RuntimeException: No swearing!\n");
}

@Test
public void unlessEnforceCheckIsFalse() throws Exception {
writeBuild(
" } // format",
" enforceCheck false",
"} // spotless");
setFile("README.md").toContent("This code is fubar.");
runWithSuccess("> Task :compileJava NO-SOURCE");
}

@Test
public void unlessExemptedByStep() throws Exception {
writeBuild(
" ignoreErrorForStep 'no swearing'",
" } // format",
"} // spotless");
setFile("README.md").toContent("This code is fubar.");
runWithSuccess("> Task :spotlessMisc\n" +
"Unable to apply step 'no swearing' to 'README.md'");
}

@Test
public void unlessExemptedByPath() throws Exception {
writeBuild(
" ignoreErrorForPath 'README.md'",
" } // format",
"} // spotless");
setFile("README.md").toContent("This code is fubar.");
runWithSuccess("> Task :spotlessMisc",
"Unable to apply step 'no swearing' to 'README.md'");
}

@Test
public void failsIfNeitherStepNorFileExempted() throws Exception {
writeBuild(
" ignoreErrorForStep 'nope'",
" ignoreErrorForPath 'nope'",
" } // format",
"} // spotless");
setFile("README.md").toContent("This code is fubar.");
runWithFailure("> Task :spotlessMisc FAILED\n" +
"Step 'no swearing' found problem in 'README.md':\n" +
"No swearing!\n" +
"java.lang.RuntimeException: No swearing!\n");
}

private void runWithSuccess(String... messages) throws Exception {
if (JreVersion.thisVm() != JreVersion._11) {
return;
}
BuildResult result = gradleRunner().withArguments("check").build();
assertResultAndMessages(result, TaskOutcome.SUCCESS, messages);
}

private void runWithFailure(String... messages) throws Exception {
if (JreVersion.thisVm() != JreVersion._11) {
return;
}
BuildResult result = gradleRunner().withArguments("check").buildAndFail();
assertResultAndMessages(result, TaskOutcome.FAILED, messages);
}

private void assertResultAndMessages(BuildResult result, TaskOutcome outcome, String... messages) {
String expectedToStartWith = StringPrinter.buildStringFromLines(messages).trim();
int numNewlines = CharMatcher.is('\n').countIn(expectedToStartWith);
List<String> actualLines = Splitter.on('\n').splitToList(LineEnding.toUnix(result.getOutput().trim()));
String actualStart = String.join("\n", actualLines.subList(0, numNewlines + 1));
Assertions.assertThat(actualStart).isEqualTo(expectedToStartWith);
Assertions.assertThat(result.tasks(outcome).size() + result.tasks(TaskOutcome.UP_TO_DATE).size() + result.tasks(TaskOutcome.NO_SOURCE).size())
.isEqualTo(result.getTasks().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
import com.diffplug.common.base.CharMatcher;
import com.diffplug.common.base.Splitter;
import com.diffplug.common.base.StringPrinter;
import com.diffplug.spotless.JreVersion;
import com.diffplug.spotless.LineEnding;

/** Tests the desired behavior from https://github.com/diffplug/spotless/issues/46. */
public class ErrorShouldRethrow extends GradleIntegrationTest {
public class ErrorShouldRethrowJre8 extends GradleIntegrationTest {
private void writeBuild(String... toInsert) throws IOException {
List<String> lines = new ArrayList<>();
lines.add("plugins {");
Expand Down Expand Up @@ -119,11 +120,17 @@ public void failsIfNeitherStepNorFileExempted() throws Exception {
}

private void runWithSuccess(String... messages) throws Exception {
if (JreVersion.thisVm() != JreVersion._8) {
return;
}
BuildResult result = gradleRunner().withArguments("check").build();
assertResultAndMessages(result, TaskOutcome.SUCCESS, messages);
}

private void runWithFailure(String... messages) throws Exception {
if (JreVersion.thisVm() != JreVersion._8) {
return;
}
BuildResult result = gradleRunner().withArguments("check").buildAndFail();
assertResultAndMessages(result, TaskOutcome.FAILED, messages);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.diffplug.common.base.StringPrinter;
import com.diffplug.common.tree.TreeDef;
import com.diffplug.common.tree.TreeStream;
import com.diffplug.spotless.JreVersion;
import com.diffplug.spotless.LineEnding;
import com.diffplug.spotless.ResourceHarness;

Expand All @@ -56,11 +57,25 @@ public void gitAttributes() throws IOException {
setFile(".gitattributes").toContent("* text eol=lf");
}

/**
* For Java 11+, Gradle 5 is the minimum.
* So if you ask for less than Gradle 5, you get it on Java 8, but on Java 11 you get promoted to Gradle 5.
* If you ask for more than Gradle 5, you'll definitely get it.
*/
protected static String requestGradleForJre8and11(String ver) {
JreVersion jre = JreVersion.thisVm();
// @formatter:off
switch (jre) {
case _8: return ver;
case _11: return Double.parseDouble(ver) < 5.0 ? "5.0" : ver;
default: throw new IllegalStateException("Spotless build is only supported on Java 8 and Java 11");
}
// @formatter:on
}

protected final GradleRunner gradleRunner() throws IOException {
return GradleRunner.create()
// Test against Gradle 2.14.1 in order to maintain backwards compatibility.
// https://github.com/diffplug/spotless/issues/161
.withGradleVersion("2.14.1")
.withGradleVersion(requestGradleForJre8and11("2.14"))
.withProjectDir(rootFolder())
.withPluginClasspath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void testWithCommonInterfaceForConfiguringLicences() throws IOException {
" }",
"}");
gradleRunner()
.withGradleVersion("4.6")
.withGradleVersion(requestGradleForJre8and11("4.6")) // 4.6 is the min
.withArguments("spotlessApply")
.forwardOutput()
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.assertj.core.api.Assertions;
import org.junit.Test;

import com.diffplug.spotless.JreVersion;

public class RegisterDependenciesTaskTest extends GradleIntegrationTest {
@Test
public void registerDependencies() throws IOException {
Expand All @@ -38,16 +40,18 @@ public void registerDependencies() throws IOException {
" }",
"}");

String oldestSupported = gradleRunner()
.withArguments("spotlessCheck").build().getOutput();
Assertions.assertThat(oldestSupported.replace("\r", "")).startsWith(
":spotlessCheck UP-TO-DATE\n" +
":spotlessInternalRegisterDependencies\n" +
":sub:spotlessJava\n" +
":sub:spotlessJavaCheck\n" +
":sub:spotlessCheck\n" +
"\n" +
"BUILD SUCCESSFUL");
if (JreVersion.thisVm() == JreVersion._8) {
String oldestSupported = gradleRunner()
.withArguments("spotlessCheck").build().getOutput();
Assertions.assertThat(oldestSupported.replace("\r", "")).startsWith(
":spotlessCheck UP-TO-DATE\n" +
":spotlessInternalRegisterDependencies\n" +
":sub:spotlessJava\n" +
":sub:spotlessJavaCheck\n" +
":sub:spotlessCheck\n" +
"\n" +
"BUILD SUCCESSFUL");
}

setFile("gradle.properties").toLines();
String newestSupported = gradleRunner().withGradleVersion("6.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void integration(String patterns,
GradleRunner runner = gradleRunner()
.withArguments("spotlessApply", "-PspotlessFiles=" + patterns);
if (isKotlin) {
runner.withGradleVersion("4.0");
runner.withGradleVersion(requestGradleForJre8and11("4.0"));
}
runner.build();

Expand Down
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [1.30.0] - 2020-04-10
### Added
* Support for prettier ([#555](https://github.com/diffplug/spotless/pull/555)).
* Support for google-java-format 1.8 (requires you to run build on Java 11) ([#562](https://github.com/diffplug/spotless/issues/562))

## [1.29.0] - 2020-04-02
### Added
Expand Down
Loading

0 comments on commit de2d9b6

Please sign in to comment.