Skip to content

Commit

Permalink
Merge branch 'main' into feat/equo-ide
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Feb 26, 2023
2 parents b4d9de5 + 2872741 commit 74f2ee8
Show file tree
Hide file tree
Showing 53 changed files with 1,157 additions and 123 deletions.
13 changes: 13 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ 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]
### Fixed
* `JacksonJsonFormatterFunc` handles json files with an Array as root. ([#1585](https://github.com/diffplug/spotless/pull/1585))

## [2.35.0] - 2023-02-10
### Added
* CleanThat Java Refactorer. ([#1560](https://github.com/diffplug/spotless/pull/1560))
* Introduce `LazyArgLogger` to allow for lazy evaluation of log messages in slf4j logging. ([#1565](https://github.com/diffplug/spotless/pull/1565))
### Fixed
* Allow multiple instances of the same npm-based formatter to be used by separating their `node_modules` directories. ([#1565](https://github.com/diffplug/spotless/pull/1565))
* `ktfmt` default style uses correct continuation indent. ([#1562](https://github.com/diffplug/spotless/pull/1562))
### Changes
* Bump default `ktfmt` version to latest `0.42` -> `0.43` ([#1561](https://github.com/diffplug/spotless/pull/1561))
* Bump default `jackson` version to latest `2.14.1` -> `2.14.2` ([#1536](https://github.com/diffplug/spotless/pull/1536))

## [2.34.1] - 2023-02-05
### Changes
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ lib('java.PalantirJavaFormatStep') +'{{yes}} | {{yes}}
lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
extra('java.EclipseJdtFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.FormatAnnotationsStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('java.CleanthatJavaStep') +'{{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}} |',
Expand Down Expand Up @@ -131,6 +132,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}}
| [`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: |
| [`java.FormatAnnotationsStep`](lib/src/main/java/com/diffplug/spotless/java/FormatAnnotationsStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`java.CleanthatJavaStep`](lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.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: |
Expand Down
4 changes: 2 additions & 2 deletions gradle/java-publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ model {
}
}

if (System.env['JITPACK'] == 'true') {
if (System.env['JITPACK'] == 'true' || version.endsWith('-SNAPSHOT')) {
signing {
setRequired(false)
}
} else if (!version.endsWith('-SNAPSHOT')) {
} else {
signing {
String gpg_key = decode64('ORG_GRADLE_PROJECT_gpg_key64')
useInMemoryPgpKeys(gpg_key, System.env['ORG_GRADLE_PROJECT_gpg_passphrase'])
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 DiffPlug
* Copyright 2016-2023 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 @@ -42,6 +42,8 @@
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.concurrenttrees.radix.ConcurrentRadixTree;
import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharSequenceNodeFactory;
Expand All @@ -61,6 +63,8 @@
* back to the platform native.
*/
public final class GitAttributesLineEndings {
private static final Logger LOGGER = LoggerFactory.getLogger(GitAttributesLineEndings.class);

// prevent direct instantiation
private GitAttributesLineEndings() {}

Expand Down Expand Up @@ -261,7 +265,7 @@ private static String convertEolToLineEnding(String eol, File file) {
case "crlf":
return LineEnding.WINDOWS.str();
default:
System.err.println(".gitattributes file has unspecified eol value: " + eol + " for " + file + ", defaulting to platform native");
LOGGER.warn(".gitattributes file has unspecified eol value: {} for {}, defaulting to platform native", eol, file);
return LineEnding.PLATFORM_NATIVE.str();
}
}
Expand Down Expand Up @@ -341,8 +345,7 @@ private static List<AttributesRule> parseRules(@Nullable File file) {
return parsed.getRules();
} catch (IOException e) {
// no need to crash the whole plugin
System.err.println("Problem parsing " + file.getAbsolutePath());
e.printStackTrace();
LOGGER.warn("Problem parsing {}", file.getAbsolutePath(), e);
}
}
return Collections.emptyList();
Expand Down
18 changes: 14 additions & 4 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def NEEDS_GLUE = [
'diktat',
'scalafmt',
'jackson',
'gson'
'gson',
'cleanthat'
]
for (glue in NEEDS_GLUE) {
sourceSets.register(glue) {
Expand All @@ -39,6 +40,12 @@ versionCompatibility {
]
targetSourceSetName = 'ktlint'
}
namespaces.register('Cleanthat') {
versions = [
'2.1',
]
targetSourceSetName = 'cleanthat'
}
}
}

Expand All @@ -62,10 +69,10 @@ 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'
jacksonCompileOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
jacksonCompileOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2'

String VER_KTFMT = '0.42'
String VER_KTFMT = '0.43'
ktfmtCompileOnly "com.facebook:ktfmt:$VER_KTFMT"
String VER_KTLINT_GOOGLE_JAVA_FORMAT = '1.7' // for JDK 8 compatibility
ktfmtCompileOnly("com.google.googlejavaformat:google-java-format") {
Expand Down Expand Up @@ -100,6 +107,9 @@ dependencies {
flexmarkCompileOnly 'com.vladsch.flexmark:flexmark-all:0.62.2'

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

cleanthatCompileOnly 'io.github.solven-eu.cleanthat:java:2.6'
compatCleanthat2Dot1CompileAndTestOnly 'io.github.solven-eu.cleanthat:java:2.6'
}

// we'll hold the core lib to a high standard
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* 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.java;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.diffplug.spotless.FormatterFunc;

import eu.solven.cleanthat.config.pojo.CleanthatEngineProperties;
import eu.solven.cleanthat.config.pojo.SourceCodeProperties;
import eu.solven.cleanthat.engine.java.IJdkVersionConstants;
import eu.solven.cleanthat.engine.java.refactorer.JavaRefactorer;
import eu.solven.cleanthat.engine.java.refactorer.JavaRefactorerProperties;
import eu.solven.cleanthat.formatter.LineEnding;

/**
* The glue for CleanThat: it is build over the version in build.gradle, but at runtime it will be executed over
* the version loaded in JarState, which is by default defined in com.diffplug.spotless.java.CleanthatJavaStep#JVM_SUPPORT
*/
public class JavaCleanthatRefactorerFunc implements FormatterFunc {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaCleanthatRefactorerFunc.class);

private String jdkVersion;
private List<String> included;
private List<String> excluded;
private boolean includeDraft;

public JavaCleanthatRefactorerFunc(String jdkVersion, List<String> included, List<String> excluded, boolean includeDraft) {
this.jdkVersion = jdkVersion == null ? IJdkVersionConstants.JDK_8 : jdkVersion;
this.included = included == null ? Collections.emptyList() : included;
this.excluded = excluded == null ? Collections.emptyList() : excluded;
this.includeDraft = includeDraft;
}

public JavaCleanthatRefactorerFunc() {
this(IJdkVersionConstants.JDK_8, Arrays.asList("SafeAndConsensual"), Arrays.asList(), false);
}

@Override
public String apply(String input) throws Exception {
// https://stackoverflow.com/questions/1771679/difference-between-threads-context-class-loader-and-normal-classloader
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
// Ensure CleanThat main Thread has its custom classLoader while executing its refactoring
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
return doApply(input);
} finally {
// Restore the originalClassLoader
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}

private String doApply(String input) throws InterruptedException, IOException {
// call some API that uses reflection without taking ClassLoader param
CleanthatEngineProperties engineProperties = CleanthatEngineProperties.builder().engineVersion(jdkVersion).build();

// Spotless will push us LF content
engineProperties.setSourceCode(SourceCodeProperties.builder().lineEnding(LineEnding.LF).build());

JavaRefactorerProperties refactorerProperties = new JavaRefactorerProperties();

refactorerProperties.setIncluded(included);
refactorerProperties.setExcluded(excluded);

refactorerProperties.setIncludeDraft(includeDraft);

JavaRefactorer refactorer = new JavaRefactorer(engineProperties, refactorerProperties);

LOGGER.debug("Processing sourceJdk={} included={} excluded={}", jdkVersion, included, excluded, includeDraft);
LOGGER.debug("Available mutators: {}", JavaRefactorer.getAllIncluded());

// Spotless calls steps always with LF eol.
return refactorer.doFormat(input, LineEnding.LF);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
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;
Expand Down Expand Up @@ -49,7 +48,7 @@ public String apply(String input) throws Exception {
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);
Object objectNode = objectMapper.readValue(input, inferType(input));
String output = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectNode);

return output;
Expand All @@ -58,6 +57,13 @@ protected String format(ObjectMapper objectMapper, String input) throws IllegalA
}
}

/**
*
* @param input
* @return the {@link Class} into which the String has to be deserialized
*/
protected abstract Class<?> inferType(String input);

/**
* @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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.diffplug.spotless.glue.json;

import java.util.Collection;
import java.util.Map;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonFactoryBuilder;
import com.fasterxml.jackson.core.JsonGenerator;
Expand All @@ -37,6 +40,15 @@ public JacksonJsonFormatterFunc(JacksonJsonConfig jacksonConfig) {
this.jacksonConfig = jacksonConfig;
}

@Override
protected Class<?> inferType(String input) {
if (input.trim().startsWith("[")) {
return Collection.class;
} else {
return Map.class;
}
}

/**
* @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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,18 @@ protected JsonFactory makeJsonFactory() {
return yamlFactoryBuilder.build();
}

@Override
protected Class<?> inferType(String input) {
return JsonNode.class;
}

@Override
protected String format(ObjectMapper objectMapper, String input) throws IllegalArgumentException, IOException {
try {
// https://stackoverflow.com/questions/25222327/deserialize-pojos-from-multiple-yaml-documents-in-a-single-file-in-jackson
// https://github.com/FasterXML/jackson-dataformats-text/issues/66#issuecomment-375328648
JsonParser yamlParser = objectMapper.getFactory().createParser(input);
List<JsonNode> documents = objectMapper.readValues(yamlParser, JsonNode.class).readAll();
List<?> documents = objectMapper.readValues(yamlParser, inferType(input)).readAll();

// https://github.com/FasterXML/jackson-dataformats-text/issues/66#issuecomment-554265055
// https://github.com/FasterXML/jackson-dataformats-text/issues/66#issuecomment-554265055
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 DiffPlug
* Copyright 2022-2023 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 @@ -78,7 +78,7 @@ private FormattingOptions createFormattingOptions() {
formattingOptions.getStyle(),
ktfmtFormattingOptions.getMaxWidth().orElse(formattingOptions.getMaxWidth()),
ktfmtFormattingOptions.getBlockIndent().orElse(formattingOptions.getBlockIndent()),
ktfmtFormattingOptions.getContinuationIndent().orElse(formattingOptions.getBlockIndent()),
ktfmtFormattingOptions.getContinuationIndent().orElse(formattingOptions.getContinuationIndent()),
ktfmtFormattingOptions.getRemoveUnusedImport().orElse(formattingOptions.getRemoveUnusedImports()),
formattingOptions.getDebuggingPrintOpsAfterFormatting());
}
Expand Down
40 changes: 40 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/LazyArgLogger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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;

import java.util.function.Supplier;

/**
* This is a utility class to allow for lazy evaluation of arguments to be passed to a logger
* and thus avoid unnecessary computation of the arguments if the log level is not enabled.
*/
public final class LazyArgLogger {

private final Supplier<Object> argSupplier;

private LazyArgLogger(Supplier<Object> argSupplier) {
this.argSupplier = argSupplier;
}

public static LazyArgLogger lazy(Supplier<Object> argSupplier) {
return new LazyArgLogger(argSupplier);
}

@Override
public String toString() {
return String.valueOf(argSupplier.get());
}
}
Loading

0 comments on commit 74f2ee8

Please sign in to comment.