diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/AddDependencyVisitor.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/AddDependencyVisitor.java index 61659730458..e57fde69723 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/AddDependencyVisitor.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/AddDependencyVisitor.java @@ -199,7 +199,7 @@ static G.CompilationUnit addDependency( } return resolved; }), - new ResolvedDependency(null, resolvedGav, newRequested, transitiveDependencies, + new ResolvedDependency(null, resolvedGav, newRequested, transitiveDependencies, emptyList(), emptyList(), "jar", classifier, null, 0, null))); } newNameToConfiguration.put(newGdc.getName(), newGdc); diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/ExcludeDependency.java b/rewrite-maven/src/main/java/org/openrewrite/maven/ExcludeDependency.java index c7bce4a7968..9cbab5b23b7 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/ExcludeDependency.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/ExcludeDependency.java @@ -99,7 +99,8 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { ResolvedDependency dependency = findDependency(tag, scope); if (dependency != null && !(matchesGlob(dependency.getGroupId(), groupId) && matchesGlob(dependency.getArtifactId(), artifactId)) && - dependency.findDependency(groupId, artifactId) != null) { + dependency.findDependencyWithOmit(groupId, artifactId) != null) { + boolean needUpdate = false; Optional maybeExclusions = tag.getChild("exclusions"); if (maybeExclusions.isPresent()) { Xml.Tag exclusions = maybeExclusions.get(); @@ -116,6 +117,7 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { "")) .visitNonNull(exclusions, ctx, getCursor()); tag = tag.withContent(ListUtils.map((List) tag.getContent(), t -> t == exclusions ? newExclusions : t)); + needUpdate = true; } } else { tag = (Xml.Tag) new AddToTagVisitor<>(tag, @@ -127,8 +129,11 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { "\n" + "")) .visitNonNull(tag, ctx, getCursor().getParentOrThrow()); + needUpdate = true; + } + if (needUpdate) { + maybeUpdateModel(); } - maybeUpdateModel(); } return tag; } diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedDependency.java b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedDependency.java index d677c54ef57..c31190a45d0 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedDependency.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedDependency.java @@ -52,6 +52,10 @@ public class ResolvedDependency implements Serializable { @EqualsAndHashCode.Exclude List dependencies; + @NonFinal + @EqualsAndHashCode.Exclude + List omitDependencies; + List licenses; @Nullable @@ -81,6 +85,10 @@ void unsafeSetDependencies(List dependencies) { this.dependencies = dependencies; } + void unsafeSetOmitDependencies(List omitDependencies) { + this.omitDependencies = omitDependencies; + } + void unsafeSetEffectiveExclusions(List effectiveExclusions) { this.effectiveExclusions = effectiveExclusions; } @@ -142,6 +150,40 @@ public boolean isTransitive() { return null; } + public @Nullable ResolvedDependency findDependencyWithOmit(String groupId, String artifactId) { + return findDependencyWithOmit0(groupId, artifactId, Collections.newSetFromMap(new IdentityHashMap<>())); + } + + private @Nullable ResolvedDependency findDependencyWithOmit0(String groupId, String artifactId, Set visited) { + if (matchesGlob(getGroupId(), groupId) && matchesGlob(getArtifactId(), artifactId)) { + return this; + } else if (!visited.add(this)) { + return null; + } + outer: + for (ResolvedDependency dependency : dependencies) { + ResolvedDependency found = dependency.findDependencyWithOmit0(groupId, artifactId, visited); + if (found != null) { + if (getRequested().getExclusions() != null) { + for (GroupArtifact exclusion : getRequested().getExclusions()) { + if (matchesGlob(found.getGroupId(), exclusion.getGroupId()) && + matchesGlob(found.getArtifactId(), exclusion.getArtifactId())) { + continue outer; + } + } + } + return found; + } + } + + for (GroupArtifactVersion omit : omitDependencies) { + if (matchesGlob(omit.getGroupId(), groupId) && matchesGlob(omit.getArtifactId(), artifactId)) { + return this; + } + } + return null; + } + @Override public String toString() { return (repository == null ? "" : repository.getUri() + "/") + diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedPom.java b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedPom.java index d23f22dbe2c..e327504f2a5 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedPom.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/tree/ResolvedPom.java @@ -916,6 +916,13 @@ public List resolveDependencies(Scope scope, Map()); + } + includedBy.getOmitDependencies().add(new GroupArtifactVersion(d.getGroupId(), d.getArtifactId(), d.getVersion())); + } continue; } } @@ -938,7 +945,7 @@ public List resolveDependencies(Scope scope, Map spec.typeValidationOptions(TypeValidation.none()).afterTypeValidationOptions(TypeValidation.none()) + .recipe(new ExcludeDependency("org.apache.logging.log4j", "log4j-api", null)), + pomXml( + """ + + 4.0.0 + com.example + demo + 0.0.1-SNAPSHOT + + + org.springframework.boot + spring-boot-starter + 2.7.18 + + + + org.opensearch.client + spring-data-opensearch-starter + 1.3.0 + + + + """, + """ + + 4.0.0 + com.example + demo + 0.0.1-SNAPSHOT + + + org.springframework.boot + spring-boot-starter + 2.7.18 + + + org.apache.logging.log4j + log4j-api + + + + + + org.opensearch.client + spring-data-opensearch-starter + 1.3.0 + + + org.apache.logging.log4j + log4j-api + + + + + + """ + ) + ); + } }