Skip to content

PoC: Add rewrite support for errorprone.refasterrules #2576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ concurrency:
cancel-in-progress: true
jobs:
sanityCheck:
name: spotlessCheck assemble testClasses
name: QA (spotlessCheck, assemble testClasses, rewriteDryRun)
runs-on: ubuntu-latest
env:
buildcacheuser: ${{ secrets.BUILDCACHE_USER }}
Expand All @@ -33,6 +33,8 @@ jobs:
run: ./gradlew spotlessCheck
- name: assemble testClasses
run: ./gradlew assemble testClasses
- name: rewriteDryRun
run: ./gradlew rewriteDryRun --build-cache --info
build:
needs: sanityCheck
strategy:
Expand Down Expand Up @@ -66,10 +68,10 @@ jobs:
uses: gradle/actions/setup-gradle@v4
- name: build (maven-only)
if: matrix.kind == 'maven'
run: ./gradlew :plugin-maven:build -x spotlessCheck
run: ./gradlew :plugin-maven:build -x spotlessCheck -x rewriteDryRun
- name: build (everything-but-maven)
if: matrix.kind == 'gradle'
run: ./gradlew build -x spotlessCheck -PSPOTLESS_EXCLUDE_MAVEN=true
run: ./gradlew build -x spotlessCheck -x rewriteDryRun -PSPOTLESS_EXCLUDE_MAVEN=true
- name: test npm
if: matrix.kind == 'npm'
run: ./gradlew testNpm
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
* Adds support for worktrees (fixes [#1765](https://github.com/diffplug/spotless/issues/1765))
* Bump default `google-java-format` version to latest `1.24.0` -> `1.28.0`. ([#2345](https://github.com/diffplug/spotless/pull/2345))
* Bump default `ktlint` version to latest `1.5.0` -> `1.7.1`. ([#2555](https://github.com/diffplug/spotless/pull/2555))
* PoC: Add `rewrite` support for `errorprone.refasterrules` ([#2576](https://github.com/diffplug/spotless/pull/2576))

## [3.3.1] - 2025-07-21
### Fixed
Expand Down
36 changes: 15 additions & 21 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
apply plugin: 'dev.equo.ide'
equoIde {
branding().title('Spotless').icon(file('_images/spotless_logo.png'))
welcome().openUrl('https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md')
gradleBuildship().autoImport('.')
}

repositories {
mavenCentral()
}

apply from: rootProject.file('gradle/java-publish.gradle')
apply from: rootProject.file('gradle/changelog.gradle')
apply from: rootProject.file('gradle/java-publish.gradle')
apply from: rootProject.file('gradle/spotless-freshmark.gradle')

allprojects {
apply from: rootProject.file('gradle/spotless.gradle')
apply from: rootProject.file('gradle/rewrite.gradle')
}

equoIde {
branding().title('Spotless').icon(file('_images/spotless_logo.png'))
welcome().openUrl('https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md')
gradleBuildship().autoImport('.')
}
apply from: rootProject.file('gradle/spotless-freshmark.gradle')

spotless {
groovyGradle {
target '*.gradle', 'gradle/*.gradle'
}
format 'dotfiles', {
target '.gitignore', '.gitattributes', '.editorconfig'
leadingTabsToSpaces(2)
trimTrailingWhitespace()
endWithNewline()
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-migrate-java:3.14.1")
rewrite("org.openrewrite.recipe:rewrite-rewrite:0.10.1")
rewrite("org.openrewrite.recipe:rewrite-static-analysis:2.14.0")
rewrite("org.openrewrite.recipe:rewrite-third-party:0.24.1")
}
49 changes: 49 additions & 0 deletions gradle/rewrite.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apply plugin: 'org.openrewrite.rewrite'

rewrite {
activeRecipe(
"org.openrewrite.gradle.GradleBestPractices",
"org.openrewrite.java.RemoveUnusedImports",
"org.openrewrite.java.format.RemoveTrailingWhitespace",
"org.openrewrite.java.recipes.JavaRecipeBestPractices",
"org.openrewrite.java.recipes.RecipeTestingBestPractices",
"org.openrewrite.staticanalysis.EmptyBlock",
"org.openrewrite.staticanalysis.EqualsAvoidsNull",
"org.openrewrite.staticanalysis.JavaApiBestPractices",
"org.openrewrite.staticanalysis.LowercasePackage",
"org.openrewrite.staticanalysis.MissingOverrideAnnotation",
"org.openrewrite.staticanalysis.ModifierOrder",
"org.openrewrite.staticanalysis.NoFinalizer",
"org.openrewrite.staticanalysis.RemoveCallsToSystemGc",
"org.openrewrite.staticanalysis.RemoveUnneededAssertion",
"org.openrewrite.staticanalysis.RemoveUnusedLocalVariables",
"org.openrewrite.staticanalysis.RemoveUnusedPrivateFields",
"org.openrewrite.staticanalysis.RemoveUnusedPrivateMethods",
"org.openrewrite.staticanalysis.StringLiteralEquality",
"org.openrewrite.staticanalysis.UnnecessaryParentheses",
"org.openrewrite.text.EndOfLineAtEndOfFile",
"tech.picnic.errorprone.refasterrules.BugCheckerRulesRecipes",
"tech.picnic.errorprone.refasterrules.CollectionRulesRecipes",
"tech.picnic.errorprone.refasterrules.FileRulesRecipes",
"tech.picnic.errorprone.refasterrules.NullRulesRecipes",
"tech.picnic.errorprone.refasterrules.StreamRulesRecipes",
"tech.picnic.errorprone.refasterrules.StringRulesRecipes",
"tech.picnic.errorprone.refasterrules.SuggestedFixRulesRecipes",
//"org.openrewrite.java.migrate.UpgradeToJava17",
//"org.openrewrite.staticanalysis.CodeCleanup",
//"org.openrewrite.staticanalysis.UnnecessaryThrows",
)
// bugs
exclusions.add("**AJacksonFormatterFunc.java")
exclusions.add("**NpmPathResolver.java")
exclusions.add("**NpmTestsWithoutNpmInstallationTest_gradle_node_plugin_example_*.gradle")
exclusions.add("**gradle/changelog.gradle")
exclusions.add("**gradle/java-publish.gradle")
exclusions.add("**lib-extra/build.gradle")
exclusions.add("**lib/build.gradle")
exclusions.add("**package-info.java")
exclusions.add("**plugin-maven/build.gradle")
exclusions.add("**settings.gradle")
exportDatatables = true
failOnDryRunResults = true
}
43 changes: 24 additions & 19 deletions gradle/spotless.gradle
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
apply plugin: 'com.diffplug.spotless'

spotless {
groovyGradle {
target '*.gradle', 'gradle/*.gradle'
greclipse().configFile rootProject.files('gradle/spotless.eclipseformat.xml', 'gradle/spotless.groovyformat.prefs')
}
format 'dotfiles', {
target '.gitignore', '.gitattributes', '.editorconfig'
leadingTabsToSpaces(2)
trimTrailingWhitespace()
endWithNewline()
}
def noInternalDepsClosure = {
String text = it
/*
* No good way to get around using this import:
* https://github.com/gradle/gradle/issues/3191
*/
String regex = "import org\\.gradle\\.api\\.internal\\.(?!plugins\\.DslObject)(?!project\\.ProjectInternal)"
if ((text.contains('import org.gradle.internal.') || text.find(regex)) &&
!text.contains('def noInternalDepsClosure')) {
if ((text.contains('import org.gradle.internal.') || text.find(regex))
&& !text.contains('def noInternalDepsClosure')) {
throw new AssertionError("Accidental internal import")
}
}
if (project != rootProject) {
// the rootProject doesn't have any java
java {
ratchetFrom 'origin/main'
bumpThisNumberIfACustomStepChanges(1)
licenseHeaderFile rootProject.file('gradle/spotless.license')
importOrderFile rootProject.file('gradle/spotless.importorder')
eclipse().configFile rootProject.file('gradle/spotless.eclipseformat.xml')
trimTrailingWhitespace()
removeUnusedImports()
formatAnnotations()
custom 'noInternalDeps', noInternalDepsClosure
}
}
groovyGradle {
target '*.gradle'
greclipse().configFile rootProject.files('gradle/spotless.eclipseformat.xml', 'gradle/spotless.groovyformat.prefs')
java {
target '*.gitignore'
ratchetFrom 'origin/main'
bumpThisNumberIfACustomStepChanges(1)
licenseHeaderFile rootProject.file('gradle/spotless.license')
importOrderFile rootProject.file('gradle/spotless.importorder')
eclipse().configFile rootProject.file('gradle/spotless.eclipseformat.xml')
trimTrailingWhitespace()
removeUnusedImports()
formatAnnotations()
custom 'noInternalDeps', noInternalDepsClosure
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ private boolean isSortPreserved(BodyDeclaration bodyDeclaration) {
}

private int preserveRelativeOrder(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclaration2) {
int value1 = ((Integer) bodyDeclaration1.getProperty(CompilationUnitSorter.RELATIVE_ORDER));
int value2 = ((Integer) bodyDeclaration2.getProperty(CompilationUnitSorter.RELATIVE_ORDER));
int value1 = (Integer) bodyDeclaration1.getProperty(CompilationUnitSorter.RELATIVE_ORDER);
int value2 = (Integer) bodyDeclaration2.getProperty(CompilationUnitSorter.RELATIVE_ORDER);
return value1 - value2;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ && isInterfaceOrAnnotationMember(bodyDeclaration))
}

private static boolean isPackageVisible(BodyDeclaration bodyDeclaration) {
return (!isPrivate(bodyDeclaration) && !isProtected(bodyDeclaration) && !isPublic(bodyDeclaration));
return !isPrivate(bodyDeclaration) && !isProtected(bodyDeclaration) && !isPublic(bodyDeclaration);
}

private static boolean isPrivate(BodyDeclaration bodyDeclaration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -127,7 +122,7 @@ public FormatterStep build() {
var roundtrippableState = new EquoStep(formatterVersion, settingProperties, settingXml, FileSignature.promise(settingsFiles), JarState.promise(() -> {
P2QueryResult query;
try {
if (null != cacheDirectory) {
if (cacheDirectory != null) {
CacheLocations.override_p2data = cacheDirectory.toPath().resolve("dev/equo/p2-data").toFile();
}
query = createModelWithMirrors().query(P2ClientCache.PREFER_OFFLINE, P2QueryCache.ALLOW);
Expand Down Expand Up @@ -190,8 +185,8 @@ static class EquoStep implements Serializable {
ImmutableMap<String, String> stepProperties) {

this.semanticVersion = semanticVersion;
this.settingProperties = Optional.ofNullable(settingProperties).orElse(new ArrayList<>());
this.settingXml = Optional.ofNullable(settingXml).orElse(new ArrayList<>());
this.settingProperties = Objects.requireNonNullElse(settingProperties, new ArrayList<>());
this.settingXml = Objects.requireNonNullElse(settingXml, new ArrayList<>());
this.settingsPromise = settingsPromise;
this.jarPromise = jarPromise;
this.stepProperties = stepProperties;
Expand All @@ -218,8 +213,8 @@ public static class State implements Serializable {
public State(String semanticVersion, JarState jarState, List<String> settingProperties, List<String> settingXml, FileSignature settingsFiles, ImmutableMap<String, String> stepProperties) {
this.semanticVersion = semanticVersion;
this.jarState = jarState;
this.settingProperties = Optional.ofNullable(settingProperties).orElse(new ArrayList<>());
this.settingXml = Optional.ofNullable(settingXml).orElse(new ArrayList<>());
this.settingProperties = Objects.requireNonNullElse(settingProperties, new ArrayList<>());
this.settingXml = Objects.requireNonNullElse(settingXml, new ArrayList<>());
this.settingsFiles = settingsFiles;
this.stepProperties = stepProperties;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,15 @@ static class CachedEndings implements Serializable {
private static final long serialVersionUID = -2534772773057900619L;

/** this is transient, to simulate PathSensitive.RELATIVE */
transient final String rootDir;
final transient String rootDir;
/** the line ending used for most files */
final String defaultEnding;
/** any exceptions to that default, in terms of relative path from rootDir */
final ConcurrentRadixTree<String> hasNonDefaultEnding = new ConcurrentRadixTree<>(new DefaultCharSequenceNodeFactory());

CachedEndings(File projectDir, Runtime runtime, Iterable<File> toFormat) {
String rootPath = FileSignature.pathNativeToUnix(projectDir.getAbsolutePath());
rootDir = rootPath.equals("/") ? rootPath : rootPath + "/";
rootDir = "/".equals(rootPath) ? rootPath : rootPath + "/";
defaultEnding = runtime.defaultEnding;
for (File file : toFormat) {
String ending = runtime.getEndingFor(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ private static boolean worktreeIsCleanCheckout(TreeWalk treeWalk) {
return treeWalk.idEqual(TREE, WORKDIR);
}

private final static int TREE = 0;
private final static int INDEX = 1;
private final static int WORKDIR = 2;
private static final int TREE = 0;
private static final int INDEX = 1;
private static final int WORKDIR = 2;

Map<File, Repository> gitRoots = new HashMap<>();
Table<Repository, String, ObjectId> rootTreeShaCache = HashBasedTable.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ private static FormatterFunc apply(EquoBasedStepBuilder.State state) throws Exce
return (String) method.invoke(formatter, input);
} catch (InvocationTargetException exceptionWrapper) {
Throwable throwable = exceptionWrapper.getTargetException();
Exception exception = (throwable instanceof Exception) ? (Exception) throwable : null;
throw (null == exception) ? exceptionWrapper : exception;
Exception exception = throwable instanceof Exception ? (Exception) throwable : null;
throw exception == null ? exceptionWrapper : exception;
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ private static FormatterFunc apply(EquoBasedStepBuilder.State state) throws Exce
return (String) method.invoke(formatter, input);
} catch (InvocationTargetException exceptionWrapper) {
Throwable throwable = exceptionWrapper.getTargetException();
Exception exception = (throwable instanceof Exception) ? (Exception) throwable : null;
throw (null == exception) ? exceptionWrapper : exception;
Exception exception = throwable instanceof Exception ? (Exception) throwable : null;
throw exception == null ? exceptionWrapper : exception;
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public static Map.Entry<Integer, String> diff(Path rootDir, Formatter formatter,
}

private static Map.Entry<Integer, String> diff(CleanProvider formatter, File file) throws IOException {
String raw = new String(Files.readAllBytes(file.toPath()), formatter.getEncoding());
String raw = Files.readString(file.toPath(), formatter.getEncoding());
String rawUnix = LineEnding.toUnix(raw);
String formatted = formatter.getFormatted(file, rawUnix);
String formattedUnix = LineEnding.toUnix(formatted);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ private static FormatterFunc applyWithoutFile(String className, EclipseBasedStep
return (String) method.invoke(formatter, input);
} catch (InvocationTargetException exceptionWrapper) {
Throwable throwable = exceptionWrapper.getTargetException();
Exception exception = (throwable instanceof Exception) ? (Exception) throwable : null;
throw (null == exception) ? exceptionWrapper : exception;
Exception exception = throwable instanceof Exception ? (Exception) throwable : null;
throw exception == null ? exceptionWrapper : exception;
}
};
}
Expand All @@ -85,8 +85,8 @@ public String applyWithFile(String unix, File file) throws Exception {
return (String) method.invoke(formatter, unix, file.getAbsolutePath());
} catch (InvocationTargetException exceptionWrapper) {
Throwable throwable = exceptionWrapper.getTargetException();
Exception exception = (throwable instanceof Exception) ? (Exception) throwable : null;
throw (null == exception) ? exceptionWrapper : exception;
Exception exception = throwable instanceof Exception ? (Exception) throwable : null;
throw exception == null ? exceptionWrapper : exception;
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import com.diffplug.spotless.extra.eclipse.EquoResourceHarness;

public class GrEclipseFormatterStepTest extends EquoResourceHarness {
private final static String INPUT = "class F{ def m(){} }";
private final static String EXPECTED = "class F{\n\tdef m(){}\n}";
private static final String INPUT = "class F{ def m(){} }";
private static final String EXPECTED = "class F{\n\tdef m(){}\n}";

public GrEclipseFormatterStepTest() {
super(GrEclipseFormatterStep.createBuilder(TestProvisioner.mavenCentral()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Properties;
import java.util.function.Consumer;
import java.util.stream.Stream;
Expand All @@ -33,7 +34,7 @@
import com.diffplug.spotless.extra.eclipse.EclipseResourceHarness;

public class EclipseWtpFormatterStepTest {
private final static Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support("Oldest Version").add(8, "4.8.0");
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support("Oldest Version").add(8, "4.8.0");

private static class NestedTests extends EclipseResourceHarness {
private final String unformatted, formatted;
Expand Down Expand Up @@ -76,7 +77,7 @@ void multipleConfigurations() throws Exception {
private File createPropertyFile(Consumer<Properties> config) throws IOException {
Properties configProps = new Properties();
config.accept(configProps);
File tempFile = File.createTempFile("EclipseWtpFormatterStepTest-", ".properties");
File tempFile = Files.createTempFile("EclipseWtpFormatterStepTest-", ".properties").toFile();
OutputStream tempOut = new FileOutputStream(tempFile);
configProps.store(tempOut, "test properties");
tempOut.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protected 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>
*/
@Override
protected JsonFactory makeJsonFactory() {
JsonFactory jsonFactory = new JsonFactoryBuilder().build();

Expand Down
Loading
Loading