On 10/08/10 5:05 PM, Baruch Sadogursky wrote:
Adam, thanks for inputs!
On Tue, Aug 10, 2010 at 09:21, Adam Murdoch <[email protected]
<mailto:[email protected]>> wrote:
On 7/08/10 8:09 PM, Baruch Sadogursky wrote:
Hi, devs!
I'd like to introduce you the *Gradle maven-embedder plugin*. The
target is the same as with my maven2gradle converter
<http://blog.sadogursky.com/2010/02/23/maven2-to-gradle-convertor/>,
but the implementation is much more awesome :)
It certainly is. This is fantastic.
The plugin embeds Maven in it and gets all the information needed
for the build from maven after it parsed the pom.xml
The source code is on github
<http://github.com/jbaruch/Gradle-Maven-embedder-Plugin>, the
plugin is deployed to Artifactory
<http://repo.jfrog.org/artifactory/webapp/browserepo.html?pathId=gradle-release-local%3Aorg%2Fgradle%2Fplugins%2Fgradle-mavenembedder-plugin>and
you can try it according to the readme
<http://github.com/jbaruch/Gradle-Maven-embedder-Plugin/blob/master/README>.
Now, except of the PR, the reason I write this to you is that I
have number of unsolved problems, and your advice will be greatly
appreciated:
1. Gradle contains maven-ant-tasks-2.1.0.jar in its lib
directory with conflicts with maven3 jars I need for my
plugin. maven-ant-tasks can not be ported to work with
maven3 easily, since JVZ changed plexus container APIs
dramatically somewhere between versions alpha-25 and
alpha-37 :) Generally, maven-ant-tasks is obsolete way to
run maven for gradle-maven-plugin, and that plugin should
probably be ported to Aether
<http://www.sonatype.com/people/2010/08/introducing-aether/>.
Other option is isolate plugins classpathes, although
looking at Maven's source with classworlds, I think
rewriting gradle-maven-plugin will be easier :)
The maven plugin will get reworked quite a bit after 0.9 is out,
so I think we could update it to use maven 3 at the same time.
Not sure it is possible. I invested some effort in it (hour or so),
and I can't see how maven-ant-tasks can be upgraded to Maven3. I am
under impression that the only way to go is to rewrite Maven plugin to
work with Aether.
That's fine. If the way to go for Maven 3 is to use Aether, then we
should use it.
1. The plugin is capable of executing Maven plugins. As PoC I
run maven-clean-plugin after Gradle's clean task. Two
questions in that regard:
1. I am not sure running all maven plugins from the
pom.xml makes sense, the corresponding Gradle plugin
(e.g. java) runs pretty much the same tasks -
compile, test, package, etc. On the other side, the
user might add specific configuration to all those
plugins, and expect special behavior from them (e.g.
adding additional directories to delete in
maven-clean-plugin, I covered this one). I will be
happy to hear your opinion on that matter - which
Maven plugins should I run?
When it comes to running plugins, I guess there's a few questions
that we need to answer for a given build:
- where should the meta-data for the project come from? Does it
come from the pom or from the build script?
- who should build the standard stuff? Do the Gradle plugins build
the artifacts? Or does Maven?
- which additional Maven plugins should get executed? The ones
listed in the pom? Or additional ones defined in the build script?
I guess there's a few use cases:
- Migrating from Maven. Probably want to use the meta-data from
the pom, use Gradle plugins for building, maybe run additional
plugins listed in the pom
- Build aggregation. Probably want Maven to do everything.
- Using custom Maven plugins. Probably want to use the meta-data
from the build script, and run the Maven plugins defined in the
build script.
I'd say that main purpose of the plugin is migrating from Maven, so
first scenario you listed feels the most relevant for me.
We could certainly start with that, and add any other combinations later.
1. If I want to run custom plugins (and I see it as a
main benefit of my plugin) I need them to be in the
classpath and I need which ones to run. For the
earlier there are two ways to achieve it - 1) make
the user add them to buildscript classpath or 2)
execute Maven's lookups in repositories. As much as I
don't like the first option, I like the second one
less. What do you say?
Without knowing the effort involved, I'd say you want to be able
to define plugins in the build script and/or pom, but I think
Maven should do the work of handling the lookups and classpaths.
The less behaviour we have to emulate the better.
Actually, it's adding behaviour to the plugin, not eliminating
.Running Maven plugin which is already in classpath is easier than
looking it up in repositories and then running it.
It makes it easier to implement the embedder plugin. But, for the person
using it, they have to duplicate the plugin information which is already
declared in the pom. Another problem with this approach is that the
classloader model is different, and we will almost certainly run into
classpath conflicts if we don't run the Maven plugins in the classloader
structure that they expect.
I would prefer keeping all the lookups done by one tool and going to
one place - by Gradle going to ~/.cache.
This would be possible by injecting a resolver into Maven which
delegates to Gradle's Maven repository mechanism.
I think the key thing is to keep separate using the pom for
configuration, and executing Maven plugins. I would imagine a flow like
this:
- At configuration time:
- Load up the (effective) pom and configure the Gradle Project using
the appropriate data from the pom. This may include the project
co-ordinates, dependencies, repositories, standard plugin configuration,
extra plugins and configuration. Throw the pom away at this point.
- Build script adds to or overwrites the configuration in the Gradle
Project.
- At execution time:
- Generate a pom (ideally, a Maven Project instance, not an XML
file) from the Gradle Project. Execute the appropriate mojos using this
pom. This allows us to mess with the configuration that Maven uses in
any way that we need to - replacing the repositories, and so on.
1. For the later - how can I know which plugins should I
run? Should I maintain a list of default plugins and
run all the plugins which aren't there?
1. Another obstacle I have is in-project dependencies. Inside
my code I can distinguish between external dependencies and
inter-module dependencies, but I am not sure how can I
generate correct gradle in-project dependency. Here's the
problem: I have in hand groupId:artifactId:version string
of maven dependency which relates to another module in the
build. On the other hand, the only thing I know about
Gradle modules are names from settings.xml. Will it be good
enough to match artifactId with module name and ignore all
the rest? Will it be durable enough?
Not really. Better to match on Project (group, name, version). But
even this isn't reliable, because one can change archivesBaseName
or the (groupId, artifactId, version) on the generated pom(s).
However, there's no good way to get at this for now. Part of the
dependency DSL working after the 0.9 release will make it easy to
map from a (group, artifactId, version) to a Project instance.
Not sure I can do it based on group and version. The group and version
are added by my plugin based on pom.xml. When I figure out the list of
projects it returns me the projects without group and version.
Ah, right. You could defer adding the dependencies until after all the
projects have been evaluated. Or match by name until we fix the
dependency DSL once 0.9 is out.
--
Adam Murdoch
Gradle Developer
http://www.gradle.org
CTO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz