Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
contents: read
pull-requests: read
issues: read
members: read
id-token: write
steps:
- name: Check team membership
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Fixed
- palantirJavaFormat is no longer arbitrarily set to outdated versions on Java 17, latest available version is always used ([#2686](https://github.com/diffplug/spotless/pull/2686) fixes [#2685](https://github.com/diffplug/spotless/issues/2685))
### Added
- Add a `forbidModuleImports` API for java ([#2679](https://github.com/diffplug/spotless/issues/2679))

## [4.0.0] - 2025-09-24
### Changes
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ lib('java.ImportOrderStep') +'{{yes}} | {{yes}}
lib('java.PalantirJavaFormatStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.ForbidWildcardImportsStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.ForbidModuleImportsStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
extra('java.EclipseJdtFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.FormatAnnotationsStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('java.CleanthatJavaStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
Expand Down Expand Up @@ -142,6 +143,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}}
| [`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.ForbidWildcardImportsStep`](lib/src/main/java/com/diffplug/spotless/java/ForbidWildcardImportsStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.ForbidModuleImportsStep`](lib/src/main/java/com/diffplug/spotless/java/ForbidModuleImportsStep.java) | :+1: | :+1: | :white_large_square: | :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: |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2025 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 com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.generic.ReplaceRegexStep;

/** Forbids any module import statements. */
public final class ForbidModuleImportsStep {

/**
* Matches lines like 'import module java.base;' or 'import module java.sql;'.
*/
private static final String REGEX = "(?m)^import module[^;\\n]*;\\R?";
private static final String NAME = "forbidModuleImports";
private static final String ERROR = "Do not use module imports - replace with specific class imports as 'spotlessApply' cannot auto-fix this";

private ForbidModuleImportsStep() {}

public static FormatterStep create() {
return ReplaceRegexStep.lint(NAME, REGEX, ERROR);
}
}
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Fixed
- palantirJavaFormat is no longer arbitrarily set to outdated versions on Java 17, latest available version is always used ([#2686](https://github.com/diffplug/spotless/pull/2686) fixes [#2685](https://github.com/diffplug/spotless/issues/2685))
### Added
- `forbidModuleImports()` API for java ([#2679](https://github.com/diffplug/spotless/issues/2679))

## [8.0.0] - 2025-09-24
### Changed
Expand Down
11 changes: 11 additions & 0 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ spotless {

removeUnusedImports()
forbidWildcardImports()
forbidModuleImports()

// Cleanthat will refactor your code, but it may break your style: apply it before your formatter
cleanthat() // has its own section below
Expand Down Expand Up @@ -257,6 +258,16 @@ spotless {
}
```

### forbidModuleImports

```
spotless {
java {
forbidModuleImports()
}
}
```

### google-java-format

[homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.diffplug.spotless.extra.java.EclipseJdtFormatterStep;
import com.diffplug.spotless.generic.LicenseHeaderStep;
import com.diffplug.spotless.java.CleanthatJavaStep;
import com.diffplug.spotless.java.ForbidModuleImportsStep;
import com.diffplug.spotless.java.ForbidWildcardImportsStep;
import com.diffplug.spotless.java.FormatAnnotationsStep;
import com.diffplug.spotless.java.GoogleJavaFormatStep;
Expand Down Expand Up @@ -162,6 +163,10 @@ public void forbidWildcardImports() {
addStep(ForbidWildcardImportsStep.create());
}

public void forbidModuleImports() {
addStep(ForbidModuleImportsStep.create());
}

/** Uses the <a href="https://github.com/google/google-java-format">google-java-format</a> jar to format source code. */
public GoogleJavaFormatConfig googleJavaFormat() {
return googleJavaFormat(GoogleJavaFormatStep.defaultVersion());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void removeUnusedImportsWithCleanthat() throws IOException {
}

@Test
void removeWildCardImports() throws IOException {
void forbidWildcardImports() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
Expand All @@ -92,13 +92,33 @@ void removeWildCardImports() throws IOException {
"spotless {",
" java {",
" target file('test.java')",
" removeWildcardImports()",
" forbidWildcardImports()",
" }",
"}");

setFile("test.java").toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile("test.java").toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
gradleRunner().withArguments("spotlessApply").buildAndFail();
assertFile("test.java").sameAsResource("java/removewildcardimports/JavaCodeWildcardsFormatted.test");
assertFile("test.java").sameAsResource("java/forbidwildcardimports/JavaCodeWildcardsFormatted.test");
}

@Test
void forbidModuleImports() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"repositories { mavenCentral() }",
"",
"spotless {",
" java {",
" target file('test.java')",
" forbidModuleImports()",
" }",
"}");

setFile("test.java").toResource("java/forbidmoduleimports/JavaCodeModuleImportsUnformatted.test");
gradleRunner().withArguments("spotlessApply").buildAndFail();
assertFile("test.java").sameAsResource("java/forbidmoduleimports/JavaCodeModuleImportsFormatted.test");
}

/**
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Fixed
- palantirJavaFormat is no longer arbitrarily set to outdated versions on Java 17, latest available version is always used ([#2686](https://github.com/diffplug/spotless/pull/2686) fixes [#2685](https://github.com/diffplug/spotless/issues/2685))
### Added
- `<forbidModuleImports>` API for java ([#2679](https://github.com/diffplug/spotless/issues/2679))

## [3.0.0] - 2025-09-24
### Changes
Expand Down
7 changes: 7 additions & 0 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ any other maven phase (i.e. compile) then it can be configured as below;

<removeUnusedImports /> <!-- self-explanatory -->
<forbidWildcardImports /> <!-- yell if any import ends with '*' -->
<forbidModuleImports /> <!-- yell if any module imports are found (Java 25+) -->

<formatAnnotations /> <!-- fixes formatting of type annotations, see below -->

Expand All @@ -255,6 +256,12 @@ any other maven phase (i.e. compile) then it can be configured as below;
<forbidWildcardImports/>
```

### forbidModuleImports

```xml
<forbidModuleImports/>
```

### google-java-format

[homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2025 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.maven.java;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.java.ForbidModuleImportsStep;
import com.diffplug.spotless.maven.FormatterStepConfig;
import com.diffplug.spotless.maven.FormatterStepFactory;

public class ForbidModuleImports implements FormatterStepFactory {
@Override
public FormatterStep newFormatterStep(FormatterStepConfig config) {
return ForbidModuleImportsStep.create();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public void addForbidWildcardImports(ForbidWildcardImports forbidWildcardImports
addStepFactory(forbidWildcardImports);
}

public void addForbidModuleImports(ForbidModuleImports forbidModuleImports) {
addStepFactory(forbidModuleImports);
}

public void addFormatAnnotations(FormatAnnotations formatAnnotations) {
addStepFactory(formatAnnotations);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2025 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.maven.java;

import org.junit.jupiter.api.Test;

import com.diffplug.spotless.maven.MavenIntegrationHarness;

class ForbidModuleImportsStepTest extends MavenIntegrationHarness {

@Test
void testForbidModuleImports() throws Exception {
writePomWithJavaSteps("<forbidModuleImports/>");

String path = "src/main/java/test.java";
setFile(path).toResource("java/forbidmoduleimports/JavaCodeModuleImportsUnformatted.test");
var selfie = expectSelfieErrorMsg(mavenRunner().withArguments("spotless:apply").runHasError());
assertFile(path).sameAsResource("java/forbidmoduleimports/JavaCodeModuleImportsUnformatted.test");
selfie.toBe("""
Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:VERSION:apply (default-cli) on project spotless-maven-plugin-tests: There were 2 lint error(s), they must be fixed or suppressed.
src/main/java/test.java:L1 forbidModuleImports(import module java.base;) Do not use module imports - replace with specific class imports as 'spotlessApply' cannot auto-fix this
src/main/java/test.java:L2 forbidModuleImports(import module java.sql;) Do not use module imports - replace with specific class imports as 'spotlessApply' cannot auto-fix this
Resolve these lints or suppress with `<lintSuppressions>`
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ void testForbidWildcardImports() throws Exception {
writePomWithJavaSteps("<forbidWildcardImports/>");

String path = "src/main/java/test.java";
setFile(path).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(path).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
var selfie = expectSelfieErrorMsg(mavenRunner().withArguments("spotless:apply").runHasError());
assertFile(path).sameAsResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
assertFile(path).sameAsResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
selfie.toBe("""
Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:VERSION:apply (default-cli) on project spotless-maven-plugin-tests: There were 5 lint error(s), they must be fixed or suppressed.
src/main/java/test.java:L1 forbidWildcardImports(import java.util.*;) Do not use wildcard imports (e.g. java.util.*) - replace with specific class imports (e.g. java.util.List) as 'spotlessApply' cannot auto-fix this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void testNoSuppressionFailsOnWildcardImports() throws Exception {
writePomWithJavaSteps("<forbidWildcardImports/>");

String path = "src/main/java/TestFile.java";
setFile(path).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(path).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");

expectSelfieErrorMsg(mavenRunner().withArguments("spotless:check").runHasError()).toBe("""
Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:VERSION:check (default-cli) on project spotless-maven-plugin-tests: Unable to format file ${PROJECT_DIR}/src/main/java/TestFile.java
Expand Down Expand Up @@ -58,8 +58,8 @@ void testSuppressByFilePath() throws Exception {
String suppressedFile = "src/main/java/TestFile1.java";
String unsuppressedFile = "src/main/java/TestFile2.java";

setFile(suppressedFile).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(unsuppressedFile).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(suppressedFile).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(unsuppressedFile).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");

var result = mavenRunner().withArguments("spotless:check").runHasError();
assertThat(result.stdOutUtf8()).contains("TestFile2.java");
Expand All @@ -79,7 +79,7 @@ void testSuppressByStep() throws Exception {
"</lintSuppressions>");

String path = "src/main/java/TestFile.java";
setFile(path).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(path).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");

// Should succeed because we suppressed the entire step
mavenRunner().withArguments("spotless:check").runNoError();
Expand All @@ -99,7 +99,7 @@ void testSuppressByShortCode() throws Exception {
"</lintSuppressions>");

String path = "src/main/java/TestFile.java";
setFile(path).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(path).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");

// Should succeed because we suppressed all error codes
mavenRunner().withArguments("spotless:check").runNoError();
Expand All @@ -126,9 +126,9 @@ void testMultipleSuppressionsWork() throws Exception {
String file2 = "src/main/java/TestFile2.java";
String file3 = "src/main/java/TestFile3.java";

setFile(file1).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(file2).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(file3).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(file1).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(file2).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");
setFile(file3).toResource("java/forbidwildcardimports/JavaCodeWildcardsUnformatted.test");

var result = mavenRunner().withArguments("spotless:check").runHasError();
assertThat(result.stdOutUtf8()).contains("TestFile3.java");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import module java.base;
import module java.sql;

public class Test {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import module java.base;
import module java.sql;

public class Test {}