Closed josemariavillar closed 2 years ago
Hi @josemariavillar ,
So previously, Maven
was just extending an Xml.Document
.
During the refactoring, we realized that we were not getting much by extending Xml.Document
. Therefore, we removed this class and now the MavenVisitor
is just an Xml.Visitor
that operates on an Xml.Document
that just happens to have the MavenResolutionResults
as a marker.
So, to answer your question, anywhere you were using Maven
, replace that with Xml.Document
, and visitMaven
becomes visitDocument
.
Here is an example of what this refactoring looks like:
There is also a MavenVisitor.getResolutionResult()
that will return the semantic model for the Maven XML document.
If you were using an Maven
class outside the context of a MavenVisitor, you will still change this to Xml.Document
and you can get access to the model by looking for the marker on the class :
Xml.Document maven = .....
MavenResolutionResult model = maven.getMarkers().findFirst(MavenResolutionResult.class)
.orElseThrow(() -> new IllegalStateException("Maven visitors should not be visiting XML documents without a Maven marker"));
We had a good a couple of additional good questions from @josemariavillar (thank you!) :
How could I check now if a transitive dependency exists?
Each Pom.xml has a marker on it called MavenResolutionResult
, this model object has a reference to the ResolvedPom
and it also has a Map<Scope, List<ResolvedDependency>>
which represents the list of resolved dependencies for the given scope. The list of dependencies in each scope represents all dependencies (including transitive dependencies) and there is no need to navigate to any parents.
Additionally, the list of dependencies under each scope will follow the rules defined in the maven documentation :
As an example:
List<ResolvedDependency> dependencies = results.getDependencies().get(Scope.Test)
The list of dependencies will include all dependencies that are in test scope, compile scope, and runtime scope. This also means that the same dependency may be duplicated within the resolve dependencies map.
How do you populate the Maven settings file within the ExecutionContext
while writing unit tests?
There is a MavenExecutionContextView
that acts as a wrapper around an existing execution context that provides some helper methods for setting messages on the context that are used by the underlying Maven infrastructure.
If you are extending RecipeTest, you can override the RecipeTest.getExecutionContext()
method and provide a context that includes various maven settings:
override val executionContext: ExecutionContext
get() = MavenExecutionContextView(super.executionContext).apply {
setMavenSettings(MavenSettings.parse(Parser.Input(Paths.get("settings.xml")) {//language=xml
"""
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- define settings here -->
</settings>
""".trimIndent().byteInputStream()
}, this))
}
Alternatively, you can use the finer-grained setters that are provided:
override val executionContext: ExecutionContext
get() = MavenExecutionContextView(super.executionContext).apply {
mirrors = listOf(
MavenRepositoryMirror("custom", "https://localhost:8443/repository", "central", true, true))
}
Finally, if you only want to add maven settings for a specific test, you can override the named parameter used by assertChanged/assertUnchanged:
fun myTest() = assertChanged(
executionContext = MavenExecutionContextView(super.executionContext).apply {
mirrors = listOf(
MavenRepositoryMirror("custom", "https://localhost:8443/repository", "central", true, true))
},
before = """
""",
...
For those that run into serialization errors similar to the following when using rewrite's maven plugin:
Failed to parse pom: Cannot construct instance of `org.openrewrite.maven.tree.ProfileActivation` (although at least one Creator exists): no default no-argument constructor found
This can happen when older versions of rewrite have stored serialized representations of the pom files into the Rockdb cache.
The solution to this problem is to remove all contents from the directory: ~/.rewrite-cache
The next time you run the maven plugin, rewrite will recreate the cache using the new serialization format.
Good afternoon,
I have upgraded to version 7.18.0-SNAPSHOT to have access to the latest developments and I have started to get compilation errors in my own recipes as the Maven.java class has disappeared from rewrite-maven/src/main/java/org/openrewrite/maven/tree/. Should they be replaced by another class? and if not, how should I access the Maven object from now on?
Thank you very much for everything