Recipe AddDependency doesn't remove version when there is a managed dependency
timtebeek opened this issue · comments
Discussed in #4313
Originally posted by @rregout July 10, 2024
I have created a rewrite.yml with the following recipe list:
type: specs.openrewrite.org/v1beta/recipe
name: com.example.AddSpringBootStarterDependency
displayName: Add Maven dependency example
recipeList:
- org.openrewrite.maven.AddManagedDependency:
groupId: org.springframework.boot
artifactId: spring-boot-dependencies
version: 3.3.1
type: pom
scope: import
addToRootPom: true
- org.openrewrite.maven.AddDependency:
groupId: org.springframework.boot
artifactId: spring-boot-starter
onlyIfUsing: javax.ejb.Singleton
version: 3.3.1
With this a simple module project:
A parent pom:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>services</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
and a module pom:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
</dependencies>
</project>
And within the module an example Java class:
package com.example;
import javax.ejb.Singleton;
@Singleton
public class SingletonExample {
}
After running the command mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.activeRecipes=com.example.AddSpringBootStarterDependency
the result is a parent pom with
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>services</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.3.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
and the module with:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>
</project>
Why is the version of the dependency spring-boot-starter still in the module pom? It should use the one in de managed dependencies of the parent pom and not adding the version to the module pom.
@rregout I've replicate the above with a unit test in AddManagedDependencyTest. Not sure yet why this problem occurs. I suspect this update to the Maven model might not have occurred by the time we get to Add the non-managed dependendency.
Welcome to explore further using this test on a draft PR; I don't have time to follow up right now, but would like to see this resolved too.
@Test
@Issue("https://github.com/openrewrite/rewrite/discussions/4313")
void addManagedFirstDependencySecond() {
rewriteRun(
spec -> spec.recipeFromYaml(
"""
type: specs.openrewrite.org/v1beta/recipe
name: com.example.AddSpringBootStarterDependency
displayName: Add Maven dependency example
recipeList:
- org.openrewrite.maven.AddManagedDependency:
groupId: org.springframework.boot
artifactId: spring-boot-dependencies
version: 3.3.1
type: pom
scope: import
addToRootPom: true
- org.openrewrite.maven.AddDependency:
groupId: org.springframework.boot
artifactId: spring-boot-starter
onlyIfUsing: java.lang.String
version: 3.3.1
""",
"com.example.AddSpringBootStarterDependency"
),
mavenProject("parent",
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>services</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>services</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.3.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
"""
),
mavenProject("services",
srcMainJava(
java(
"""
class Foo {
String message;
}
"""
)
),
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
</dependencies>
</project>
""",
// Child pom should not have an explicit version, as the parent manages the same version
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
"""
)
)
)
);
}