diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddDependency.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddDependency.java index 3688a54111a..271517c4d94 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddDependency.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/AddDependency.java @@ -133,6 +133,13 @@ public class AddDependency extends ScanningRecipe { @Nullable Boolean acceptTransitive; + @Option(displayName = "Specific module name", + description = "Specify the module name in a Multi-Module project in which the dependency should be added.", + example = "moduleName", + required = false) + @Nullable + String specificModuleName; + @Override public Validated validate() { Validated validated = super.validate(); @@ -212,7 +219,7 @@ public Xml visitDocument(Xml.Document document, ExecutionContext ctx) { JavaProject javaProject = document.getMarkers().findFirst(JavaProject.class).orElse(null); String maybeScope = javaProject == null ? null : acc.scopeByProject.get(javaProject); - if (onlyIfUsing != null && maybeScope == null && !acc.scopeByProject.isEmpty()) { + if ((onlyIfUsing != null && maybeScope == null && !acc.scopeByProject.isEmpty()) || (specificModuleName != null && !specificModuleName.contains(getResolutionResult().getPom().getGav().getArtifactId()))) { return maven; } @@ -235,7 +242,7 @@ public Xml visitDocument(Xml.Document document, ExecutionContext ctx) { } } - if(onlyIfUsing == null && getResolutionResult().getParent() != null && acc.pomsDefinedInCurrentRepository.contains(getResolutionResult().getParent().getPom().getGav())) { + if(onlyIfUsing == null && getResolutionResult().getParent() != null && acc.pomsDefinedInCurrentRepository.contains(getResolutionResult().getParent().getPom().getGav()) && (specificModuleName == null || !specificModuleName.contains(getResolutionResult().getPom().getGav().getArtifactId()))) { return maven; } diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddDependencyTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddDependencyTest.java index 91248547837..54b03f2db22 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddDependencyTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/AddDependencyTest.java @@ -130,7 +130,7 @@ void systemScope() { void pomType() { rewriteRun( spec -> spec - .recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, null, null, "pom", null, null, null, null)), + .recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, null, null, "pom", null, null, null, null, null)), mavenProject("project", srcMainJava( java(usingGuavaIntMath) @@ -240,7 +240,7 @@ void onlyIfUsingCompileScope(String onlyIfUsing) { @Test void addDependencyWithClassifier() { AddDependency addDep = new AddDependency("io.netty", "netty-tcnative-boringssl-static", "2.0.54.Final", null, - "compile", true, "com.google.common.math.IntMath", null, "linux-x86_64", false, null, null); + "compile", true, "com.google.common.math.IntMath", null, "linux-x86_64", false, null, null, null); rewriteRun( spec -> spec.recipe(addDep), mavenProject( @@ -494,7 +494,7 @@ void test() {} void semverSelector(String onlyIfUsing) { rewriteRun( spec -> spec.recipe(new AddDependency("com.google.guava", "guava", "29.x", "-jre", null, false, onlyIfUsing, - null, null, false, null, null)), + null, null, false, null, null, null)), mavenProject( "project", srcMainJava( @@ -777,7 +777,7 @@ void useManaged() { void useRequestedVersionInUseByOtherMembersOfTheFamily() { rewriteRun( spec -> spec.recipe(new AddDependency("com.fasterxml.jackson.module", "jackson-module-afterburner", "2.10.5", - null, null, false, "com.fasterxml.jackson.databind.*", null, null, null, "com.fasterxml.*", null)), + null, null, false, "com.fasterxml.jackson.databind.*", null, null, null, "com.fasterxml.*", null, null)), mavenProject( "project", srcMainJava( @@ -1017,6 +1017,171 @@ void addDependencyToProjectsThatNeedIt() { ); } + @Test + void addDependencyToOneSpecificModuleInProject() { + rewriteRun( + spec -> spec.recipe(addDependencyWithSpecificModule("com.google.guava:guava:29.0-jre", "project1")), + mavenProject("root", + pomXml( + """ + + com.mycompany.app + root + 1 + + project1 + project2 + + + """ + ) + ), + mavenProject("project1", + pomXml( + """ + + com.mycompany.app + project1 + 1 + + com.mycompany.app + root + 1 + + + """, + """ + + com.mycompany.app + project1 + 1 + + com.mycompany.app + root + 1 + + + + com.google.guava + guava + 29.0-jre + + + + """ + ) + ), + mavenProject("project2", + pomXml( + """ + + com.mycompany.app + project2 + 1 + + com.mycompany.app + root + 1 + + + """ + ) + ) + ); + } + + @Test + void addDependencyToTwoSpecificModulesInProject() { + rewriteRun( + spec -> spec.recipe(addDependencyWithSpecificModule("com.google.guava:guava:29.0-jre", "project1,project2")), + mavenProject("root", + pomXml( + """ + + com.mycompany.app + root + 1 + + project1 + project2 + + + """ + ) + ), + mavenProject("project1", + pomXml( + """ + + com.mycompany.app + project1 + 1 + + com.mycompany.app + root + 1 + + + """, + """ + + com.mycompany.app + project1 + 1 + + com.mycompany.app + root + 1 + + + + com.google.guava + guava + 29.0-jre + + + + """ + ) + ), + mavenProject("project2", + pomXml( + """ + + com.mycompany.app + project2 + 1 + + com.mycompany.app + root + 1 + + + """, + """ + + com.mycompany.app + project2 + 1 + + com.mycompany.app + root + 1 + + + + com.google.guava + guava + 29.0-jre + + + + """ + ) + ) + ); + } + @Test void preferRootPom() { rewriteRun( @@ -1232,7 +1397,7 @@ void noCompileScopeDependency() { @Test void addDependenciesOnEmptyProjectWithMavenProject() { rewriteRun( - spec -> spec.recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, true, null, null, null, null, null, null)), + spec -> spec.recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, true, null, null, null, null, null, null, null)), mavenProject("my-app", pomXml(""" com.mycompany.app @@ -1260,7 +1425,7 @@ void addDependenciesOnEmptyProjectWithMavenProject() { @Test void addDependenciesOnEmptyProject() { rewriteRun( - spec -> spec.recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, true, null, null, null, null, null, null)), + spec -> spec.recipe(new AddDependency("com.google.guava", "guava", "29.0-jre", null, null, true, null, null, null, null, null, null, null)), pomXml(""" com.mycompany.app @@ -1299,7 +1464,7 @@ void dependencyThatIsTransitivelyProvidedWithWrongScopeShouldBeAdded() { .recipes( new AddDependency("org.checkerframework", "checker-qual", "3.44.0", null, null, null, "main.java.checkerframework..*", null, null, null, null, - true), + true, null), new ChangePackage("main.java.checkerframework", "org.checkerframework", true) ), mavenProject("parent", @@ -1401,7 +1566,7 @@ void dependencyThatIsTransitivelyProvidedWithCorrectScopeShouldNotBeAdded() { .recipes( new AddDependency("org.checkerframework", "checker-qual", "3.44.0", null, null, null, "main.java.checkerframework..*", null, null, null, null, - true), + true, null), new ChangePackage("main.java.checkerframework", "org.checkerframework", true) ), mavenProject("parent", @@ -1465,24 +1630,28 @@ class Foo {} } private AddDependency addDependency(@SuppressWarnings("SameParameterValue") String gav) { - return addDependency(gav, null, null, null); + return addDependency(gav, null, null, null, null); } private AddDependency addDependency(String gav, @Nullable String onlyIfUsing) { - return addDependency(gav, onlyIfUsing, null, null); + return addDependency(gav, onlyIfUsing, null, null, null); + } + + private AddDependency addDependencyWithSpecificModule(String gav, @Nullable String specificModuleName) { + return addDependency(gav, null, null, null, specificModuleName); } private AddDependency addDependency(String gav, @Nullable String onlyIfUsing, @SuppressWarnings("SameParameterValue") Boolean acceptTransitive) { - return addDependency(gav, onlyIfUsing, null, acceptTransitive); + return addDependency(gav, onlyIfUsing, null, acceptTransitive, null); } private AddDependency addDependency(String gav, @Nullable String onlyIfUsing, @Nullable String scope) { - return addDependency(gav, onlyIfUsing, scope, null); + return addDependency(gav, onlyIfUsing, scope, null, null); } - private AddDependency addDependency(String gav, @Nullable String onlyIfUsing, @Nullable String scope, @Nullable Boolean acceptTransitive) { + private AddDependency addDependency(String gav, @Nullable String onlyIfUsing, @Nullable String scope, @Nullable Boolean acceptTransitive, @Nullable String specificModuleName) { String[] gavParts = gav.split(":"); return new AddDependency(gavParts[0], gavParts[1], gavParts[2], null, scope, true, onlyIfUsing, null, null, - false, null, acceptTransitive); + false, null, acceptTransitive, specificModuleName); } }