diff --git a/.gitignore b/.gitignore
index 261a2e0..7318773 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,6 @@
.mtj.tmp/
# Package Files #
-*.jar
*.war
*.nar
*.ear
diff --git a/build.gradle.kts b/build.gradle.kts
index f2f3363..b8a0bd7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -19,5 +19,11 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-engine:latest.release")
- testImplementation("com.launchdarkly:launchdarkly-java-server-sdk:5.10.+")
+ testRuntimeOnly("org.gradle:gradle-tooling-api:latest.release")
}
+
+recipeDependencies {
+ parserClasspath("com.launchdarkly:launchdarkly-java-server-sdk:5.10.+")
+ parserClasspath("com.launchdarkly:launchdarkly-java-server-sdk:6.+")
+ //parserClasspath("com.launchdarkly:launchdarkly-java-server-sdk:7.+")
+}
\ No newline at end of file
diff --git a/src/main/java/org/openrewrite/launchdarkly/MigrateUserToContext.java b/src/main/java/org/openrewrite/launchdarkly/MigrateUserToContext.java
new file mode 100644
index 0000000..0ff577b
--- /dev/null
+++ b/src/main/java/org/openrewrite/launchdarkly/MigrateUserToContext.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2023 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.launchdarkly;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+import org.openrewrite.*;
+import org.openrewrite.internal.StringUtils;
+import org.openrewrite.java.*;
+import org.openrewrite.java.search.UsesType;
+import org.openrewrite.java.tree.Expression;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.JavaType;
+import org.openrewrite.java.tree.Space;
+import org.openrewrite.marker.Markers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static java.util.Objects.requireNonNull;
+
+@Value
+@EqualsAndHashCode(callSuper = true)
+public class MigrateUserToContext extends Recipe {
+ private static final MethodMatcher NEW_USER = new MethodMatcher("com.launchdarkly.sdk.LDUser (java.lang.String)");
+ private static final MethodMatcher NEW_USER_BUILDER = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder (java.lang.String)");
+
+ private static final List BASIC_ATTRIBUTES = Arrays.asList("avatar", "country", "email", "firstName", "ip", "lastName");
+ private static final List PRIVATE_ATTRIBUTES = Arrays.asList("privateAvatar", "privateCountry", "privateEmail", "privateFirstName", "privateIp", "privateLastName", "privateName");
+ private static final MethodMatcher BUILTIN_ATTRIBUTE = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder *(java.lang.String)");
+ private static final MethodMatcher BUILTIN_PRIVATE_ATTRIBUTE = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder private*(java.lang.String)");
+ private static final MethodMatcher CUSTOM_ATTRIBUTES = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder custom(java.lang.String, ..)"); // FIXME: This really should be `*`
+ private static final MethodMatcher PRIVATE_CUSTOM_ATTRIBUTES = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder privateCustom(java.lang.String, ..)"); // FIXME: This really should be `*`
+
+ @Override
+ public String getDisplayName() {
+ return "Migrate `LDUser` to `LDContext`";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Migrate from `LDUser` and `LDUser.Builder` to `LDContext` and `ContextBuilder`.";
+ }
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ return Preconditions.check(
+ new UsesType<>("com.launchdarkly.sdk.LDUser", null),
+ new JavaVisitor() {
+ @Override
+ public J visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
+ if (NEW_USER.matches(newClass)) {
+ maybeRemoveImport("com.launchdarkly.sdk.LDUser");
+ maybeAddImport("com.launchdarkly.sdk.LDContext");
+ doAfterVisit(new ChangeType("com.launchdarkly.sdk.LDUser", "com.launchdarkly.sdk.LDContext", null).getVisitor());
+ return JavaTemplate.builder("LDContext.create(#{any(java.lang.String)})")
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.LDContext")
+ .build()
+ .apply(getCursor(), newClass.getCoordinates().replace(), newClass.getArguments().get(0));
+ } else if (NEW_USER_BUILDER.matches(newClass)) {
+ maybeRemoveImport("com.launchdarkly.sdk.LDUser");
+ maybeAddImport("com.launchdarkly.sdk.LDContext");
+ doAfterVisit(new ChangeType("com.launchdarkly.sdk.LDUser", "com.launchdarkly.sdk.LDContext", null).getVisitor());
+ return JavaTemplate.builder("LDContext.builder(#{any(java.lang.String)})")
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.LDContext")
+ .build()
+ .apply(getCursor(), newClass.getCoordinates().replace(), newClass.getArguments().get(0));
+ }
+
+ return super.visitNewClass(newClass, ctx);
+ }
+
+ @Override
+ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
+ J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
+ if (BUILTIN_ATTRIBUTE.matches(m) && BASIC_ATTRIBUTES.contains(m.getSimpleName())) {
+ String code;
+ if (requireNonNull(m.getPadding().getSelect()).getAfter().getWhitespace().contains("\n")) {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}\n.set(#{any(java.lang.String)}, #{any()})";
+ } else {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}.set(#{any(java.lang.String)}, #{any()})";
+ }
+ return JavaTemplate.builder(code)
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.ContextBuilder")
+ .build()
+ .apply(
+ getCursor(),
+ m.getCoordinates().replace(),
+ m.getSelect(),
+ new J.Literal(Tree.randomId(), Space.EMPTY, Markers.EMPTY, m.getSimpleName(), "\"" + m.getSimpleName() + "\"", null, JavaType.Primitive.String),
+ m.getArguments().get(0)
+ );
+ } else if (BUILTIN_PRIVATE_ATTRIBUTE.matches(m) && PRIVATE_ATTRIBUTES.contains(m.getSimpleName())) {
+ doAfterVisit(new UseVarargsForPrivateAttributes());
+
+ String code;
+ if (requireNonNull(m.getPadding().getSelect()).getAfter().getWhitespace().contains("\n")) {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}\n.set(#{any(java.lang.String)}, #{any()})\n.privateAttributes(#{any(java.lang.String)})";
+ } else {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}.set(#{any(java.lang.String)}, #{any()}).privateAttributes(#{any(java.lang.String)})";
+ }
+ String attributeName = StringUtils.uncapitalize(m.getSimpleName().replace("private", ""));
+ return JavaTemplate.builder(code)
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.ContextBuilder")
+ .build()
+ .apply(
+ getCursor(),
+ m.getCoordinates().replace(),
+ m.getSelect(),
+ new J.Literal(Tree.randomId(), Space.EMPTY, Markers.EMPTY, attributeName, "\"" + attributeName + "\"", null, JavaType.Primitive.String),
+ m.getArguments().get(0),
+ new J.Literal(Tree.randomId(), Space.EMPTY, Markers.EMPTY, attributeName, "\"" + attributeName + "\"", null, JavaType.Primitive.String)
+ );
+ } else if (CUSTOM_ATTRIBUTES.matches(m)) {
+ String code;
+ if (requireNonNull(m.getPadding().getSelect()).getAfter().getWhitespace().contains("\n")) {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}\n.set(#{any(java.lang.String)}, #{any()})";
+ } else {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}.set(#{any(java.lang.String)}, #{any()})";
+ }
+ return JavaTemplate.builder(code)
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.ContextBuilder")
+ .build()
+ .apply(getCursor(), m.getCoordinates().replace(), m.getSelect(), m.getArguments().get(0), m.getArguments().get(1));
+ } else if (PRIVATE_CUSTOM_ATTRIBUTES.matches(m)) {
+ doAfterVisit(new UseVarargsForPrivateAttributes());
+
+ String code;
+ if (requireNonNull(m.getPadding().getSelect()).getAfter().getWhitespace().contains("\n")) {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}\n.set(#{any(java.lang.String)}, #{any()})\n.privateAttributes(#{any(java.lang.String)})";
+ } else {
+ code = "#{any(com.launchdarkly.sdk.ContextBuilder)}.set(#{any(java.lang.String)}, #{any()}).privateAttributes(#{any(java.lang.String)})";
+ }
+ return JavaTemplate.builder(code)
+ .contextSensitive()
+ .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "launchdarkly-java-server-sdk-6"))
+ .imports("com.launchdarkly.sdk.ContextBuilder")
+ .build()
+ .apply(getCursor(), m.getCoordinates().replace(), m.getSelect(), m.getArguments().get(0), m.getArguments().get(1), m.getArguments().get(0));
+ }
+ return m;
+ }
+ }
+ );
+ }
+
+ private static class UseVarargsForPrivateAttributes extends JavaIsoVisitor {
+ private static final MethodMatcher CONTEXT_BUILDER_MATCHER = new MethodMatcher("com.launchdarkly.sdk.ContextBuilder *(..)");
+ private static final MethodMatcher PRIVATE_ATTRIBUTES_STRING_VARARGS_MATCHER = new MethodMatcher("com.launchdarkly.sdk.ContextBuilder privateAttributes(java.lang.String...)");
+ private static final MethodMatcher USER_BUILDER_BUILD_MATCHER = new MethodMatcher("com.launchdarkly.sdk.LDUser.Builder build()");
+ private static final MethodMatcher CONTEXT_BUILDER_BUILD_MATCHER = new MethodMatcher("com.launchdarkly.sdk.ContextBuilder build()");
+
+ @Override
+ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
+ J.MethodInvocation m = super.visitMethodInvocation(method, ctx);
+ if (!(USER_BUILDER_BUILD_MATCHER.matches(m) || CONTEXT_BUILDER_BUILD_MATCHER.matches(m))) {
+ return m;
+ }
+
+ List chain = computeChain(m);
+ return unfold(m, chain);
+ }
+
+ private List computeChain(J.MethodInvocation build) {
+ List chain = new ArrayList<>();
+ if (!(build.getSelect() instanceof J.MethodInvocation)) {
+ return chain;
+ }
+
+ List attributes = new ArrayList<>();
+ Expression select = build.getSelect();
+ int privateAttributesInvocations = 0;
+ int lastPrivateAttributesIdx = -1;
+ while (CONTEXT_BUILDER_MATCHER.matches(select)) {
+ J.MethodInvocation m = (J.MethodInvocation) select;
+ if (PRIVATE_ATTRIBUTES_STRING_VARARGS_MATCHER.matches(m)) {
+ if (lastPrivateAttributesIdx == -1 && CONTEXT_BUILDER_MATCHER.matches(m.getSelect())) {
+ lastPrivateAttributesIdx = chain.size();
+ chain.add(m);
+ }
+ attributes.addAll(0, m.getArguments());
+ privateAttributesInvocations++;
+ } else {
+ chain.add(m);
+ }
+ select = m.getSelect();
+ }
+ if (privateAttributesInvocations <= 1) {
+ return Collections.emptyList();
+ }
+ for (int i = 1; i < attributes.size(); i++) {
+ attributes.set(i, attributes.get(i).withPrefix(Space.SINGLE_SPACE));
+ }
+ chain.set(lastPrivateAttributesIdx, chain.get(lastPrivateAttributesIdx).withArguments(attributes));
+ return chain;
+ }
+
+ private J.MethodInvocation unfold(J.MethodInvocation build, List chain) {
+ if (chain.isEmpty()) {
+ return build;
+ }
+ Collections.reverse(chain);
+
+ J.MethodInvocation select = chain.get(0);
+ for (int i = 1; i < chain.size(); i++) {
+ select = chain.get(i)
+ .withId(Tree.randomId())
+ .withSelect(select);
+ }
+ return build.withSelect(select);
+ }
+ }
+}
diff --git a/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-5.10.9.jar b/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-5.10.9.jar
new file mode 100644
index 0000000..b04b6d0
Binary files /dev/null and b/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-5.10.9.jar differ
diff --git a/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-6.3.0.jar b/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-6.3.0.jar
new file mode 100644
index 0000000..e156e59
Binary files /dev/null and b/src/main/resources/META-INF/rewrite/classpath/launchdarkly-java-server-sdk-6.3.0.jar differ
diff --git a/src/main/resources/META-INF/rewrite/launchdarkly-6.yml b/src/main/resources/META-INF/rewrite/launchdarkly-6.yml
index 8d8e90d..2068be9 100644
--- a/src/main/resources/META-INF/rewrite/launchdarkly-6.yml
+++ b/src/main/resources/META-INF/rewrite/launchdarkly-6.yml
@@ -21,15 +21,8 @@ displayName: Migrate to LaunchDarkly 6.x
description: This recipe will apply changes commonly needed when migrating to LaunchDarkly 6.x.
recipeList:
# https://docs.launchdarkly.com/sdk/server-side/java/migration-5-to-6
- - org.openrewrite.launchdarkly.UpgradeLaunchDarkly6Dependencies
-
----
-type: specs.openrewrite.org/v1beta/recipe
-name: org.openrewrite.launchdarkly.UpgradeLaunchDarkly6Dependencies
-displayName: Migrate LaunchDarkly dependencies to 6.x
-description: Migrate LaunchDarkly dependencies to 6.x.
-recipeList:
- - org.openrewrite.java.dependencies.ChangeDependency:
- oldGroupId: com.launchdarkly
- oldArtifactId: launchdarkly-java-server-sdk
+ - org.openrewrite.java.dependencies.UpgradeDependencyVersion:
+ groupId: com.launchdarkly
+ artifactId: launchdarkly-java-server-sdk
newVersion: 6.x
+ - org.openrewrite.launchdarkly.MigrateUserToContext
diff --git a/src/main/resources/META-INF/rewrite/launchdarkly-7.yml b/src/main/resources/META-INF/rewrite/launchdarkly-7.yml
new file mode 100644
index 0000000..21686cd
--- /dev/null
+++ b/src/main/resources/META-INF/rewrite/launchdarkly-7.yml
@@ -0,0 +1,28 @@
+#
+# Copyright 2023 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.
+#
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.launchdarkly.UpgradeLaunchDarkly7
+displayName: Migrate to LaunchDarkly 7.x
+description: This recipe will apply changes commonly needed when migrating to LaunchDarkly 7.x.
+recipeList:
+ - org.openrewrite.launchdarkly.UpgradeLaunchDarkly6
+ # https://docs.launchdarkly.com/sdk/server-side/java/migration-6-to-7
+ - org.openrewrite.java.dependencies.UpgradeDependencyVersion:
+ groupId: com.launchdarkly
+ artifactId: launchdarkly-java-server-sdk
+ newVersion: 7.x
diff --git a/src/test/java/org/openrewrite/launchdarkly/MigrateUserToContextTest.java b/src/test/java/org/openrewrite/launchdarkly/MigrateUserToContextTest.java
new file mode 100644
index 0000000..ea8b23d
--- /dev/null
+++ b/src/test/java/org/openrewrite/launchdarkly/MigrateUserToContextTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2021 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.launchdarkly;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+
+import static org.openrewrite.java.Assertions.java;
+
+class MigrateUserToContextTest implements RewriteTest {
+
+ @Override
+ public void defaults(RecipeSpec spec) {
+ spec.recipe(new MigrateUserToContext())
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "launchdarkly-java-server-sdk-5"));
+ }
+
+ @Test
+ @DocumentExample
+ void builderUserToContext() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.launchdarkly.sdk.LDUser;
+ import com.launchdarkly.sdk.LDValue;
+
+ class A {
+ void foo() {
+ LDUser user = new LDUser.Builder("user-key-123abc")
+ .name("Sandy")
+ .email("sandy@example.com")
+ .custom("groups", LDValue.buildArray().add("Google").add("Microsoft").build())
+ .build();
+ }
+ }
+ """,
+ """
+ import com.launchdarkly.sdk.LDContext;
+ import com.launchdarkly.sdk.LDValue;
+
+ class A {
+ void foo() {
+ LDContext user = LDContext.builder("user-key-123abc")
+ .name("Sandy")
+ .set("email", "sandy@example.com")
+ .set("groups", LDValue.buildArray().add("Google").add("Microsoft").build())
+ .build();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void userToContext() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.launchdarkly.sdk.LDUser;
+
+ class A {
+ void foo() {
+ LDUser user = new LDUser("user-key-123abc");
+ }
+ }
+ """,
+ """
+ import com.launchdarkly.sdk.LDContext;
+
+ class A {
+ void foo() {
+ LDContext user = LDContext.create("user-key-123abc");
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void privateAttribute() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.launchdarkly.sdk.LDUser;
+ import com.launchdarkly.sdk.LDValue;
+
+ class A {
+ void foo() {
+ LDUser user = new LDUser.Builder("user-key-123abc")
+ .name("Sandy")
+ .privateEmail("sandy@example.com")
+ .privateCustom("groups", LDValue.buildArray().add("Google").add("Microsoft").build())
+ .build();
+ }
+ }
+ """,
+ """
+ import com.launchdarkly.sdk.LDContext;
+ import com.launchdarkly.sdk.LDValue;
+
+ class A {
+ void foo() {
+ LDContext user = LDContext.builder("user-key-123abc")
+ .name("Sandy")
+ .set("email", "sandy@example.com")
+ .set("groups", LDValue.buildArray().add("Google").add("Microsoft").build())
+ .privateAttributes("email", "groups")
+ .build();
+ }
+ }
+ """
+ )
+ );
+ }
+}
diff --git a/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly6Test.java b/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly6Test.java
index fe204b2..4c7cf34 100644
--- a/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly6Test.java
+++ b/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly6Test.java
@@ -15,11 +15,9 @@
*/
package org.openrewrite.launchdarkly;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
-import org.openrewrite.config.Environment;
+import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;
@@ -28,108 +26,104 @@
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.gradle.Assertions.buildGradle;
+import static org.openrewrite.gradle.Assertions.withToolingApi;
import static org.openrewrite.maven.Assertions.pomXml;
class UpgradeLaunchDarkly6Test implements RewriteTest {
-
@Override
public void defaults(RecipeSpec spec) {
- spec.recipe(Environment.builder()
- .scanRuntimeClasspath("org.openrewrite.launchdarkly")
- .build()
- .activateRecipes("org.openrewrite.launchdarkly.UpgradeLaunchDarkly6"))
- .parser(JavaParser.fromJavaVersion().classpath("launchdarkly-java-server-sdk"));
+ spec.recipeFromResource("/META-INF/rewrite/launchdarkly-6.yml", "org.openrewrite.launchdarkly.UpgradeLaunchDarkly6")
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "launchdarkly-java-server-sdk-5"));
}
- @Nested
- class Dependencies {
- @Test
- @DocumentExample
- void mavenDependency() {
- rewriteRun(
- //language=xml
- pomXml(
- """
-
-
- 4.0.0
- com.example
- demo
- 0.0.1-SNAPSHOT
-
-
- com.launchdarkly
- launchdarkly-java-server-sdk
- 5.10.9
-
-
-
- """,
- spec -> spec.after(actual -> {
- Matcher matcher = Pattern.compile("(6\\.\\d\\.\\d+)").matcher(actual);
- assertTrue(matcher.find(), actual);
- return """
-
-
- 4.0.0
- com.example
- demo
- 0.0.1-SNAPSHOT
-
-
- com.launchdarkly
- launchdarkly-java-server-sdk
- %s
-
-
-
- """.formatted(matcher.group(1));
- }
- )
- )
- );
- }
+ @Test
+ @DocumentExample("Maven")
+ void mavenDependency() {
+ rewriteRun(
+ //language=xml
+ pomXml(
+ """
+
+
+ 4.0.0
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+
+
+ com.launchdarkly
+ launchdarkly-java-server-sdk
+ 5.10.9
+
+
+
+ """,
+ spec -> spec.after(actual -> {
+ Matcher matcher = Pattern.compile("(6\\.\\d\\.\\d+)").matcher(actual);
+ assertTrue(matcher.find(), actual);
+ return """
+
+
+ 4.0.0
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+
+
+ com.launchdarkly
+ launchdarkly-java-server-sdk
+ %s
+
+
+
+ """.formatted(matcher.group(1));
+ }
+ )
+ )
+ );
}
-
- @Nested
- class CodeChanges {
- @Test
- @DocumentExample
- @Disabled("Not yet implemented")
- void userToContext() {
- rewriteRun(
- //language=java
- java(
- """
- class A {
- void foo() {
- LDUser user = new LDUser.Builder("user-key-123abc")
- .name("Sandy")
- .email("sandy@example.com")
- .custom("groups",
- LDValue.buildArray().add("Google").add("Microsoft").build())
- .build();
+ @Test
+ @DocumentExample("Gradle")
+ void gradleDependency() {
+ rewriteRun(
+ spec -> spec.beforeRecipe(withToolingApi()),
+ buildGradle(
+ """
+ plugins {
+ id "java"
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation "com.launchdarkly:launchdarkly-java-server-sdk:5.10.9"
+ }
+ """,
+ spec -> spec.after(actual -> {
+ Matcher matcher = Pattern.compile("com\\.launchdarkly:launchdarkly-java-server-sdk:(6\\.\\d+\\.\\d+)").matcher(actual);
+ assertTrue(matcher.find(), actual);
+ return """
+ plugins {
+ id "java"
+ }
+
+ repositories {
+ mavenCentral()
}
- }
- """,
- """
- class A {
- void foo() {
- LDContext context = LDContext.builder("user-key-123abc")
- .name("Sandy")
- .set("email", "sandy@example.com")
- .set("groups",
- LDValue.buildArray().add("Google").add("Microsoft").build())
- .build();
+
+ dependencies {
+ implementation "com.launchdarkly:launchdarkly-java-server-sdk:%s"
}
- }
- """
- )
- );
- }
+ """.formatted(matcher.group(1));
+ }
+ )
+ )
+ );
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly7Test.java b/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly7Test.java
new file mode 100644
index 0000000..7ed5b14
--- /dev/null
+++ b/src/test/java/org/openrewrite/launchdarkly/UpgradeLaunchDarkly7Test.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2021 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.launchdarkly;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.config.Environment;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.openrewrite.gradle.Assertions.buildGradle;
+import static org.openrewrite.gradle.Assertions.withToolingApi;
+import static org.openrewrite.maven.Assertions.pomXml;
+
+class UpgradeLaunchDarkly7Test implements RewriteTest {
+
+ @Override
+ public void defaults(RecipeSpec spec) {
+ spec.recipe(Environment.builder()
+ .scanRuntimeClasspath("org.openrewrite.launchdarkly")
+ .build()
+ .activateRecipes("org.openrewrite.launchdarkly.UpgradeLaunchDarkly7"))
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "launchdarkly-java-server-sdk-6"));
+ }
+
+ @Nested
+ class Dependencies {
+ @Test
+ @DocumentExample("Maven")
+ void mavenDependency() {
+ rewriteRun(
+ //language=xml
+ pomXml(
+ """
+
+
+ 4.0.0
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+
+
+ com.launchdarkly
+ launchdarkly-java-server-sdk
+ 6.3.0
+
+
+
+ """,
+ spec -> spec.after(actual -> {
+ Matcher matcher = Pattern.compile("(7\\.\\d\\.\\d+)").matcher(actual);
+ assertTrue(matcher.find(), actual);
+ return """
+
+
+ 4.0.0
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+
+
+ com.launchdarkly
+ launchdarkly-java-server-sdk
+ %s
+
+
+
+ """.formatted(matcher.group(1));
+ }
+ )
+ )
+ );
+ }
+
+ @Test
+ @DocumentExample("Gradle")
+ void gradleDependency() {
+ rewriteRun(
+ spec -> spec.beforeRecipe(withToolingApi()),
+ buildGradle(
+ """
+ plugins {
+ id "java"
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation "com.launchdarkly:launchdarkly-java-server-sdk:6.3.0"
+ }
+ """,
+ spec -> spec.after(actual -> {
+ Matcher matcher = Pattern.compile("com\\.launchdarkly:launchdarkly-java-server-sdk:(7\\.\\d+\\.\\d+)").matcher(actual);
+ assertTrue(matcher.find(), actual);
+ return """
+ plugins {
+ id "java"
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation "com.launchdarkly:launchdarkly-java-server-sdk:%s"
+ }
+ """.formatted(matcher.group(1));
+ }
+ )
+ )
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/openrewrite/launchdarkly/search/FindFeatureFlagTest.java b/src/test/java/org/openrewrite/launchdarkly/search/FindFeatureFlagTest.java
index 5fb0ad8..6e0286f 100644
--- a/src/test/java/org/openrewrite/launchdarkly/search/FindFeatureFlagTest.java
+++ b/src/test/java/org/openrewrite/launchdarkly/search/FindFeatureFlagTest.java
@@ -17,6 +17,7 @@
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;
@@ -26,7 +27,7 @@
class FindFeatureFlagTest implements RewriteTest {
@Override
public void defaults(RecipeSpec spec) {
- spec.parser(JavaParser.fromJavaVersion().classpath("launchdarkly-java-server-sdk"));
+ spec.parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "launchdarkly-java-server-sdk-5"));
}
@Test
@@ -34,6 +35,7 @@ public void defaults(RecipeSpec spec) {
void findFeatureFlag() {
rewriteRun(
spec -> spec.recipe(new FindFeatureFlag(null, null)),
+ //language=java
java(
"""
import com.launchdarkly.sdk.LDUser;
@@ -81,6 +83,7 @@ public void a() {
void findFeatureFlagByType() {
rewriteRun(
spec -> spec.recipe(new FindFeatureFlag(FindFeatureFlag.FeatureFlagType.Bool, null)),
+ //language=java
java(
"""
import com.launchdarkly.sdk.LDUser;
@@ -140,6 +143,7 @@ public void a() {
void findFeatureFlagByName() {
rewriteRun(
spec -> spec.recipe(new FindFeatureFlag(null, "flag-key-123abc")),
+ //language=java
java(
"""
import com.launchdarkly.sdk.LDUser;
@@ -199,6 +203,7 @@ public void a() {
void findFeatureFlagByTypeAndName() {
rewriteRun(
spec -> spec.recipe(new FindFeatureFlag(FindFeatureFlag.FeatureFlagType.Bool, "flag-key-123abc")),
+ //language=java
java(
"""
import com.launchdarkly.sdk.LDUser;
@@ -258,6 +263,7 @@ public void a() {
void findFlagByNameUsingVariable() {
rewriteRun(
spec -> spec.recipe(new FindFeatureFlag(null, "flag-key-123abc")),
+ //language=java
java(
"""
import com.launchdarkly.sdk.LDUser;