Skip to content

Commit

Permalink
Add support for palantir-java-format (#1083 implements #1076)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Jan 12, 2022
2 parents bb27596 + f4db9e0 commit c66f83e
Show file tree
Hide file tree
Showing 24 changed files with 545 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
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
* Added support for the [palantir-java-format](https://github.com/palantir/palantir-java-format) Java formatter ([#1083](https://github.com/diffplug/spotless/pull/1083)).

## [2.21.2] - 2022-01-07
### Fixed
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -58,6 +58,7 @@ extra('cpp.EclipseFormatterStep') +'{{yes}} | {{yes}}
extra('groovy.GrEclipseFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.GoogleJavaFormatStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.ImportOrderStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.PalantirJavaFormatStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
extra('java.EclipseJdtFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
Expand Down Expand Up @@ -98,6 +99,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}}
| [`groovy.GrEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.ImportOrderStep`](lib/src/main/java/com/diffplug/spotless/java/ImportOrderStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.PalantirJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/PalantirJavaFormatStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`java.RemoveUnusedImportsStep`](lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.EclipseJdtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
Expand Down
3 changes: 3 additions & 0 deletions gradle.properties
@@ -1,3 +1,6 @@
# To fix metaspace errors
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

name=spotless
description=Spotless - keep your code spotless with Gradle
org=diffplug
Expand Down
3 changes: 3 additions & 0 deletions lib/build.gradle
Expand Up @@ -8,6 +8,7 @@ apply from: rootProject.file('gradle/java-publish.gradle')

def NEEDS_GLUE = [
'sortPom',
'palantirJavaFormat',
'ktlint',
'flexmark'
]
Expand All @@ -29,6 +30,8 @@ dependencies {
// used for pom sorting
sortPomCompileOnly 'com.github.ekryd.sortpom:sortpom-sorter:3.0.0'

palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0'

String VER_KTLINT='0.43.2'
ktlintCompileOnly "com.pinterest:ktlint:$VER_KTLINT"
ktlintCompileOnly "com.pinterest.ktlint:ktlint-core:$VER_KTLINT"
Expand Down
@@ -0,0 +1,74 @@
/*
* Copyright 2016-2022 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.spotless.java;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.Objects;

import com.diffplug.spotless.*;

/** Wraps up <a href="https://github.com/palantir/palantir-java-format">palantir-java-format</a> fork of
* <a href="https://github.com/google/google-java-format">google-java-format</a> as a FormatterStep. */
public class PalantirJavaFormatStep {
// prevent direct instantiation
private PalantirJavaFormatStep() {}

private static final String NAME = "palantir-java-format";
private static final String MAVEN_COORDINATE = "com.palantir.javaformat:palantir-java-format:";
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(8, "1.1.0").add(11, "2.10.0");

/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(Provisioner provisioner) {
return create(defaultVersion(), provisioner);
}

/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(String version, Provisioner provisioner) {
Objects.requireNonNull(version, "version");
Objects.requireNonNull(provisioner, "provisioner");

return FormatterStep.createLazy(NAME,
() -> new State(JarState.from(MAVEN_COORDINATE + version, provisioner), version),
State::createFormat);
}

/** Get default formatter version */
public static String defaultVersion() {
return JVM_SUPPORT.getRecommendedFormatterVersion();
}

private static final class State implements Serializable {
private static final long serialVersionUID = 1L;

/** The jar that contains the formatter. */
private final JarState jarState;
/** Version of the formatter jar. */
private final String formatterVersion;

State(JarState jarState, String formatterVersion) {
this.jarState = jarState;
this.formatterVersion = formatterVersion;
}

FormatterFunc createFormat() throws Exception {
final ClassLoader classLoader = jarState.getClassLoader();
final Class<?> formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.pjf.PalantirJavaFormatFormatterFunc");
final Constructor<?> constructor = formatterFunc.getConstructor();
return JVM_SUPPORT.suggestLaterVersionOnError(formatterVersion, (FormatterFunc) constructor.newInstance());
}
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2022 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.spotless.glue.pjf;

import com.palantir.javaformat.java.Formatter;
import com.palantir.javaformat.java.ImportOrderer;
import com.palantir.javaformat.java.JavaFormatterOptions;
import com.palantir.javaformat.java.RemoveUnusedImports;

import com.diffplug.spotless.FormatterFunc;

public class PalantirJavaFormatFormatterFunc implements FormatterFunc {

private final Formatter formatter;

public PalantirJavaFormatFormatterFunc() {
formatter = Formatter.createFormatter(JavaFormatterOptions.builder()
.style(JavaFormatterOptions.Style.PALANTIR)
.build());
}

@Override
public String apply(String input) throws Exception {
String source = input;
source = ImportOrderer.reorderImports(source, JavaFormatterOptions.Style.PALANTIR);
source = RemoveUnusedImports.removeUnusedImports(source);
return formatter.formatSource(source);
}

@Override
public String toString() {
return "PalantirJavaFormatFormatterFunc{formatter=" + formatter + '}';
}
}
1 change: 1 addition & 0 deletions plugin-gradle/CHANGES.md
Expand Up @@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Added
* 🎉🎉🎉 [**IntelliJ plugin**](https://plugins.jetbrains.com/plugin/18321-spotless-gradle) thanks to [@ragurney](https://github.com/ragurney) 🎉🎉🎉
* Added support for the [palantir-java-format](https://github.com/palantir/palantir-java-format) Java formatter ([#1083](https://github.com/diffplug/spotless/pull/1083)).

## [6.1.2] - 2022-01-07
### Fixed
Expand Down
28 changes: 27 additions & 1 deletion plugin-gradle/README.md
Expand Up @@ -60,7 +60,7 @@ Spotless supports all of Gradle's built-in performance features (incremental bui
- [**Quickstart**](#quickstart)
- [Requirements](#requirements)
- **Languages**
- [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [clang-format](#clang-format), [prettier](#prettier))
- [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [clang-format](#clang-format), [prettier](#prettier), [palantir-java-format](#palantir-java-format))
- [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy))
- [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [prettier](#prettier))
- [Scala](#scala) ([scalafmt](#scalafmt))
Expand Down Expand Up @@ -205,6 +205,32 @@ org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAME
```
This is a workaround to a [pending issue](https://github.com/diffplug/spotless/issues/834).

### palantir-java-format

[homepage](https://github.com/palantir/palantir-java-format). [changelog](https://github.com/palantir/palantir-java-format/releases).
```gradle
spotless {
java {
palantirJavaFormat()
// optional: you can specify a specific version
palantirJavaFormat('2.9.0')
```

**⚠️ Note on using Palantir Java Format with Java 16+**

Using Java 16+ with Palantir Java Format [requires additional flags](https://github.com/google/google-java-format/releases/tag/v1.10.0) on the running JDK.
These Flags can be provided using the `gradle.properties` file (See [documentation](https://docs.gradle.org/current/userguide/build_environment.html)).

For example the following file under `gradle.properties` will run maven with the required flags:
```
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
```
This is a workaround to a [pending issue](https://github.com/diffplug/spotless/issues/834).

### eclipse jdt

[homepage](https://www.eclipse.org/downloads/packages/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter). See [here](../ECLIPSE_SCREENSHOTS.md) for screenshots that demonstrate how to get and install the config file mentioned below.
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,6 +34,7 @@
import com.diffplug.spotless.generic.LicenseHeaderStep;
import com.diffplug.spotless.java.GoogleJavaFormatStep;
import com.diffplug.spotless.java.ImportOrderStep;
import com.diffplug.spotless.java.PalantirJavaFormatStep;
import com.diffplug.spotless.java.RemoveUnusedImportsStep;

public class JavaExtension extends FormatExtension implements HasBuiltinDelimiterForLicense {
Expand Down Expand Up @@ -175,6 +176,35 @@ private FormatterStep createStep() {
}
}

/** Uses the <a href="https://github.com/palantir/palantir-java-format">palantir-java-format</a> jar to format source code. */
public PalantirJavaFormatConfig palantirJavaFormat() {
return palantirJavaFormat(PalantirJavaFormatStep.defaultVersion());
}

/**
* Uses the given version of <a href="https://github.com/palantir/palantir-java-format">palantir-java-format</a> to format source code.
*
* Limited to published versions. See <a href="https://github.com/diffplug/spotless/issues/33#issuecomment-252315095">issue #33</a>
* for an workaround for using snapshot versions.
*/
public PalantirJavaFormatConfig palantirJavaFormat(String version) {
Objects.requireNonNull(version);
return new PalantirJavaFormatConfig(version);
}

public class PalantirJavaFormatConfig {
final String version;

PalantirJavaFormatConfig(String version) {
this.version = Objects.requireNonNull(version);
addStep(createStep());
}

private FormatterStep createStep() {
return PalantirJavaFormatStep.create(version, provisioner());
}
}

public EclipseConfig eclipse() {
return new EclipseConfig(EclipseJdtFormatterStep.defaultVersion());
}
Expand Down
@@ -0,0 +1,48 @@
/*
* Copyright 2022 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 org.junit.jupiter.api.Test;

class PalantirJavaFormatIntegrationTest extends GradleIntegrationHarness {
@Test
void integration() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"repositories { mavenCentral() }",
"",
"spotless {",
" java {",
" target file('test.java')",
" palantirJavaFormat('1.1.0')",
" }",
"}");

setFile("test.java").toResource("java/palantirjavaformat/JavaCodeUnformatted.test");
gradleRunner().withArguments("spotlessApply").build();
assertFile("test.java").sameAsResource("java/palantirjavaformat/JavaCodeFormatted.test");

checkRunsThenUpToDate();
replace("build.gradle",
"palantirJavaFormat('1.1.0')",
"palantirJavaFormat('1.0.1')");
checkRunsThenUpToDate();
}
}
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Added support for the [palantir-java-format](https://github.com/palantir/palantir-java-format) Java formatter ([#1083](https://github.com/diffplug/spotless/pull/1083)).

## [2.19.2] - 2022-01-10
### Fixed
Expand Down
23 changes: 22 additions & 1 deletion plugin-maven/README.md
Expand Up @@ -47,7 +47,7 @@ user@machine repo % mvn spotless:check
- [Requirements](#requirements)
- [Binding to maven phase](#binding-to-maven-phase)
- **Languages**
- [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [prettier](#prettier))
- [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [prettier](#prettier), [palantir-java-format](#palantir-java-format))
- [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy))
- [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [prettier](#prettier))
- [Scala](#scala) ([scalafmt](#scalafmt))
Expand Down Expand Up @@ -223,6 +223,27 @@ For example the following file under `.mvn/jvm.config` will run maven with the r
```
This is a workaround to a [pending issue](https://github.com/diffplug/spotless/issues/834).

### palantir-java-format

[homepage](https://github.com/palantir/palantir-java-format). [changelog](https://github.com/palantir/palantir-java-format/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/PalantirJavaFormat.java).

```xml
<palantirJavaFormat>
<version>2.10.0</version> <!-- optional -->
</palantirJavaFormat>
```

**⚠️ Note on using Palantir Java Format with Java 16+**

Using Java 16+ with Palantir Java Format [requires additional flags](https://github.com/google/google-java-format/releases/tag/v1.10.0) on the running JDK.
These Flags can be provided using `MAVEN_OPTS` environment variable or using the `./mvn/jvm.config` file (See [documentation](https://maven.apache.org/configure.html#mvn-jvm-config-file)).

For example the following file under `.mvn/jvm.config` will run maven with the required flags:
```
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
```
This is a workaround to a [pending issue](https://github.com/diffplug/spotless/issues/834).

### eclipse jdt

[homepage](https://www.eclipse.org/downloads/packages/). [compatible versions](https://github.com/diffplug/spotless/tree/main/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java). See [here](../ECLIPSE_SCREENSHOTS.md) for screenshots that demonstrate how to get and install the config file mentioned below.
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2016 DiffPlug
* Copyright 2016-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,6 +54,10 @@ public void addImportOrder(ImportOrder importOrder) {
addStepFactory(importOrder);
}

public void addPalantirJavaFormat(PalantirJavaFormat palantirJavaFormat) {
addStepFactory(palantirJavaFormat);
}

public void addRemoveUnusedImports(RemoveUnusedImports removeUnusedImports) {
addStepFactory(removeUnusedImports);
}
Expand Down

0 comments on commit c66f83e

Please sign in to comment.