diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddPluginRepository.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddPluginRepository.java
deleted file mode 100644
index 1a861e51f7c..00000000000
--- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddPluginRepository.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2022 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.maven;
-
-import lombok.EqualsAndHashCode;
-import lombok.Value;
-import org.intellij.lang.annotations.Language;
-import org.openrewrite.ExecutionContext;
-import org.openrewrite.Option;
-import org.openrewrite.Recipe;
-import org.openrewrite.TreeVisitor;
-import org.openrewrite.internal.lang.Nullable;
-import org.openrewrite.xml.AddToTagVisitor;
-import org.openrewrite.xml.ChangeTagValueVisitor;
-import org.openrewrite.xml.RemoveContentVisitor;
-import org.openrewrite.xml.XPathMatcher;
-import org.openrewrite.xml.tree.Xml;
-
-import java.util.Objects;
-import java.util.Optional;
-
-@Value
-@EqualsAndHashCode(callSuper = false)
-public class AddPluginRepository extends Recipe {
- private static final XPathMatcher PLUGIN_REPOS_MATCHER = new XPathMatcher("/project/pluginRepositories");
-
- @Option(example = "repo-id", displayName = "Plugin repository ID",
- description = "A unique name to describe the plugin repository.")
- String id;
-
- @Option(example = "http://myrepo.maven.com/repo", displayName = "Plugin repository URL",
- description = "The URL of the plugin repository.")
- String url;
-
- @Option(example = "My Great Repo Name", required = false,
- displayName = "Plugin repository name",
- description = "A display name for the plugin repository.")
- @Nullable
- String pluginRepoName;
-
- @Option(example = "default", required = false,
- displayName = "Plugin repository layout",
- description = "The Maven layout of the plugin repository.")
- @Nullable
- String layout;
-
- @Option(required = false,
- displayName = "Enable snapshots",
- description = "Snapshots from the plugin repository are available.")
- @Nullable
- Boolean snapshotsEnabled;
-
- @Option(example = "warn", required = false,
- displayName = "Snapshots checksum policy",
- description = "Governs whether snapshots require checksums.")
- @Nullable
- String snapshotsChecksumPolicy;
-
- @Option(example = "always", required = false,
- displayName = "Snapshots update policy",
- description = "The policy governing snapshot updating interval.")
- @Nullable
- String snapshotsUpdatePolicy;
-
- @Option(required = false,
- displayName = "Releases enabled",
- description = "Releases from the plugin repository are available")
- @Nullable
- Boolean releasesEnabled;
-
- @Option(example = "fail", required = false,
- displayName = "Releases checksum policy",
- description = "Governs whether releases require checksums.")
- @Nullable
- String releasesChecksumPolicy;
-
- @Option(example = "never", required = false,
- displayName = "Releases update policy",
- description = "The policy governing release updating interval.")
- @Nullable
- String releasesUpdatePolicy;
-
- @Override
- public String getDisplayName() {
- return "Add plugin repository";
- }
-
- @Override
- public String getDescription() {
- return "Adds a new Maven Plugin Repository or updates a matching plugin repository.";
- }
-
- @Override
- public TreeVisitor, ExecutionContext> getVisitor() {
- return new MavenIsoVisitor() {
- @Override
- public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
- Xml.Tag root = document.getRoot();
- if (!root.getChild("pluginRepositories").isPresent()) {
- document = (Xml.Document) new AddToTagVisitor<>(root, Xml.Tag.build(""))
- .visitNonNull(document, ctx, getCursor().getParentOrThrow());
- }
- return super.visitDocument(document, ctx);
- }
-
- @Override
- public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
- Xml.Tag pluginRepositories = super.visitTag(tag, ctx);
-
- if (PLUGIN_REPOS_MATCHER.matches(getCursor())) {
- Optional maybePluginRepo = pluginRepositories.getChildren().stream()
- .filter(pluginRepo ->
- "pluginRepository".equals(pluginRepo.getName())
- && (id.equals(pluginRepo.getChildValue("id").orElse(null)) || (isReleasesEqual(pluginRepo) && isSnapshotsEqual(pluginRepo)))
- && url.equals(pluginRepo.getChildValue("url").orElse(null))
- )
- .findAny();
-
- if (maybePluginRepo.isPresent()) {
- Xml.Tag pluginRepo = maybePluginRepo.get();
- if (pluginRepoName != null && !Objects.equals(pluginRepoName, pluginRepo.getChildValue("name").orElse(null))) {
- //noinspection OptionalGetWithoutIsPresent
- pluginRepositories = (Xml.Tag) new ChangeTagValueVisitor<>(pluginRepo.getChild("name").get(), pluginRepoName)
- .visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- }
- if (pluginRepoName != null && layout != null && !Objects.equals(layout, pluginRepo.getChildValue("layout").orElse(null))) {
- //noinspection OptionalGetWithoutIsPresent
- pluginRepositories = (Xml.Tag) new ChangeTagValueVisitor<>(pluginRepo.getChild("layout").get(), pluginRepoName)
- .visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- maybeUpdateModel();
- }
- if (!isReleasesEqual(pluginRepo)) {
- Xml.Tag releases = pluginRepo.getChild("releases").orElse(null);
- if (releases == null) {
- pluginRepositories = (Xml.Tag) new AddToTagVisitor<>(pluginRepo, Xml.Tag.build(assembleReleases()))
- .visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- } else {
- pluginRepositories = (Xml.Tag) new RemoveContentVisitor<>(releases, true)
- .visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- if (!isNoSnapshots()) {
- pluginRepositories = (Xml.Tag) new AddToTagVisitor<>(pluginRepo, Xml.Tag.build(assembleReleases()))
- .visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- }
- }
- maybeUpdateModel();
- }
- if (!isSnapshotsEqual(pluginRepo)) {
- Xml.Tag snapshots = pluginRepo.getChild("snapshots").orElse(null);
- if (snapshots == null) {
- pluginRepositories = (Xml.Tag) new AddToTagVisitor<>(pluginRepo, Xml.Tag.build(assembleSnapshots())).visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- } else {
- pluginRepositories = (Xml.Tag) new RemoveContentVisitor<>(snapshots, true).visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- if (!isNoSnapshots()) {
- pluginRepositories = (Xml.Tag) new AddToTagVisitor<>(pluginRepo, Xml.Tag.build(assembleSnapshots())).visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- }
- }
- maybeUpdateModel();
- }
- } else {
- @Language("xml")
- String sb = "\n" +
- assembleTagWithValue("id", id) +
- assembleTagWithValue("url", url) +
- assembleTagWithValue("name", pluginRepoName) +
- assembleTagWithValue("layout", layout) +
- assembleReleases() +
- assembleSnapshots() +
- "\n";
-
- Xml.Tag pluginRepoTag = Xml.Tag.build(sb);
- pluginRepositories = (Xml.Tag) new AddToTagVisitor<>(pluginRepositories, pluginRepoTag).visitNonNull(pluginRepositories, ctx, getCursor().getParentOrThrow());
- maybeUpdateModel();
- }
- }
- return pluginRepositories;
- }
- };
- }
-
- private String assembleTagWithValue(String tag, @Nullable String value) {
- StringBuilder sb = new StringBuilder();
- if (value != null) {
- sb.append("<");
- sb.append(tag);
- sb.append(">");
- sb.append(value);
- sb.append("");
- sb.append(tag);
- sb.append(">\n");
- }
- return sb.toString();
- }
-
- private String assembleReleases() {
- StringBuilder sb = new StringBuilder();
- if (releasesUpdatePolicy != null || releasesEnabled != null || releasesChecksumPolicy != null) {
- sb.append("");
- if (releasesEnabled != null) {
- sb.append(assembleTagWithValue("enabled", String.valueOf(releasesEnabled.booleanValue())));
- }
- if (releasesUpdatePolicy != null) {
- sb.append(assembleTagWithValue("updatePolicy", releasesUpdatePolicy));
- }
- if (releasesChecksumPolicy != null) {
- sb.append(assembleTagWithValue("checksumPolicy", releasesChecksumPolicy));
- }
- sb.append("\n");
- }
- return sb.toString();
- }
-
- private String assembleSnapshots() {
- StringBuilder sb = new StringBuilder();
- if (snapshotsEnabled != null || snapshotsChecksumPolicy != null || snapshotsUpdatePolicy != null) {
- sb.append("");
- if (snapshotsEnabled != null) {
- sb.append(assembleTagWithValue("enabled", String.valueOf(snapshotsEnabled.booleanValue())));
- }
- if (snapshotsUpdatePolicy != null) {
- sb.append(assembleTagWithValue("updatePolicy", snapshotsUpdatePolicy));
- }
- if (snapshotsChecksumPolicy != null) {
- sb.append(assembleTagWithValue("checksumPolicy", snapshotsChecksumPolicy));
- }
- sb.append("\n");
- }
- return sb.toString();
- }
-
- private boolean isReleasesEqual(Xml.Tag pluginRepo) {
- Xml.Tag releases = pluginRepo.getChild("releases").orElse(null);
- if (releases == null) {
- return isNoReleases();
- } else {
- return Objects.equals(releasesEnabled == null ? null : String.valueOf(releasesEnabled.booleanValue()), releases.getChildValue("enabled").orElse(null))
- && Objects.equals(releasesUpdatePolicy, releases.getChildValue("updatePolicy").orElse(null))
- && Objects.equals(releasesChecksumPolicy, releases.getChildValue("checksumPolicy").orElse(null));
- }
- }
-
- private boolean isNoReleases() {
- return releasesEnabled == null && releasesUpdatePolicy == null && releasesChecksumPolicy == null;
- }
-
- private boolean isSnapshotsEqual(Xml.Tag pluginRepo) {
- Xml.Tag snapshots = pluginRepo.getChild("snapshots").orElse(null);
- if (snapshots == null) {
- return isNoSnapshots();
- } else {
- return Objects.equals(snapshotsEnabled == null ? null : String.valueOf(snapshotsEnabled.booleanValue()), snapshots.getChildValue("enabled").orElse(null))
- && Objects.equals(snapshotsUpdatePolicy, snapshots.getChildValue("updatePolicy").orElse(null))
- && Objects.equals(snapshotsChecksumPolicy, snapshots.getChildValue("checksumPolicy").orElse(null));
- }
- }
-
- private boolean isNoSnapshots() {
- return snapshotsEnabled == null && snapshotsUpdatePolicy == null && snapshotsChecksumPolicy == null;
- }
-
-}
diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddRepository.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddRepository.java
index 79a4e29ac42..50c7537780e 100644
--- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddRepository.java
+++ b/rewrite-maven/src/main/java/org/openrewrite/maven/AddRepository.java
@@ -16,6 +16,7 @@
package org.openrewrite.maven;
import lombok.EqualsAndHashCode;
+import lombok.RequiredArgsConstructor;
import lombok.Value;
import org.intellij.lang.annotations.Language;
import org.openrewrite.ExecutionContext;
@@ -35,7 +36,6 @@
@Value
@EqualsAndHashCode(callSuper = false)
public class AddRepository extends Recipe {
- private static final XPathMatcher REPOS_MATCHER = new XPathMatcher("/project/repositories");
@Option(example = "repo-id", displayName = "Repository ID",
description = "A unique name to describe the repository.")
@@ -93,6 +93,20 @@ public class AddRepository extends Recipe {
@Nullable
String releasesUpdatePolicy;
+ @Option(displayName = "Repository type",
+ description = "The type of repository to add.",
+ example = "Repository")
+ Type type;
+
+ @RequiredArgsConstructor
+ public enum Type {
+ Repository("repository", "repositories"),
+ PluginRepository("pluginRepository", "pluginRepositories");
+
+ final String xmlTagSingle;
+ final String xmlTagPlural;
+ }
+
@Override
public String getDisplayName() {
return "Add repository";
@@ -106,11 +120,13 @@ public String getDescription() {
@Override
public TreeVisitor, ExecutionContext> getVisitor() {
return new MavenIsoVisitor() {
+ private final XPathMatcher REPOS_MATCHER = new XPathMatcher("/project/" + type.xmlTagPlural);
+
@Override
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
Xml.Tag root = document.getRoot();
- if (!root.getChild("repositories").isPresent()) {
- document = (Xml.Document) new AddToTagVisitor<>(root, Xml.Tag.build(""))
+ if (!root.getChild(type.xmlTagPlural).isPresent()) {
+ document = (Xml.Document) new AddToTagVisitor<>(root, Xml.Tag.build("<" + type.xmlTagPlural + "/>"))
.visitNonNull(document, ctx, getCursor().getParentOrThrow());
}
return super.visitDocument(document, ctx);
@@ -123,7 +139,7 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if (REPOS_MATCHER.matches(getCursor())) {
Optional maybeRepo = repositories.getChildren().stream()
.filter(repo ->
- "repository".equals(repo.getName()) &&
+ type.xmlTagSingle.equals(repo.getName()) &&
(id.equals(repo.getChildValue("id").orElse(null)) || (isReleasesEqual(repo) && isSnapshotsEqual(repo))) &&
url.equals(repo.getChildValue("url").orElse(null))
)
@@ -171,14 +187,14 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
}
} else {
@Language("xml")
- String sb = "\n" +
+ String sb = "<" + type.xmlTagSingle + ">\n" +
assembleTagWithValue("id", id) +
assembleTagWithValue("url", url) +
assembleTagWithValue("name", repoName) +
assembleTagWithValue("layout", layout) +
assembleReleases() +
assembleSnapshots() +
- "\n";
+ "" + type.xmlTagSingle + ">\n";
Xml.Tag repoTag = Xml.Tag.build(sb);
repositories = (Xml.Tag) new AddToTagVisitor<>(repositories, repoTag).visitNonNull(repositories, ctx, getCursor().getParentOrThrow());
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginRepositoryTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginRepositoryTest.java
deleted file mode 100644
index bfb33b2ca58..00000000000
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddPluginRepositoryTest.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2022 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.maven;
-
-import org.junit.jupiter.api.Test;
-import org.openrewrite.DocumentExample;
-import org.openrewrite.test.RewriteTest;
-
-import static org.openrewrite.maven.Assertions.pomXml;
-
-class AddPluginRepositoryTest implements RewriteTest {
-
- @DocumentExample
- @Test
- void addSimpleRepo() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- null, null, null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
- """,
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
-
-
- """
- )
- );
- }
-
- @Test
- void updateExistingRepo() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", "bb", null,
- null, null, null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
- qq
-
-
-
- """,
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
- bb
-
-
-
- """
- )
- );
- }
-
- @Test
- void doNotRemoveRepoName() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- null, null, null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
- qq
-
-
-
- """
- )
- );
- }
-
- @Test
- void removeSnapshots() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- null, null, null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
- true
-
-
-
-
- """,
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
-
-
- """
- )
- );
- }
-
- @Test
- void updateSnapshots1() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- false, "whatever", null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
- true
-
-
-
-
- """,
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
- false
- whatever
-
-
-
-
- """
- )
- );
- }
-
- @Test
- void updateSnapshots2() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- null, "whatever", null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
- true
-
-
-
-
- """,
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo
- http://myrepo.maven.com/repo
-
- whatever
-
-
-
-
- """
- )
- );
- }
-
- @Test
- void noIdMatch1SameSnapshots() {
- rewriteRun(
- spec -> spec.recipe(new AddPluginRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
- true, null, null,
- null, null, null)),
- pomXml(
- """
-
- com.mycompany.app
- my-app
- 1
-
-
- myRepo-X
- http://myrepo.maven.com/repo
-
- true
-
-
-
-
- """
- )
- );
- }
-}
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddRepositoryTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddRepositoryTest.java
index 90b3da09f22..c9b1beeed3f 100644
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddRepositoryTest.java
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/AddRepositoryTest.java
@@ -29,7 +29,7 @@ void addSimpleRepo() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
null, null, null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -55,12 +55,43 @@ void addSimpleRepo() {
);
}
+ @Test
+ void addSimplePluginRepo() {
+ rewriteRun(
+ spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
+ null, null, null,
+ null, null, null, AddRepository.Type.PluginRepository)),
+ pomXml(
+ """
+
+ com.mycompany.app
+ my-app
+ 1
+
+ """,
+ """
+
+ com.mycompany.app
+ my-app
+ 1
+
+
+ myRepo
+ http://myrepo.maven.com/repo
+
+
+
+ """
+ )
+ );
+ }
+
@Test
void updateExistingRepo() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", "bb", null,
null, null, null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -99,7 +130,7 @@ void doNotRemoveRepoName() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
null, null, null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -124,7 +155,7 @@ void removeSnapshots() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
null, null, null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -164,7 +195,7 @@ void updateSnapshots1() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
false, "whatever", null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -208,7 +239,7 @@ void updateSnapshots2() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
null, "whatever", null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -251,7 +282,7 @@ void noIdMatch1SameSnapshots() {
rewriteRun(
spec -> spec.recipe(new AddRepository("myRepo", "http://myrepo.maven.com/repo", null, null,
true, null, null,
- null, null, null)),
+ null, null, null, AddRepository.Type.Repository)),
pomXml(
"""
@@ -280,7 +311,7 @@ void updateToSpringBoot30Snapshot() {
spec -> spec.recipes(
new AddRepository("boot-snapshots", "https://repo.spring.io/snapshot", null, null,
true, null, null,
- null, null, null),
+ null, null, null, AddRepository.Type.Repository),
new UpgradeParentVersion("org.springframework.boot", "spring-boot-starter-parent", "3.0.0-SNAPSHOT", null)
),
pomXml(