diff --git a/lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java b/lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java index 990cf65806..5a77752be5 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,9 @@ */ package com.diffplug.spotless.generic; +import static com.diffplug.spotless.Lint.atLine; +import static com.diffplug.spotless.Lint.atUndefinedLine; + import java.io.Serializable; import java.util.Objects; import java.util.regex.Pattern; @@ -35,6 +38,15 @@ public static FormatterStep create(String name, String regex, String replacement State::toFormatter); } + public static FormatterStep lint(String name, String regex, String error) { + Objects.requireNonNull(name, "name"); + Objects.requireNonNull(regex, "regex"); + Objects.requireNonNull(error, "error"); + return FormatterStep.createLazy(name, + () -> new State(Pattern.compile(regex, Pattern.UNIX_LINES | Pattern.MULTILINE), error), + State::toLinter); + } + private static final class State implements Serializable { private static final long serialVersionUID = 1L; @@ -49,5 +61,14 @@ private static final class State implements Serializable { FormatterFunc toFormatter() { return raw -> regex.matcher(raw).replaceAll(replacement); } + + FormatterFunc toLinter() { + return raw -> { + if (regex.matcher(raw).find()) { + throw atLine(11111,"", replacement).shortcut(); + } + return raw; + }; + } } } diff --git a/lib/src/main/java/com/diffplug/spotless/java/RemoveWildcardImportsStep.java b/lib/src/main/java/com/diffplug/spotless/java/RemoveWildcardImportsStep.java index ca513b8280..efb6ede93b 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/RemoveWildcardImportsStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/RemoveWildcardImportsStep.java @@ -20,13 +20,17 @@ /** Removes any wildcard import statements. */ public final class RemoveWildcardImportsStep { + + /** + * Matches lines like 'import foo.*;' or 'import static foo.*;'. + */ + private static final String REGEX = "(?m)^import\\s+(?:static\\s+)?[^;\\n]*\\*;\\R?"; + private static final String NAME = "removeWildcardImports"; + private static final String ERROR = "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"; + private RemoveWildcardImportsStep() {} public static FormatterStep create() { - // Matches lines like 'import foo.*;' or 'import static foo.*;'. - return ReplaceRegexStep.create( - "removeWildcardImports", - "(?m)^import\\s+(?:static\\s+)?[^;\\n]*\\*;\\R?", - ""); + return ReplaceRegexStep.lint(NAME, REGEX, ERROR); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java index f3e1f30355..a2fc252dac 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java @@ -46,6 +46,8 @@ import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationHarness extends ResourceHarness { + + protected static final String PATH = "src/main/java/test.java"; /** * To run tests in the IDE, run {@code gradlew :plugin-maven:changelogPrint}, then * put the last version it prints into {@code SPOTLESS_MAVEN_VERSION_IDE}. From now diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveWildcardImportsStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveWildcardImportsStepTest.java index 4d4ade94d0..7017e4843a 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveWildcardImportsStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveWildcardImportsStepTest.java @@ -15,19 +15,49 @@ */ package com.diffplug.spotless.maven.java; +import static org.assertj.core.api.Assertions.assertThat; + +import com.diffplug.spotless.FormatterStep; + +import com.diffplug.spotless.StepHarnessWithFile; +import com.diffplug.spotless.TestProvisioner; +import com.diffplug.spotless.kotlin.KtLintStep; + +import org.assertj.core.api.AbstractStringAssert; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.diffplug.spotless.maven.MavenIntegrationHarness; class RemoveWildcardImportsStepTest extends MavenIntegrationHarness { + private static final String ERROR = "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"; + + @BeforeEach + void init() throws Exception { + writePomWithJavaSteps(""); + } + @Test void testRemoveWildcardImports() throws Exception { - writePomWithJavaSteps(""); + setFile(PATH).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test"); + assertFile(PATH).sameAsResource("java/removewildcardimports/JavaCodeWildcardsFormatted.test"); + AbstractStringAssert abstractStringAssert = assertThat(mavenRunner().withArguments("spotless:apply").runHasError().stdOutUtf8()); + abstractStringAssert + .contains(ERROR) + .contains("11111") + ; - String path = "src/main/java/test.java"; - setFile(path).toResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test"); + FormatterStep step = KtLintStep.create("0.49.0", TestProvisioner.mavenCentral()); + StepHarnessWithFile.forStep(this, step) + .testResource("java/removewildcardimports/JavaCodeWildcardsUnformatted.test", "java/removewildcardimports/JavaCodeWildcardsFormatted.test") + .expectLintsOfResource("kotlin/ktlint/unsolvable.dirty").toBe("L1 ktlint(standard:no-wildcard-imports) Wildcard import"); + } + + @Test + void testRemoveWildcardImportsNoError() throws Exception { + setFile(PATH).toResource("java/removewildcardimports/JavaCodeNoWildcardsUnformatted.test"); + assertFile(PATH).sameAsResource("java/removewildcardimports/JavaCodeNoWildcardsUnformatted.test"); mavenRunner().withArguments("spotless:apply").runNoError(); - assertFile(path).sameAsResource("java/removewildcardimports/JavaCodeWildcardsFormatted.test"); } } diff --git a/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsFormatted.test b/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsFormatted.test new file mode 100644 index 0000000000..85ee903fc5 --- /dev/null +++ b/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsFormatted.test @@ -0,0 +1,4 @@ +import java.util.List; +import mylib.Helper; + +public class Test {} \ No newline at end of file diff --git a/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsUnformatted.test b/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsUnformatted.test new file mode 100644 index 0000000000..85ee903fc5 --- /dev/null +++ b/testlib/src/main/resources/java/removewildcardimports/JavaCodeNoWildcardsUnformatted.test @@ -0,0 +1,4 @@ +import java.util.List; +import mylib.Helper; + +public class Test {} \ No newline at end of file diff --git a/testlib/src/main/resources/java/removewildcardimports/JavaCodeWildcardsFormatted.test b/testlib/src/main/resources/java/removewildcardimports/JavaCodeWildcardsFormatted.test index 85ee903fc5..74646094ae 100644 --- a/testlib/src/main/resources/java/removewildcardimports/JavaCodeWildcardsFormatted.test +++ b/testlib/src/main/resources/java/removewildcardimports/JavaCodeWildcardsFormatted.test @@ -1,4 +1,9 @@ +import java.util.*; +import static java.util.Collections.*; import java.util.List; import mylib.Helper; +import io.quarkus.maven.dependency.*; +import static io.quarkus.vertx.web.Route.HttpMethod.*; +import static org.springframework.web.reactive.function.BodyInserters.*; public class Test {} \ No newline at end of file