diff --git a/README.md b/README.md index dd0f5b76f..d51402668 100644 --- a/README.md +++ b/README.md @@ -298,11 +298,15 @@ spotless { importOrder '' trimTrailingWhitespace indentWithSpaces 4 - endWithNewline + + // only enabled if you run `./gradlew format -Pcom.palantir.baseline-format.eclipse` + eclipse().configFile "$rootDir/.baseline/eclipse.xml" } } ``` +We chose the Eclipse formatter because it can be run from the command line and from both IDEs (IntelliJ using the [Eclipse Code Formatter](https://plugins.jetbrains.com/plugin/6546-eclipse-code-formatter) plugin). + ## com.palantir.baseline-reproducibility This plugin is a shorthand for the following snippet, which opts-in to reproducible behaviour for all Gradle's Jar, Tar and Zip tasks. (Surprisingly, these tasks are not reproducible by default). diff --git a/changelog/@unreleased/pr-707.v2.yml b/changelog/@unreleased/pr-707.v2.yml new file mode 100644 index 000000000..f2d58f339 --- /dev/null +++ b/changelog/@unreleased/pr-707.v2.yml @@ -0,0 +1,7 @@ +type: improvement +improvement: + description: > + Baseline can now re-format all your Java files using the Eclipse formatter. + This is currently an opt-in preview, try it out by running `./gradlew format -Pcom.palantir.baseline-format.eclipse`. + links: + - https://github.com/palantir/gradle-baseline/pull/707 diff --git a/gradle-baseline-java-config/resources/spotless/eclipse.xml b/gradle-baseline-java-config/resources/spotless/eclipse.xml new file mode 100644 index 000000000..054985988 --- /dev/null +++ b/gradle-baseline-java-config/resources/spotless/eclipse.xml @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineConfig.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineConfig.java index 77bcbba57..4eca336a3 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineConfig.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineConfig.java @@ -74,6 +74,10 @@ public void execute(Task task) { copySpec.into(BaselineConfig.this.getConfigDir()); copySpec.exclude("**/scalastyle_config.xml"); copySpec.setIncludeEmptyDirs(false); + + if (!BaselineFormat.eclipseFormattingEnabled(task.getProject())) { + copySpec.exclude("**/spotless/eclipse.xml"); + } }); if (rootProject .getAllprojects() diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineFormat.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineFormat.java index d3873a75f..cd3b5e579 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineFormat.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineFormat.java @@ -17,6 +17,9 @@ package com.palantir.baseline.plugins; import com.diffplug.gradle.spotless.SpotlessExtension; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.ConfigurableFileCollection; @@ -25,9 +28,15 @@ class BaselineFormat extends AbstractBaselinePlugin { + // TODO(dfox): remove this feature flag when we've refined the eclipse.xml sufficiently + private static final String ECLIPSE_FORMATTING = "com.palantir.baseline-format.eclipse"; + @Override public void apply(Project project) { this.project = project; + + Path eclipseXml = Paths.get(getConfigDir(), "spotless/eclipse.xml"); + project.getPluginManager().withPlugin("java", plugin -> { project.getPluginManager().apply("com.diffplug.gradle.spotless"); @@ -46,18 +55,17 @@ public void apply(Project project) { // use empty string to specify one group for all non-static imports java.importOrder(""); java.trimTrailingWhitespace(); - java.indentWithSpaces(4); - java.endWithNewline(); - // No empty lines at start of blocks - java.replaceRegex("Block starts with blank lines", "\\) \\{\n+", ") {\n"); - - // No dangling parentheses - closing paren must be on the same line as the expression - java.replaceRegex("Dangling closing parenthesis", "(\n\\s+)+\\)", ")"); + if (eclipseFormattingEnabled(project)) { + java.eclipse().configFile(project.file(eclipseXml.toString())); + } }); // necessary because SpotlessPlugin creates tasks in an afterEvaluate block Task formatTask = project.task("format"); + if (eclipseFormattingEnabled(project) && !Files.exists(eclipseXml)) { + formatTask.dependsOn(project.getTasks().findByPath(":baselineUpdateConfig")); + } project.afterEvaluate(p -> { Task spotlessApply = project.getTasks().getByName("spotlessApply"); formatTask.dependsOn(spotlessApply); @@ -65,4 +73,8 @@ public void apply(Project project) { }); }); } + + static boolean eclipseFormattingEnabled(Project project) { + return project.hasProperty(ECLIPSE_FORMATTING); + } } diff --git a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineConfigIntegrationTest.groovy b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineConfigIntegrationTest.groovy index 290941f71..06d9886c6 100644 --- a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineConfigIntegrationTest.groovy +++ b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineConfigIntegrationTest.groovy @@ -22,7 +22,7 @@ import org.gradle.testkit.runner.TaskOutcome * This test relies on running ./gradlew :gradle-baseline-java-config:publishToMavenLocal. */ class BaselineConfigIntegrationTest extends AbstractPluginTest { - def projectVersion = "git describe --tags --first-parent --dirty=.dirty".execute().text.trim() + def projectVersion = "git describe --tags --first-parent --dirty=.dirty --abbrev=7".execute().text.trim() def standardBuildFile = """ plugins { id 'com.palantir.baseline-config' @@ -45,8 +45,10 @@ class BaselineConfigIntegrationTest extends AbstractPluginTest { """.stripIndent() then: - with('--stacktrace', '--info', 'baselineUpdateConfig').build() - directory('.baseline').list().toList().toSet() == ['checkstyle', 'copyright', 'eclipse', 'idea'].toSet() + with('--stacktrace', '--info', 'baselineUpdateConfig', '-Pcom.palantir.baseline-format.eclipse').build() + directory('.baseline').list().toList().toSet() == [ + 'checkstyle', 'copyright', 'eclipse', 'idea', 'spotless' + ].toSet() directory('project').list().toList().isEmpty() } @@ -65,7 +67,9 @@ class BaselineConfigIntegrationTest extends AbstractPluginTest { then: with('--stacktrace', '--info', 'baselineUpdateConfig').build() - directory('.baseline').list().toList().toSet() == ['checkstyle', 'copyright', 'eclipse', 'idea'].toSet() + directory('.baseline').list().toList().toSet() == [ + 'checkstyle', 'copyright', 'eclipse', 'idea' + ].toSet() directory('project').list().toList().toSet() == ['scalastyle_config.xml'].toSet() } diff --git a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatIntegrationTest.groovy b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatIntegrationTest.groovy index 40b3db4f8..26f9c43e2 100644 --- a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatIntegrationTest.groovy +++ b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatIntegrationTest.groovy @@ -16,11 +16,18 @@ package com.palantir.baseline +import org.apache.commons.io.FileUtils import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.TaskOutcome class BaselineFormatIntegrationTest extends AbstractPluginTest { + def setup() { + FileUtils.copyDirectory( + new File("../gradle-baseline-java-config/resources"), + new File(projectDir, ".baseline")) + } + def standardBuildFile = ''' plugins { id 'java' @@ -36,23 +43,23 @@ class BaselineFormatIntegrationTest extends AbstractPluginTest { def validJavaFile = ''' package test; - public class Test { void test() { - int x = 1; - System.out.println( - "Hello"); - Optional.of("hello").orElseGet(() -> { - return "Hello World"; - }); - } } + + public class Test { + void test() { + int x = 1; + System.out.println( + "Hello"); + Optional.of("hello").orElseGet(() -> { + return "Hello World"; + }); + } + } '''.stripIndent() def invalidJavaFile = ''' package test; import com.java.unused; - public class Test { void test() { - - - int x = 1; + public class Test { void test() {int x = 1; System.out.println( "Hello" ); @@ -84,7 +91,7 @@ class BaselineFormatIntegrationTest extends AbstractPluginTest { file('src/main/java/test/Test.java') << invalidJavaFile then: - BuildResult result = with('format').build(); + BuildResult result = with('format', '-Pcom.palantir.baseline-format.eclipse').build(); result.task(":format").outcome == TaskOutcome.SUCCESS result.task(":spotlessApply").outcome == TaskOutcome.SUCCESS file('src/main/java/test/Test.java').text == validJavaFile @@ -99,7 +106,7 @@ class BaselineFormatIntegrationTest extends AbstractPluginTest { file('src/foo/java/test/Test.java') << invalidJavaFile then: - BuildResult result = with('format').build() + BuildResult result = with('format', '-Pcom.palantir.baseline-format.eclipse').build() result.task(":format").outcome == TaskOutcome.SUCCESS result.task(":spotlessApply").outcome == TaskOutcome.SUCCESS file('src/foo/java/test/Test.java').text == validJavaFile @@ -115,7 +122,7 @@ class BaselineFormatIntegrationTest extends AbstractPluginTest { file('src/foo/groovy/test/Test.java') << invalidJavaFile then: - BuildResult result = with('format').build() + BuildResult result = with('format', '-Pcom.palantir.baseline-format.eclipse').build() result.task(":format").outcome == TaskOutcome.SUCCESS result.task(":spotlessApply").outcome == TaskOutcome.SUCCESS file('src/foo/groovy/test/Test.java').text == validJavaFile diff --git a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatTest.groovy b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatTest.groovy index 73b8bbd41..563d452c3 100644 --- a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatTest.groovy +++ b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineFormatTest.groovy @@ -28,6 +28,11 @@ class BaselineFormatTest extends Specification { def setup() { project = ProjectBuilder.builder().build() + project.buildscript { + repositories { + mavenCentral() + } + } project.plugins.apply 'java' project.plugins.apply BaselineFormat project.evaluate()