From d5206b4b7d3c9f107cb7a4215262b597529523b9 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 21 Jan 2024 16:49:11 +0100 Subject: [PATCH 1/7] Add NoGuavaByteStreams Refaster recipe using Java 9+ --- build.gradle.kts | 13 ++++ .../resources/META-INF/rewrite/no-guava.yml | 1 + .../migrate/guava/NoGuavaByteStreams.java | 65 +++++++++++++++++ .../migrate/guava/NoGuavaByteStreamsTest.java | 70 +++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java create mode 100644 src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java diff --git a/build.gradle.kts b/build.gradle.kts index 91d7d64a5e..3b45d16f5b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -60,3 +60,16 @@ dependencies { testRuntimeOnly("org.codehaus.groovy:groovy:latest.release") testRuntimeOnly(gradleApi()) } + +// Add a source set for refaster rules that allows for Java 9+ syntax +sourceSets { + val refaster = create("refaster") { + java { + compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath + runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath + annotationProcessorPath += sourceSets.main.get().annotationProcessorPath + } + } + sourceSets.test.get().compileClasspath += refaster.output + sourceSets.test.get().runtimeClasspath += refaster.output +} diff --git a/src/main/resources/META-INF/rewrite/no-guava.yml b/src/main/resources/META-INF/rewrite/no-guava.yml index 12f1ed8a73..308350b92e 100644 --- a/src/main/resources/META-INF/rewrite/no-guava.yml +++ b/src/main/resources/META-INF/rewrite/no-guava.yml @@ -75,6 +75,7 @@ tags: - java11 recipeList: - org.openrewrite.java.migrate.guava.NoGuava + - org.openrewrite.java.migrate.guava.NoGuavaByteStreamsRecipes - org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsRequireNonNullElse --- type: specs.openrewrite.org/v1beta/recipe diff --git a/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java b/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java new file mode 100644 index 0000000000..d6e2e3e45d --- /dev/null +++ b/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * 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 + *

+ * https://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 org.openrewrite.java.migrate.guava; + +import com.google.common.io.ByteStreams; +import com.google.errorprone.refaster.annotation.AfterTemplate; +import com.google.errorprone.refaster.annotation.BeforeTemplate; +import org.openrewrite.java.template.RecipeDescriptor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +@RecipeDescriptor(name = "No Guava ByteStreams", + description = "Replaces Guava ByteStreams with Java 9+ alternatives.", + tags = "guava") +public class NoGuavaByteStreams { + private NoGuavaByteStreams() { + } + + @RecipeDescriptor( + name = "ByteStreams#copy", + description = "Replaces Guava `ByteStreams.copy` with `InputStream.transferTo`.", + tags = "guava") + static final class InputStreamTransferTo { + @BeforeTemplate + long before(InputStream in, OutputStream out) throws IOException { + return ByteStreams.copy(in, out); + } + + @AfterTemplate + long after(InputStream in, OutputStream out) throws IOException { + return in.transferTo(out); + } + } + + @RecipeDescriptor( + name = "ByteStreams#toByteArray", + description = "Replaces Guava `ByteStreams.toByteArray` with `InputStream.readAllBytes`.", + tags = "guava") + static final class InputStreamReadAllBytes { + @BeforeTemplate + byte[] before(InputStream in) throws IOException { + return ByteStreams.toByteArray(in); + } + + @AfterTemplate + byte[] after(InputStream in) throws IOException { + return in.readAllBytes(); + } + } +} diff --git a/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java new file mode 100644 index 0000000000..239c1fcc73 --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * 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 + *

+ * https://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 org.openrewrite.java.migrate.guava; + +import org.junit.jupiter.api.Test; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class NoGuavaByteStreamsTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec + .recipe(new NoGuavaByteStreamsRecipes()) + .parser(JavaParser.fromJavaVersion().classpath("guava")); + } + + @Test + void replace() { + rewriteRun( + //language=java + java( + """ + import com.google.common.io.ByteStreams; + import java.io.ByteArrayInputStream; + import java.io.ByteArrayOutputStream; + import java.io.IOException; + + class InputStreamRulesTest { + long testInputStreamTransferTo() throws IOException { + return ByteStreams.copy(new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream()); + } + byte[] testInputStreamReadAllBytes() throws IOException { + return ByteStreams.toByteArray(new ByteArrayInputStream(new byte[0])); + } + } + """, + """ + import java.io.ByteArrayInputStream; + import java.io.ByteArrayOutputStream; + import java.io.IOException; + + class InputStreamRulesTest { + long testInputStreamTransferTo() throws IOException { + return new ByteArrayInputStream(new byte[0]).transferTo(new ByteArrayOutputStream()); + } + byte[] testInputStreamReadAllBytes() throws IOException { + return new ByteArrayInputStream(new byte[0]).readAllBytes(); + } + } + """ + ) + ); + } +} From 25fb1d51341f118606078261a12632a7484d8cfd Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 21 Jan 2024 20:10:48 +0100 Subject: [PATCH 2/7] Minor polish --- .../migrate/guava/NoGuavaByteStreams.java | 4 +-- .../migrate/guava/NoGuavaByteStreamsTest.java | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java b/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java index d6e2e3e45d..15d74f763c 100644 --- a/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java +++ b/src/refaster/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreams.java @@ -35,7 +35,7 @@ private NoGuavaByteStreams() { name = "ByteStreams#copy", description = "Replaces Guava `ByteStreams.copy` with `InputStream.transferTo`.", tags = "guava") - static final class InputStreamTransferTo { + public static final class InputStreamTransferTo { @BeforeTemplate long before(InputStream in, OutputStream out) throws IOException { return ByteStreams.copy(in, out); @@ -51,7 +51,7 @@ long after(InputStream in, OutputStream out) throws IOException { name = "ByteStreams#toByteArray", description = "Replaces Guava `ByteStreams.toByteArray` with `InputStream.readAllBytes`.", tags = "guava") - static final class InputStreamReadAllBytes { + public static final class InputStreamReadAllBytes { @BeforeTemplate byte[] before(InputStream in) throws IOException { return ByteStreams.toByteArray(in); diff --git a/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java index 239c1fcc73..92f3af6057 100644 --- a/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java @@ -37,30 +37,31 @@ void replace() { java( """ import com.google.common.io.ByteStreams; - import java.io.ByteArrayInputStream; - import java.io.ByteArrayOutputStream; + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; - class InputStreamRulesTest { - long testInputStreamTransferTo() throws IOException { - return ByteStreams.copy(new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream()); + class Foo { + long testInputStreamTransferTo(InputStream from, OutputStream to) throws IOException { + return ByteStreams.copy(from, to); } - byte[] testInputStreamReadAllBytes() throws IOException { - return ByteStreams.toByteArray(new ByteArrayInputStream(new byte[0])); + byte[] testInputStreamReadAllBytes(InputStream from) throws IOException { + return ByteStreams.toByteArray(from); } } """, """ - import java.io.ByteArrayInputStream; - import java.io.ByteArrayOutputStream; import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; - class InputStreamRulesTest { - long testInputStreamTransferTo() throws IOException { - return new ByteArrayInputStream(new byte[0]).transferTo(new ByteArrayOutputStream()); + class Foo { + long testInputStreamTransferTo(InputStream from, OutputStream to) throws IOException { + return from.transferTo(to); } - byte[] testInputStreamReadAllBytes() throws IOException { - return new ByteArrayInputStream(new byte[0]).readAllBytes(); + byte[] testInputStreamReadAllBytes(InputStream from) throws IOException { + return from.readAllBytes(); } } """ From 8f236094c23d892f4984c9cffb6100a1e1c1960f Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 21 Jan 2024 20:26:43 +0100 Subject: [PATCH 3/7] Define a refaster configuration and pass in guava --- build.gradle.kts | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3b45d16f5b..97a2e4fb53 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,6 +7,26 @@ plugins { group = "org.openrewrite.recipe" description = "Migrate to later Java versions. Automatically." + +// Add a source set for refaster rules that allows for Java 9+ syntax +sourceSets { + val refaster = create("refaster") { + java { + annotationProcessorPath += sourceSets.main.get().annotationProcessorPath + compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath + runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath + } + } + sourceSets.test.get().compileClasspath += refaster.output + sourceSets.test.get().runtimeClasspath += refaster.output +} + +configurations { + create("refaster") { + extendsFrom(configurations.implementation.get()) + } +} + val rewriteVersion = rewriteRecipe.rewriteVersion.get() dependencies { compileOnly("org.projectlombok:lombok:latest.release") @@ -15,6 +35,7 @@ dependencies { annotationProcessor("org.projectlombok:lombok:latest.release") testImplementation("org.projectlombok:lombok:latest.release") + "refaster"("com.google.guava:guava:29.0-jre") annotationProcessor("org.openrewrite:rewrite-templating:$rewriteVersion") compileOnly("com.google.errorprone:error_prone_core:2.19.1:with-dependencies") { exclude("com.google.auto.service", "auto-service-annotations") @@ -59,17 +80,4 @@ dependencies { testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") testRuntimeOnly("org.codehaus.groovy:groovy:latest.release") testRuntimeOnly(gradleApi()) -} - -// Add a source set for refaster rules that allows for Java 9+ syntax -sourceSets { - val refaster = create("refaster") { - java { - compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath - runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath - annotationProcessorPath += sourceSets.main.get().annotationProcessorPath - } - } - sourceSets.test.get().compileClasspath += refaster.output - sourceSets.test.get().runtimeClasspath += refaster.output -} +} \ No newline at end of file From 35ee063bd737335515b516cd37297beab8270a44 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 21 Jan 2024 21:14:54 +0100 Subject: [PATCH 4/7] Drop `error_prone_core` qualifier `with-dependencies` --- build.gradle.kts | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 97a2e4fb53..ee03a48718 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,26 +7,6 @@ plugins { group = "org.openrewrite.recipe" description = "Migrate to later Java versions. Automatically." - -// Add a source set for refaster rules that allows for Java 9+ syntax -sourceSets { - val refaster = create("refaster") { - java { - annotationProcessorPath += sourceSets.main.get().annotationProcessorPath - compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath - runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath - } - } - sourceSets.test.get().compileClasspath += refaster.output - sourceSets.test.get().runtimeClasspath += refaster.output -} - -configurations { - create("refaster") { - extendsFrom(configurations.implementation.get()) - } -} - val rewriteVersion = rewriteRecipe.rewriteVersion.get() dependencies { compileOnly("org.projectlombok:lombok:latest.release") @@ -35,9 +15,8 @@ dependencies { annotationProcessor("org.projectlombok:lombok:latest.release") testImplementation("org.projectlombok:lombok:latest.release") - "refaster"("com.google.guava:guava:29.0-jre") annotationProcessor("org.openrewrite:rewrite-templating:$rewriteVersion") - compileOnly("com.google.errorprone:error_prone_core:2.19.1:with-dependencies") { + compileOnly("com.google.errorprone:error_prone_core:2.19.1") { exclude("com.google.auto.service", "auto-service-annotations") } @@ -80,4 +59,17 @@ dependencies { testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") testRuntimeOnly("org.codehaus.groovy:groovy:latest.release") testRuntimeOnly(gradleApi()) -} \ No newline at end of file +} + +// Add a source set for refaster rules that allows for Java 9+ syntax +sourceSets { + val refaster = create("refaster") { + java { + annotationProcessorPath += sourceSets.main.get().annotationProcessorPath + compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath + runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath + } + } + sourceSets.test.get().compileClasspath += refaster.output + sourceSets.test.get().runtimeClasspath += refaster.output +} From ce61091815b598688a15d6671ed47ce798577510 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 21 Jan 2024 21:33:21 +0100 Subject: [PATCH 5/7] Include refaster classes in jar --- build.gradle.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index ee03a48718..da92de470c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -73,3 +73,9 @@ sourceSets { sourceSets.test.get().compileClasspath += refaster.output sourceSets.test.get().runtimeClasspath += refaster.output } + +tasks { + withType{ + from(sourceSets["refaster"].output) + } +} From 2af80518e9fe858b9def0aeae7a66ada2b097ac3 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Mon, 22 Jan 2024 20:29:03 +0100 Subject: [PATCH 6/7] Use `sourceSets.registering` instead of `create` --- build.gradle.kts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index da92de470c..e643a427cd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,20 +62,21 @@ dependencies { } // Add a source set for refaster rules that allows for Java 9+ syntax -sourceSets { - val refaster = create("refaster") { - java { - annotationProcessorPath += sourceSets.main.get().annotationProcessorPath - compileClasspath += sourceSets.main.get().output + sourceSets.main.get().compileClasspath - runtimeClasspath += sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath - } +val refaster by sourceSets.registering { + java { + val main = sourceSets.main.get() + annotationProcessorPath += main.annotationProcessorPath + compileClasspath += main.output + main.compileClasspath + runtimeClasspath += main.output + main.runtimeClasspath } - sourceSets.test.get().compileClasspath += refaster.output - sourceSets.test.get().runtimeClasspath += refaster.output +} +sourceSets.named("test").configure { + compileClasspath += refaster.get().output.classesDirs + runtimeClasspath += refaster.get().output.classesDirs } tasks { - withType{ - from(sourceSets["refaster"].output) + jar { + from(refaster.get().output) } } From 9cabac23584d2867aa7ce6f8ed444d8591b7aa2b Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Mon, 4 Mar 2024 10:25:53 +0100 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java index 92f3af6057..2bff690bd5 100644 --- a/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/guava/NoGuavaByteStreamsTest.java @@ -16,6 +16,7 @@ package org.openrewrite.java.migrate.guava; import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; import org.openrewrite.java.JavaParser; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; @@ -30,6 +31,7 @@ public void defaults(RecipeSpec spec) { .parser(JavaParser.fromJavaVersion().classpath("guava")); } + @DocumentExample @Test void replace() { rewriteRun(