[GRADLE-154] Create a utility to easily translate Maven dependency lists to Gradle dependency lists - XSLT? Created: 09/Jul/08 Updated: 04/Jan/13 Resolved: 28/Nov/12 |
|
Status: | Resolved |
Project: | Gradle |
Affects Version/s: | None |
Fix Version/s: | 1.2-rc-1 |
Type: | New Feature | ||
Reporter: | Antony Stubbs | Assignee: | Unassigned |
Resolution: | Fixed | Votes: | 9 |
Attachments: | Maven2Gradle.groovy dExtractor.groovy maven dependency translator.groovy pom.xml |
Description |
Perhaps this could initially easily be done with an XSLT sheet? |
Comments |
Comment by Antony Stubbs [ 10/Jul/08 ] |
ha! who needs XSLT when you've got Groovy! A simple Groovy script to start you off with the Gradle formatting of dependencies. Just paste in your dependecies section into the script and run. I recommend the Groovy console. translates: to: |
Comment by Hans Dockter [ 10/Jul/08 ] |
Very cool. If we add two things to this we can ship it with 0.3.
If this could also be wrapped in a unix and windows script which runs against a pom.xml in the current dir that would be awesome. End of the wishlist |
Comment by Antony Stubbs [ 10/Jul/08 ] |
Also need to support exclusions? Or is the dep management too different? |
Comment by Hans Dockter [ 10/Jul/08 ] |
Exclusions would be important. See user's guide: 12.2.3 |
Comment by Antony Stubbs [ 10/Jul/08 ] |
done! ok - getting more complicated here This one groups together scopes and adds on classifiers if they are found The layout of the scopes could be tweeked-but i'm not yet familiar with how gradle handles them anyway - or what the various scope equivalents are. excludes are just a test and slightly more complicated formatting away! I have also included a pretty messed up pom.xml to show it is pretty tolerant. usage is - put it in your project root ( same as your pom.xml ) and type: |
Comment by Hans Dockter [ 10/Jul/08 ] |
Great. I gonna have a look the code soon. Scope Mapping: Maven:Gradle |
Comment by Antony Stubbs [ 10/Jul/08 ] |
Done! Added exclusion support and corrected scope mapping. I'm getting faster with this groovy stuff The test pom.xml included produces this output (please let me know if it's wrong): output Working path:C:\workspaces\mavenDepConvert\src\. compile: "c3p0:c3p0:0.9.1.2" compile: "com.fonterra.tams:msg-classes:1.0.0" compile: "oracle.jdbc.driver:OracleDriver:10.2.0.3" addDependency(['compile'], "org.apache.struts:struts-core:1.3.8") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.apache.struts:struts-extras:1.3.8") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.apache.struts:struts-taglib:1.3.8") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.apache.ibatis:ibatis-sqlmap:2.3.0") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.springframework:spring-web:2.5") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.springframework:spring-beans:2.5") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.springframework:spring-jdbc:2.5") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.springframework:spring-orm:2.5") { exclude(module: 'commons-logging') } addDependency(['compile'], "org.hibernate:hibernate:3.2.5.ga") { exclude(module: 'commons-logging') } compile: "commons-lang:commons-lang:2.3" compile: "javax.xml.bind:jaxb-api:2.1" compile: "opensymphony:sitemesh:2.3" addDependency(['compile'], "displaytag:displaytag:1.1") { exclude(module: 'commons-logging') } compile: "javax.jms:jms:1.1" compile: "joda-time:joda-time:1.5" compile: "org.slf4j:slf4j-api:1.4.3" compile: "org.slf4j:slf4j-log4j12:1.4.3" compile: "org.slf4j:jcl104-over-slf4j:1.4.3" compile: "log4j:log4j:1.2.14" compile: "org.apache.commons:commons-io:1.3.2" compile: "jscience:jscience:4.3.1" compile: "org.google:google-collect:0.20071022-BETA" compile: "taglibs:standard:1.1.2" runtime: "com.sun.xml.bind:jaxb-impl:2.0.3" runtime: "cglib:cglib:2.1_3" testCompile: "org.easymock:easymock:2.3" testCompile: "org.easymock:easymockclassextension:2.2.2:jdk14" addDependency(['testCompile'], "org.dbunit:dbunit:2.2") { exclude(module: 'commons-logging') } testCompile: "junit:junit:4.4" addDependency(['testCompile'], "org.openqa.selenium.client-drivers:selenium-java-client-driver:${selenium-version}") { exclude(module: 'commons-logging') exclude(module: 'selenium-server') exclude(module: 'selenium-server-coreless') } addDependency(['testCompile'], "org.openqa.selenium.server:selenium-server:${selenium-version}") { exclude(module: 'commons-logging') } provided: "javax.servlet:jstl:1.1.2" provided: "javax.servlet:servlet-api:2.5" provided: "javax.servlet:jsp-api:2.0" system: "com.ibm:WebSphere-Runtime:6.1.0.13"}} |
Comment by Antony Stubbs [ 11/Jul/08 ] |
Added license (correct one?) and comments. |
Comment by Antony Stubbs [ 11/Jul/08 ] |
Added gradle formated project group and version (what else can we add? - where is a reference similar to the maven pom reference with all the things we can optionally conifgure?) |
Comment by Antony Stubbs [ 11/Jul/08 ] |
$ groovy ../../../mavenDepConvert/src/converter.groovy Working path:c:\workspaces\jbossMavenPlugin\jboss\jboss-server-manager\. Project settings: project.group = 'org.jboss.jbossas' project.version = 'jboss-server-manager Dependency information: compile: "org.apache.commons:commons-io:1.3.2" |
Comment by Antony Stubbs [ 11/Jul/08 ] |
typo |
Comment by Antony Stubbs [ 12/Jul/08 ] |
omg - did i have my eyes shut when i wrote that? |
Comment by Hans Dockter [ 12/Jul/08 ] |
version = 'jboss-server-manager' will do. Any assignment gets automatically delegated to the project object. To provide the user a better out of the box experience it would be cool to have start scripts for this, which adds the groovy jar which is shipped with Gradle to the classpath. That way the user does not need to have Gradle installed. And we have a defined Groovy version we run against. Could you imagine to do this? If not I'm also happy to do this. |
Comment by Hans Dockter [ 12/Jul/08 ] |
We use launch4j to provide windows start scripts. This is for example used in the build.gradle file of Gradle. |
Comment by Hans Dockter [ 12/Jul/08 ] |
Some more details: Your transformer code would live in a new package in the gradle-core src called for example org.gradle.mvn2gradle. Our build would generate a jar just out of this package. Our build would also generate two scripts, mvn2gradle and mvn2gradle.exe for starting the command under *nix and windows. Those scripts would be part of the Gradle bin directory. For this your script would need to move into a class. This class might be wrapped by a Mvn2GradleMain class for argument processing (I'm sure eventually we will have some). Last but not least it would be important to have a test. Does this makes sense? |
Comment by Antony Stubbs [ 13/Jul/08 ] |
Yup - sweet as. Is this already done anywhere yet, that I could use as an example? |
Comment by Hans Dockter [ 13/Jul/08 ] |
We do the same for the Gradle start scripts. Have a look in the build.gradle of Gradle. StartScriptsGenerator.generate("$archivesBaseName-${version}.jar", explodedDistBinDir, archivesBaseName) This is were we generate the *nix start script. StartScriptsGenerator is a class from buildSrc. This is were we create the windows exe: logger.info('Generate launch4j windows exe.') String launch4jDistName = "launch4j-" + launch4jVersion createLaunch4j(explodedDistLaunch4jLibDir, launch4jDistName) try { ant.taskdef( name: "launch4j", classname: "net.sf.launch4j.ant.Launch4jTask", classpath: "$buildDir/$launch4jDistName/launch4j.jar:$buildDir/$launch4jDistName/lib/xstream.jar") ant.launch4j() { config(headerType: "console", outfile: "$explodedDistBinDir/gradle.exe", dontWrapJar: "true", jarPath: "../lib/" + archive_jar.archiveName) { jre(minVersion: "1.5.0", jdkPreference: 'jdkOnly') } } } catch (Exception e) { logger.warning("The windows start exe could not be generated. Possibly you run the build on a machine with an OS which is not Linux, Mac OS X or Windows.") logger.warning(e.getMessage()); } |
Comment by Baruch Sadogursky [ 23/Nov/09 ] |
New version - MavenDependencyExtractor.groovy Added support for multi-module POMs, inheritance, dependency management, properties - everything. Uses maven-help-plugin, so have it in local repo or have an Internet connection Enjoy. P.S. "-verbose" (w/o quotes) to see the output of maven-help-plugin execution |
Comment by Hans Dockter [ 30/Nov/09 ] |
Thanks Baruch, this is excellent stuff, Baruch. That script should be either shipped with Gradle 0.9 or made available in a prominent way. I will start a discussion on the dev list on that soon and put you in cc. Maven 3 should provide additional means of integrating Maven projects into Gradle, Maven 3 is supposed to be very easy to embedd. What would be very nice, is to include a pom.xml at runtime. Either just for the dependencies or as a complete project. The latter could wrap Maven goals and lifecycle phases as Gradle tasks. Have you had a look at Maven 3? |
Comment by Baruch Sadogursky [ 30/Nov/09 ] |
Hans, I am not sure I understood what do you mean by "include a pom.xml at runtime either just for the dependencies or as a complete project". Anyway, we just had the JavaEdge09 conference (biggest annual Java conference in Israel) and I made a talk about modern build tools, featuring Gradle, of course. It included a demo on migrating from Maven2 to Gradle (that's what I needed the script for). |
Comment by Hans Dockter [ 30/Nov/09 ] |
Hi Baruch, just reading my very cryptic comment (I have written that in a rush). Apologies for that. With your script you can transform a maven pom.xml in a build.gradle file. Which is very helpful and might be exactly what people want if they want to migrate to Gradle. But there are other scenarios where people want to stick with the pom.xml. For example if you want to integrate an active Maven project in your multi-project Gradle build. Our vision for Gradle is also to be a build integration tool. I have seen a couple of situations where people had a mix of Maven and Ant builds and they wanted to have a single multi-project build for them. They ended up using CI tools for that. Our idea is that you can use Gradle to orchestrate any kind of build. With Ant builds this is already possible. For Ant projects you can already say in build.gradle. ant.import('build.xml') It would be very handy if you could do: maven.importDependencies('pom.xml') or maven.import('pom.xml') The first would add dynamically the dependencies of the pom.xml to the Gradle project object. The latter would to the same plus creating a number of Gradle tasks that wrap Maven lifecycle phases and goals. Have a look at the Ant import described in the user's guide. That way you can not just integrate Maven projects but also add functionality to them from Gradle. Does that make sense? |
Comment by Baruch Sadogursky [ 30/Nov/09 ] |
Oh, yeah. Lot's of sense. Frankly, I have expected this functionality to exist in a first place, and turned to this script only as a hack when didn't find one. If such functionality will be present in Gradle that would be a huge selling point. Meanwhile, I hacked the other direction too - in order to maintain pom.xml dependencies (for IntelliJ) I use the Gradle's Maven plugin to generate pom and then copy it (inside the build) to the root directory. Then I have my build in Gradle, and my IntelliJ happy with up-to-date dependencies in pom.xml |
Comment by Baruch Sadogursky [ 22/Feb/10 ] |
Kind of complete Maven2 to Gradle conversion script. More details here: http://jbaruch.wordpress.com/2010/02/23/maven2-to-gradle-convertor |
Comment by Hans Dockter [ 23/Feb/10 ] |
I'm wondering what is the best way to roll it out. It would be nice to provide a good out-of-the-box experience. One way to achieve that would be to have a Maven2Gradle.bat/shell script. Those scrips would use the groovy shipped with Gradle to run the Maven2Gradke groovy script. I guess something like the following could be used in the script: java -cp libs/groovy-....jar SomeGroovyStarterClass Maven2Gradle.groovy |
Comment by Bob Herrmann [ 31/Aug/10 ] |
why not just put the groovy script into a task somewhere. Then a maven user can do $ gradle createBuildScriptFromPom or C:> gradle createBuildScriptFromPom |
Comment by Baruch Sadogursky [ 31/Aug/10 ] |
@Bob, I am not sure it should be Gradle task. Gradle builds your code, while this script "builds" your build. |
Comment by Bob Herrmann [ 02/Sep/10 ] |
@Baruch understood. I was mostly thinking that not having to twiddle with or install something else would help get to the nice "out-of-the-box" experience that we want. I'm sitting looking at a pom.xml I'm thinking whats that gradle thing I heard about. How many mental steps are required to get that build running in gradle? 1. download gradle 2. configure GRADLE_HOME and PATH 3. find something to convert pom to build.gradle 4. install that 5. run it 6. gradle build 7. book vacation in paradise Would be nice to get 1 and 7 closer. |
Comment by Baruch Sadogursky [ 03/Sep/10 ] |
@Bob sure, the points 3-5 are just temporary solution. Soon it will be 1,2, 3.write 3 lines build.gradle to include maven-metadata-plugin, 6,7. |
Comment by Chris Beams [ 03/Sep/10 ] |
To Bob's ease-of-use comments, I too would like to see this functionality available directly from `gradle`. Whether it's using some variant of Baruch's approach, XSLT, or the forthcoming embedded Maven support, the point is that the 'how' should be an implementation detail to the user, who simply expresses through a convenient CLI 'what' he or she wants to do. In this case, the 'what' is converting an existing (set of) pom(s) to Gradle script(s). I say when in doubt, ask yourself "what would Git do"? Git would certainly integrate this as a subcommand, something like `gradle convert`. Because doing such a conversion could be arbitrarily complex with many options, Git would also likely provide an interactive mode (`gradle convert -i`). I think Git is a shining example of command-line power and usability. We should strive to make Gradle's CLI just as inclusive and even more user friendly. Gradle is about more than 'building your code'. The vision is that Gradle is your one stop for project automation needs. If a conversion from Maven is something that Gradle intends to support, then I'd say that's right in the core `gradle` executable's wheelhouse. Supporting such features suggests that Gradle's CLI needs to expand a bit. Perhaps 'everything is a task', but as-is, that wouldn't be too friendly to the user. Hans and Adam have already been discussing this, but Gradle needs to somehow accomodate things like per-task options, a structure that feels like Git's subcommands, etc. |
Comment by Hans Dockter [ 28/Sep/10 ] |
Eventually we will putt this functionality in the maven plugin. Plus in the future you will be able to call a plugin from the command line without applying it from the build script. That way Gradle will provide a good solution for this. |
Comment by Daz DeBoer [ 28/Nov/12 ] |
This feature is included in the new Bootstrap plugin: http://www.gradle.org/docs/current/userguide/bootstrap_plugin.html#N13E69 |
Comment by Antony Stubbs [ 28/Nov/12 ] |
Awesome! What's the way to go the other way again? To generate a pom? Would be nice to have that snippet of info here too. haha, cool, my 4 year old little issue |
Comment by Baruch Sadogursky [ 29/Nov/12 ] |
Antony, using Maven plugin's install task generates pom file. All you need to do is configure the location. http://www.gradle.org/docs/current/userguide/maven_plugin.html Thanks for inception what eventually became the Bootstrap plugin |