Skip to content

Commit

Permalink
Merge branch 'main' into drop-ktlint-3x
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Jan 25, 2023
2 parents 4b2097c + 33f4abe commit a205607
Show file tree
Hide file tree
Showing 88 changed files with 2,606 additions and 687 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* text eol=lf
*.bat eol=crlf
*.png binary
*.jar binary
3 changes: 2 additions & 1 deletion .github/workflows/changelog-print.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ jobs:
with:
java-version: 11
distribution: 'temurin'
cache: 'gradle'
- name: gradle caching
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
- run: ./gradlew changelogPrint
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ jobs:
with:
distribution: "temurin"
java-version: 11
cache: gradle
- name: gradle caching
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
- name: spotlessCheck
run: ./gradlew spotlessCheck --build-cache
- name: assemble testClasses
Expand Down Expand Up @@ -60,7 +63,10 @@ jobs:
with:
distribution: "temurin"
java-version: ${{ matrix.jre }}
cache: gradle
- name: gradle caching
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
- name: build (maven-only)
if: matrix.kind == 'maven'
run: ./gradlew :plugin-maven:build -x spotlessCheck --build-cache
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ jobs:
with:
java-version: 11
distribution: 'temurin'
cache: 'gradle'
- name: gradle caching
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
- name: publish all
if: "${{ github.event.inputs.to_publish == 'all' }}"
run: |
Expand Down
8 changes: 6 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Added
* `ProcessRunner` has added some convenience methods so it can be used for maven testing. ([#1496](https://github.com/diffplug/spotless/pull/1496))
* `ProcessRunner` allows to limit captured output to a certain number of bytes. ([#1511](https://github.com/diffplug/spotless/pull/1511))
* `ProcessRunner` is now capable of handling long-running tasks where waiting for exit is delegated to the caller. ([#1511](https://github.com/diffplug/spotless/pull/1511))
* Allow to specify node executable for node-based formatters using `nodeExecutable` parameter ([#1500](https://github.com/diffplug/spotless/pull/1500))
### Fixed
* The default list of type annotations used by `formatAnnotations` has had 8 more annotations from the Checker Framework added [#1494](https://github.com/diffplug/spotless/pull/1494)
### Changes
#### Removed
* Removed support for KtLint 0.3x and 0.45.2 ([#1475](https://github.com/diffplug/spotless/pull/1475))
* Rename `YamlJacksonStep` into `JacksonYamlStep` while normalizing Jackson usage ([#1492](https://github.com/diffplug/spotless/pull/1492))
* Convert `gson` integration to use a compile-only source set ([#1510](https://github.com/diffplug/spotless/pull/1510)).
* ** POTENTIALLY BREAKING** Removed support for KtLint 0.3x and 0.45.2 ([#1475](https://github.com/diffplug/spotless/pull/1475))
* `KtLint` does not maintain a stable API - before this PR, we supported every breaking change in the API since 2019.
* From now on, we will support no more than 2 breaking changes at a time.

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}}
extra('java.EclipseJdtFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.FormatAnnotationsStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('json.gson.GsonStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('json.JacksonJsonStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('json.JsonSimpleStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('kotlin.KtfmtStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
Expand All @@ -77,7 +78,7 @@ lib('python.BlackStep') +'{{yes}} | {{no}}
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('yaml.YamlJacksonStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
'| [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | {{no}} | {{no}} | {{no}} | {{no}} |',
].join('\n');
-->
Expand Down Expand Up @@ -109,6 +110,7 @@ lib('yaml.YamlJacksonStep') +'{{no}} | {{yes}}
| [`java.EclipseJdtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.FormatAnnotationsStep`](lib/src/main/java/com/diffplug/spotless/java/FormatAnnotationsStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`json.gson.GsonStep`](lib/src/main/java/com/diffplug/spotless/json/gson/GsonStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`json.JacksonJsonStep`](lib/src/main/java/com/diffplug/spotless/json/JacksonJsonStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`json.JsonSimpleStep`](lib/src/main/java/com/diffplug/spotless/json/JsonSimpleStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
Expand All @@ -123,7 +125,7 @@ lib('yaml.YamlJacksonStep') +'{{no}} | {{yes}}
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`wtp.EclipseWtpFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`yaml.YamlJacksonStep`](lib/src/main/java/com/diffplug/spotless/yaml/YamlJacksonStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
| [`yaml.JacksonYamlStep`](lib/src/main/java/com/diffplug/spotless/yaml/JacksonYamlStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | :white_large_square: | :white_large_square: | :white_large_square: | :white_large_square: |
<!---freshmark /matrix -->

Expand Down
2 changes: 1 addition & 1 deletion _ext/eclipse-wtp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ sourceSets {
* All test classes need to run separately since they all instatiate different setups of the
* Eclipse framework.
*/
test {
tasks.withType(Test).configureEach {
//Skip default tests, which would run every test case.
exclude '**'
}
Expand Down
4 changes: 3 additions & 1 deletion _ext/gradle/java-setup.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ dependencies {
testImplementation project(':testlib')
}

test { useJUnitPlatform() }
tasks.withType(Test).configureEach {
useJUnitPlatform()
}
2 changes: 1 addition & 1 deletion gradle/special-tests.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def special = [
]

boolean isCiServer = System.getenv().containsKey("CI")
tasks.named('test') {
tasks.withType(Test).configureEach {
// See com.diffplug.spotless.tag package for available JUnit 5 @Tag annotations
useJUnitPlatform {
excludeTags special as String[]
Expand Down
2 changes: 1 addition & 1 deletion lib-extra/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies {
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)

apply from: rootProject.file('gradle/special-tests.gradle')
tasks.named('test') {
tasks.withType(Test).configureEach {
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16)) {
// needed for EclipseCdtFormatterStepTest
jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
Expand Down
28 changes: 27 additions & 1 deletion lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def NEEDS_GLUE = [
'flexmark',
'diktat',
'scalafmt',
'jackson'
'jackson',
'gson'
]
for (glue in NEEDS_GLUE) {
sourceSets.register(glue) {
Expand All @@ -41,6 +42,11 @@ versionCompatibility {
}
}

tasks.named("check").configure {
dependsOn(tasks.named("testCompatibilityAdapters"))
dependsOn(tasks.named("testCompatibility"))
}

dependencies {
compileOnly 'org.slf4j:slf4j-api:2.0.0'
// zero runtime reqs is a hard requirements for spotless-lib
Expand All @@ -56,6 +62,7 @@ dependencies {
palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' // this version needs to stay compilable against Java 8 for CI Job testNpm

// used jackson-based formatters
jacksonCompileOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.1'
jacksonCompileOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.1'

String VER_KTFMT = '0.42'
Expand Down Expand Up @@ -91,12 +98,31 @@ dependencies {

// used for markdown formatting
flexmarkCompileOnly 'com.vladsch.flexmark:flexmark-all:0.62.2'

gsonCompileOnly 'com.google.code.gson:gson:2.10.1'
}

// we'll hold the core lib to a high standard
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)

apply from: rootProject.file('gradle/special-tests.gradle')
tasks.withType(Test).configureEach {
def jdkVersion = JavaVersion.current().majorVersion.toInteger()
def args = []
if (jdkVersion >= 16) {
// https://docs.gradle.org/7.5/userguide/upgrading_version_7.html#removes_implicit_add_opens_for_test_workers
args += [
"--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED",
]
}
if (jdkVersion >= 18) {
// https://openjdk.org/jeps/411
args += "-Djava.security.manager=allow"
}
jvmArgs(args)
}

jar {
for (glue in NEEDS_GLUE) {
from sourceSets.getByName(glue).output.classesDirs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2023 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.gson;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Collections;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;

import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.ThrowingEx;
import com.diffplug.spotless.json.gson.GsonConfig;

public class GsonFormatterFunc implements FormatterFunc {

private static final String FAILED_TO_PARSE_ERROR_MESSAGE = "Unable to format JSON";

private final Gson gson;
private final GsonConfig gsonConfig;
private final String generatedIndent;

public GsonFormatterFunc(GsonConfig gsonConfig) {
GsonBuilder gsonBuilder = new GsonBuilder().serializeNulls();
if (!gsonConfig.isEscapeHtml()) {
gsonBuilder = gsonBuilder.disableHtmlEscaping();
}
this.gson = gsonBuilder.create();
this.gsonConfig = gsonConfig;
this.generatedIndent = generateIndent(gsonConfig.getIndentSpaces());
}

@Override
public String apply(String inputString) {
String result;
if (inputString.isEmpty()) {
result = "";
} else {
JsonElement jsonElement = gson.fromJson(inputString, JsonElement.class);
if (jsonElement == null) {
throw new AssertionError(FAILED_TO_PARSE_ERROR_MESSAGE);
}
if (gsonConfig.isSortByKeys() && jsonElement.isJsonObject()) {
jsonElement = sortByKeys(jsonElement.getAsJsonObject());
}
try (StringWriter stringWriter = new StringWriter()) {
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setIndent(this.generatedIndent);
gson.toJson(jsonElement, jsonWriter);
result = stringWriter + "\n";
} catch (IOException ioException) {
throw ThrowingEx.asRuntime(ioException);
}
}
return result;
}

private JsonElement sortByKeys(JsonObject jsonObject) {
JsonObject result = new JsonObject();
jsonObject.keySet().stream().sorted()
.forEach(key -> {
JsonElement element = jsonObject.get(key);
if (element.isJsonObject()) {
element = sortByKeys(element.getAsJsonObject());
}
result.add(key, element);
});
return result;
}

private String generateIndent(int indentSpaces) {
return String.join("", Collections.nCopies(indentSpaces, " "));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2021-2023 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.json;

import java.io.IOException;
import java.util.Map;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.json.JacksonConfig;

/**
* A {@link FormatterFunc} based on Jackson library
*/
// https://github.com/FasterXML/jackson-dataformats-text/issues/372
public abstract class AJacksonFormatterFunc implements FormatterFunc {
private JacksonConfig jacksonConfig;

public AJacksonFormatterFunc(JacksonConfig jacksonConfig) {
this.jacksonConfig = jacksonConfig;
}

@Override
public String apply(String input) throws Exception {
ObjectMapper objectMapper = makeObjectMapper();

return format(objectMapper, input);
}

protected String format(ObjectMapper objectMapper, String input) throws IllegalArgumentException, IOException {
try {
// ObjectNode is not compatible with SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS
Map objectNode = objectMapper.readValue(input, Map.class);
String output = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectNode);

return output;
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Unable to format. input='" + input + "'", e);
}
}

/**
* @return a {@link JsonFactory}. May be overridden to handle alternative formats.
* @see <a href="https://github.com/FasterXML/jackson-dataformats-text">jackson-dataformats-text</a>
*/
protected abstract JsonFactory makeJsonFactory();

protected ObjectMapper makeObjectMapper() {
JsonFactory jsonFactory = makeJsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);

objectMapper.setDefaultPrettyPrinter(makePrettyPrinter());

// Configure the ObjectMapper
// https://github.com/FasterXML/jackson-databind#commonly-used-features
jacksonConfig.getFeatureToToggle().forEach((rawFeature, toggle) -> {
// https://stackoverflow.com/questions/3735927/java-instantiating-an-enum-using-reflection
SerializationFeature feature = SerializationFeature.valueOf(rawFeature);

objectMapper.configure(feature, toggle);
});

return objectMapper;
}

protected PrettyPrinter makePrettyPrinter() {
return new DefaultPrettyPrinter();
}
}
Loading

0 comments on commit a205607

Please sign in to comment.