The code has been refactored from script to class, and it is now hosted on github.
Thanks to @lilithapp I have discovered a limitation – your project will be considered multi-module only if your reactor is also a parent of at least one of your modules. I probably won’t fix it, since that’s the case in most projects and since gradle-m2metadata-plugin doesn’t have that limitation.
Last JavaEdge I delivered a session about Java build tools landscape. My impression from this overview is solid – Gradle rocks. It is a best of breed and takes the best from Ant and Maven2, leaving the downsides of both behind. Take at look, it is worth it (Prezi rocks too, but it’s another blog post).
The only fly in the ointment I found is lack of good maven2 to Gradle convention. Gradle has good maven support. First of all, it can use dependenices’ POMs to determine their transitive dependencies. Second, it has Maven plugin, but it works in the opposite direction – it can generate POM for your project, built with Gradle. I need the other side – something similar Gradle has for Ant – ant.importBuild()
imports an Ant build into the Gradle project, and each Ant target is treated as a Gradle task. This is cool! Franky, I need much less with Maven.
Here’s the shopping list: I need to generate the following settings from POM.xml
- Dependencies (inc. scopes and exclusions)
- Correct plugins selection (e.g. war for web application module)
- GroupId
- Version
- Repositories
- Compiler level settings
- All those with full multi-module support
- All those with reuse support from inheritance and settings.xml
After a short search I discovered JIRA issue GRADLE-154, in which Antony Stubbs asks for a subset of such functionality, and finally attaches a small Groovy script that parses given POM.xml and dumps to the console dependencies in Gradle format. That was a great start for me, but the drawbacks were obvious – no support for multi-module projects (I can’t recall when I saw single-module project last time), no support for parts, coming from settings.xml, etc. One specific pom.xml file in view has very little to do with the effective pom in runtime. You already got it, right? The parsing should be done on the effective pom, which is easily obtained using maven-help-plugin. So, having effective pom in hand, I can rip it apart and build nice set of build.gradle files, and the settings.gradle for the multi module support, and they include all the items from the above list!
I can assure you there are some bugs here and there in this script, but generally it works, and I managed to migrate fairly complicated project with war assembly, transitive dependencies, poms inheritance, artifacts exclusions etc. in a single click. “Is this cool or is this cool?”
So, grab the script, and give it a shot. It has two flags: -verbose prints out Maven output during effective pom resolution and -keepFile keeps the effective pom file for you.
Note the new task in the generated gradle.build – replacePoms. The idea is to solve the lack of IntelliJ Gradle integration when it comes to dependency management (IDEA knows how to run the build). Gradle generates poms for your modules. The gradle.build knows to copy them to the place where IntelliJ needs them. Just run “build replacePoms”, and IDEA will recognize dependencies from Gradle! Yup!
Enjoy.
P.S. You should check the new gradle-m2metadata-plugin, it’s the real thing – Maven3 embedded into Gradle’s plugin. It gets all the metadata in runtime!
P.P.S. Sorry for my Groovy, it’s not my mother tongue.
Filed under: Build, Friendly Java Blogs Tagged: gradle, groovy, maven2
