Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ 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
- Add a `groupArtifact` option to `PalantirJavaFormatStep`. ([#3179](https://github.com/diffplug/spotless/pull/3179))
### Fixed
- GrEclipse no longer leaves a `file%3A...` directory in the working directory. ([#2019](https://github.com/diffplug/spotless/issues/2019))
- DBeaver SQL formatter no longer prints an `IndexOutOfBoundsException` when a file starts with a keyword like `SET`. ([#1552](https://github.com/diffplug/spotless/issues/1552))
- `ExpandWildcardImportsStep` no longer fails with `Symbol resolution not configured` on records and other syntax newer than Java 11, and leaves files JavaParser cannot validate unchanged. ([#2946](https://github.com/diffplug/spotless/issues/2946))
- `removeSemicolons()` no longer removes semicolons inside dollar-slashy strings (`$/ ... /$`), after escaped triple quotes in multiline strings, or in multi-line `for (init; cond; update)` headers. ([#2780](https://github.com/diffplug/spotless/issues/2780))
- `RemoveUnusedImportsStep` and `GoogleJavaFormatStep` no longer remove imports that are only used by links in Markdown doc comments (`///`, JDK 23+). ([#3161](https://github.com/diffplug/spotless/issues/3161))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public final class PalantirJavaFormatStep implements Serializable {
private static final boolean DEFAULT_FORMAT_JAVADOC = false;
private static final String DEFAULT_STYLE = "PALANTIR";
private static final String NAME = "palantir-java-format";
public static final String MAVEN_COORDINATE = "com.palantir.javaformat:palantir-java-format:";
private static final String DEFAULT_GROUP_ARTIFACT = "com.palantir.javaformat:palantir-java-format";
public static final String MAVEN_COORDINATE = DEFAULT_GROUP_ARTIFACT + ":";
public static final String DEFAULT_VERSION = BuildConfig.VERSION_PALANTIR_JAVA_FORMAT; // compatible with Java 11+

/** The jar that contains the formatter. */
Expand Down Expand Up @@ -77,16 +78,33 @@ public static FormatterStep create(String version, String style, Provisioner pro
* format style.
*/
public static FormatterStep create(String version, String style, boolean formatJavadoc, Provisioner provisioner) {
return create(defaultGroupArtifact(), version, style, formatJavadoc, provisioner);
}

/**
* Creates a step which formats everything - groupArtifact, code, import order, unused imports, and Java docs. And with the given
* format style.
*/
public static FormatterStep create(String groupArtifact, String version, String style, boolean formatJavadoc, Provisioner provisioner) {
Objects.requireNonNull(groupArtifact, "groupArtifact");
if (groupArtifact.chars().filter(ch -> ch == ':').count() != 1) {
throw new IllegalArgumentException("groupArtifact must be in the form 'groupId:artifactId'");
}
Objects.requireNonNull(version, "version");
Objects.requireNonNull(style, "style");
Objects.requireNonNull(provisioner, "provisioner");

return FormatterStep.create(NAME,
new PalantirJavaFormatStep(JarState.promise(() -> JarState.from(MAVEN_COORDINATE + version, provisioner)), version, style, formatJavadoc),
new PalantirJavaFormatStep(JarState.promise(() -> JarState.from(groupArtifact + ":" + version, provisioner)), version, style, formatJavadoc),
PalantirJavaFormatStep::equalityState,
State::createFormat);
}

/** Get default formatter group and artifact */
public static String defaultGroupArtifact() {
return DEFAULT_GROUP_ARTIFACT;
}

/** Get default formatter version */
public static String defaultVersion() {
return DEFAULT_VERSION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ && isCommentLine(SQL_DIALECT, token.getString())
boolean isDelimiter = statementDelimiters.contains(token.getString().toUpperCase(Locale.ENGLISH));

if (!isDelimiter) {
if (argIndex == 0) {
// nothing precedes the first token, so there is no line to break
return 0;
}
token = argList.get(argIndex - 1);
if (token.getType() == TokenType.SPACE) {
token.setString(s.toString());
Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]
### Added
- Add `groupArtifact(String)` to `palantirJavaFormat()`. ([#3179](https://github.com/diffplug/spotless/pull/3179))
- `SpotlessApply` writes a report of the files it rewrote to `build/spotless/<taskName>-changed-files.txt`, configurable via `changedFilesReport`. The report is a task output, so tasks which take it as an input automatically depend on the apply task. ([#2715](https://github.com/diffplug/spotless/issues/2715))
### Changes
- `SpotlessApply` now only reports that it did work (and is otherwise `UP-TO-DATE`) when it actually rewrote a file. ([#2715](https://github.com/diffplug/spotless/issues/2715))
### Fixed
- GrEclipse no longer leaves a `file%3A...` directory in the working directory. ([#2019](https://github.com/diffplug/spotless/issues/2019))
- DBeaver SQL formatter no longer prints an `IndexOutOfBoundsException` when a file starts with a keyword like `SET`. ([#1552](https://github.com/diffplug/spotless/issues/1552))
- `expandWildcardImports()` no longer fails with `Symbol resolution not configured` on records and other syntax newer than Java 11, and leaves files JavaParser cannot validate unchanged. ([#2946](https://github.com/diffplug/spotless/issues/2946))
- String `targetExclude` patterns ending in `/**` (e.g. `**/build/**`) are now applied as exclude patterns on String `target`s, so excluded directories are skipped while walking the target instead of walking the whole project directory, which made configuration cache store and reuse scale with the size of the project. ([#3147](https://github.com/diffplug/spotless/issues/3147))
- `removeSemicolons()` no longer removes semicolons inside dollar-slashy strings (`$/ ... /$`), after escaped triple quotes in multiline strings, or in multi-line `for (init; cond; update)` headers. ([#2780](https://github.com/diffplug/spotless/issues/2780))
Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ spotless {
palantirJavaFormat('2.9.0').style("GOOGLE")
// optional: you can also format Javadocs, requires at least Palantir 2.39.0
palantirJavaFormat('2.39.0').formatJavadoc(true)
// optional: you can also use custom group artifact (you probably don't need this)
palantirJavaFormat('2.39.0').groupArtifact('com.palantir.javaformat:palantir-java-format')
```

### prince-of-space
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,15 +312,23 @@ public PalantirJavaFormatConfig palantirJavaFormat(String version) {

public class PalantirJavaFormatConfig {
final String version;
String groupArtifact;
String style;
boolean formatJavadoc;

PalantirJavaFormatConfig(String version) {
this.version = Objects.requireNonNull(version);
this.groupArtifact = PalantirJavaFormatStep.defaultGroupArtifact();
this.style = PalantirJavaFormatStep.defaultStyle();
addStep(createStep());
}

public PalantirJavaFormatConfig groupArtifact(String groupArtifact) {
this.groupArtifact = Objects.requireNonNull(groupArtifact);
replaceStep(createStep());
return this;
}

public PalantirJavaFormatConfig style(String style) {
this.style = Objects.requireNonNull(style);
replaceStep(createStep());
Expand All @@ -334,7 +342,7 @@ public PalantirJavaFormatConfig formatJavadoc(boolean formatJavadoc) {
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/
package com.diffplug.gradle.spotless;

import static org.junit.jupiter.api.condition.JRE.JAVA_21;

import java.io.IOException;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;

class PalantirJavaFormatIntegrationTest extends GradleIntegrationHarness {
@Test
Expand Down Expand Up @@ -67,4 +70,27 @@ void formatJavaDoc() throws IOException {

checkRunsThenUpToDate();
}

@Test
@EnabledForJreRange(min = JAVA_21)
void customGroupArtifact() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"repositories { mavenCentral() }",
"",
"spotless {",
" java {",
" target file('test.java')",
" palantirJavaFormat('21.0.2').groupArtifact('dev.openjavaformat:open-java-format')",
" }",
"}");

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

checkRunsThenUpToDate();
}
}
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]
### Added
- Add a `<groupArtifact>` parameter to `<palantirJavaFormat>`. ([#3179](https://github.com/diffplug/spotless/pull/3179))
- Add a `spotless:report` goal that puts a Spotless page in the Maven site. ([#3175](https://github.com/diffplug/spotless/pull/3175))
List `spotless-maven-plugin` under `<reporting>` and run `mvn site`: the page shows which files need formatting, with a colored diff for each, and their lint problems. It works with `maven-site-plugin` 3.12.1 and 3.20.0 or later.
### Fixed
- GrEclipse no longer leaves a `file%3A...` directory in the working directory. ([#2019](https://github.com/diffplug/spotless/issues/2019))
- DBeaver SQL formatter no longer prints an `IndexOutOfBoundsException` when a file starts with a keyword like `SET`. ([#1552](https://github.com/diffplug/spotless/issues/1552))
- `<expandWildcardImports>` no longer fails with `Symbol resolution not configured` on records and other syntax newer than Java 11, and leaves files JavaParser cannot validate unchanged. ([#2946](https://github.com/diffplug/spotless/issues/2946))
- `<removeSemicolons/>` no longer removes semicolons inside dollar-slashy strings (`$/ ... /$`), after escaped triple quotes in multiline strings, or in multi-line `for (init; cond; update)` headers. ([#2780](https://github.com/diffplug/spotless/issues/2780))
- `<removeUnusedImports>` and `<googleJavaFormat>` no longer remove imports that are only used by links in Markdown doc comments (`///`, JDK 23+). ([#3161](https://github.com/diffplug/spotless/issues/3161))
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ Note: when enabling `AOSP` style, `reorderImports` needs to be enabled to apply
<version>2.39.0</version> <!-- optional -->
<style>PALANTIR</style> <!-- or AOSP/GOOGLE (optional) -->
<formatJavadoc>false</formatJavadoc> <!-- defaults to false (optional, requires at least Palantir 2.39.0) -->
<!-- optional: custom group artifact (you probably don't need this) -->
<groupArtifact>com.palantir.javaformat:palantir-java-format</groupArtifact>
</palantirJavaFormat>
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2024 DiffPlug
* Copyright 2016-2026 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,8 @@
import com.diffplug.spotless.maven.FormatterStepFactory;

public class PalantirJavaFormat implements FormatterStepFactory {
@Parameter
private String groupArtifact;

@Parameter
private String version;
Expand All @@ -35,9 +37,10 @@ public class PalantirJavaFormat implements FormatterStepFactory {

@Override
public FormatterStep newFormatterStep(FormatterStepConfig config) {
String groupArtifact = this.groupArtifact != null ? this.groupArtifact : PalantirJavaFormatStep.defaultGroupArtifact();
String version = this.version != null ? this.version : PalantirJavaFormatStep.defaultVersion();
String style = this.style != null ? this.style : PalantirJavaFormatStep.defaultStyle();
boolean formatJavadoc = this.formatJavadoc != null ? this.formatJavadoc : PalantirJavaFormatStep.defaultFormatJavadoc();
return PalantirJavaFormatStep.create(version, style, formatJavadoc, config.getProvisioner());
return PalantirJavaFormatStep.create(groupArtifact, version, style, formatJavadoc, config.getProvisioner());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package com.diffplug.spotless.maven.java;

import static org.junit.jupiter.api.Assumptions.assumeTrue;

import org.junit.jupiter.api.Test;

import com.diffplug.spotless.Jvm;
import com.diffplug.spotless.java.PalantirJavaFormatStep;
import com.diffplug.spotless.maven.MavenIntegrationHarness;

Expand Down Expand Up @@ -52,6 +55,19 @@ void formatJavaDoc() throws Exception {
runTest("java/palantirjavaformat/JavaCodeWithJavaDocFormatted.test", "java/palantirjavaformat/JavaCodeWithJavaDocUnformatted.test");
}

@Test
void customGroupArtifact() throws Exception {
assumeTrue(Jvm.version() >= 21, "open-java-format 21.0.2 requires JVM 21+");

writePomWithJavaSteps(
"<palantirJavaFormat>",
" <groupArtifact>dev.openjavaformat:open-java-format</groupArtifact>",
" <version>21.0.2</version>",
"</palantirJavaFormat>");

runTest("java/palantirjavaformat/JavaCodeFormatted.test", "java/palantirjavaformat/JavaCodeUnformatted.test");
}

private void runTest(String targetResource, String sourceResource) throws Exception {
String path = "src/main/java/test.java";
setFile(path).toResource(sourceResource);
Expand Down
2 changes: 2 additions & 0 deletions testlib/src/main/resources/sql/dbeaver/set-mode.clean
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SET
MODE PostgreSQL;
1 change: 1 addition & 0 deletions testlib/src/main/resources/sql/dbeaver/set-mode.dirty
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SET MODE PostgreSQL;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
*/
package com.diffplug.spotless.java;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.condition.JRE.JAVA_21;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.ResourceHarness;
Expand Down Expand Up @@ -67,9 +71,28 @@ void behaviorWithGoogleStyle() throws Exception {
.testResource("java/palantirjavaformat/JavaCodeWithPackageUnformatted.test", "java/palantirjavaformat/JavaCodeWithPackageFormattedGoogle.test");
}

@Test
@EnabledForJreRange(min = JAVA_21)
void behaviorWithCustomGroupArtifact() throws Exception {
FormatterStep step = PalantirJavaFormatStep.create("dev.openjavaformat:open-java-format", "21.0.2", PalantirJavaFormatStep.defaultStyle(), PalantirJavaFormatStep.defaultFormatJavadoc(), TestProvisioner.mavenCentral());
StepHarness.forStep(step)
.testResource("java/palantirjavaformat/JavaCodeUnformatted.test", "java/palantirjavaformat/JavaCodeFormatted.test")
.testResource("java/palantirjavaformat/JavaCodeWithLicenseUnformatted.test", "java/palantirjavaformat/JavaCodeWithLicenseFormatted.test")
.testResource("java/palantirjavaformat/JavaCodeWithPackageUnformatted.test", "java/palantirjavaformat/JavaCodeWithPackageFormatted.test");
}

@Test
void invalidGroupArtifact() {
assertThrows(IllegalArgumentException.class,
() -> PalantirJavaFormatStep.create("com.palantir.javaformat", "1.1.0", "PALANTIR", false, TestProvisioner.mavenCentral()));
assertThrows(IllegalArgumentException.class,
() -> PalantirJavaFormatStep.create("com.palantir.javaformat:palantir-java-format:1.1.0", "1.1.0", "PALANTIR", false, TestProvisioner.mavenCentral()));
}

@Test
void equality() {
new SerializableEqualityTester() {
String groupArtifact = PalantirJavaFormatStep.defaultGroupArtifact();
String version = "1.1.0";
String style = "";
boolean formatJavadoc;
Expand All @@ -93,12 +116,17 @@ protected void setupTest(API api) {
formatJavadoc = true;
api.areDifferentThan();
formatJavadoc = false;

// change the groupArtifact, and it's different
groupArtifact = "com.palantir.javaformat:palantir-java-format-spi";
api.areDifferentThan();
groupArtifact = PalantirJavaFormatStep.defaultGroupArtifact();
}

@Override
protected FormatterStep create() {
String finalVersion = this.version;
return PalantirJavaFormatStep.create(finalVersion, style, formatJavadoc, TestProvisioner.mavenCentral());
return PalantirJavaFormatStep.create(groupArtifact, finalVersion, style, formatJavadoc, TestProvisioner.mavenCentral());
}
}.testEquals();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2024 DiffPlug
* Copyright 2016-2026 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,7 +15,11 @@
*/
package com.diffplug.spotless.sql;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.util.Collections;
import java.util.List;

Expand All @@ -39,6 +43,22 @@ void behavior() {
.testResource("sql/dbeaver/jdbi-params.dirty", "sql/dbeaver/jdbi-params.clean");
}

@Test
void keywordAtStartOfFileDoesNotThrow() {
// https://github.com/diffplug/spotless/issues/1552
PrintStream originalErr = System.err;
ByteArrayOutputStream err = new ByteArrayOutputStream();
System.setErr(new PrintStream(err, true));
try {
FormatterStep step = DBeaverSQLFormatterStep.create(Collections.emptySet());
StepHarness.forStep(step)
.testResource("sql/dbeaver/set-mode.dirty", "sql/dbeaver/set-mode.clean");
} finally {
System.setErr(originalErr);
}
assertThat(err.toString()).isEmpty();
}

@Test
void behaviorWithConfigFile() {
FormatterStep step = DBeaverSQLFormatterStep.create(createTestFiles("sql/dbeaver/sqlConfig.properties"));
Expand Down
Loading