Russel Winder wrote:
Adam,
I'm really not sure I see the rational here. The primary difference
between groovy and groovy all is the ASM, Antlr, and Commons CLI being
embedded. These are not dependencies of Gradle
We already have ASM as a direct dependency (for the test scanning, and
soon for the convention mapping), and Antlr as a transitive dependency
(for checkstyle). So, this change uses the smaller groovy.jar, keeping
the distribution size down.
Interestingly, we also have a dependency on the version of ASM that
groovy uses, as we pass ASM classes into Groovy (in the script
compiler). So, when we use groovy-all.jar, we have to pass in jarjarasm
classes, because that's what Groovy is expecting. When we use
groovy.jar, we can pass in ASM classes. This is a much better option
because it's what's documented in the groovy javadoc, and it's the same
stuff we use in the other places.
and it seems the build
requires multiple instances of mentioning them. Doesn't this violate
DRY and lead to maintenance nightmare?
Yes. Unfortunately, we don't have a good way to share module definitions
between projects yet.
Some notes below.
Modified: gradle-core/trunk/build.gradle (1779 => 1780)
--- gradle-core/trunk/build.gradle 2009-08-21 03:36:57 UTC (rev 1779)
+++ gradle-core/trunk/build.gradle 2009-08-21 06:56:07 UTC (rev 1780)
@@ -147,7 +147,10 @@
userGuideStyleSheets 'docbook:docbook-xsl:1.7...@zip'
- groovy module("org.codehaus.groovy:groovy-all:1.6.4") {
+ groovy module("org.codehaus.groovy:groovy:1.6.4") {
+ dependency("asm:asm-all:2....@jar")
+ dependency("antlr:antlr:2....@jar")
+ dependency("commons-cli:commons-cli:1...@jar")
Why should Gradle have to specify transitive dependencies of Groovy,
this is what Ivy should manage using the POMs. It seems highly
inappropriate for Gradle to have to track Groovy data.
We don't have to. But we choose to tightly control the meta-data for the
dependencies which end up in the distribution for a few reasons:
- We can restrict transitive dependencies to just those we need for how
we use the library. Given that we're using the public maven repos, most
poms tend to pull in more dependencies than they need. By specifying
this, we keep the distribution size down.
- We can ensure we use a single version of each transitive dependency.
The public meta-data doesn't generally make use of version ranges, so we
get conflicts. This way we get to choose and make it explicit.
- The above 2 combined mean we end up with less problems when we jam
everything into a single classloader.
- We can swap the implementation of a transitive dependency. For
example, we swap in jcl-over-slf4j for everything which depends on
commons-logging.
There is a cost to this, of course. So, we tend to use only module() and
@jar dependencies in the compile and runtime configurations, and plain
dependencies in the configurations that are used for testing and
building where the above issues don't matter so much.
module("org.apache.ant:ant:1.7.0") {
dependencies("org.apache.ant:ant-junit:1....@jar",
"org.apache.ant:ant-launcher:1....@jar")
}
Modified:
gradle-core/trunk/src/samples/userguide/tutorial/groovyWithFlatDir/build.gradle
(1779 => 1780)
---
gradle-core/trunk/src/samples/userguide/tutorial/groovyWithFlatDir/build.gradle
2009-08-21 03:36:57 UTC (rev 1779)
+++
gradle-core/trunk/src/samples/userguide/tutorial/groovyWithFlatDir/build.gradle
2009-08-21 06:56:07 UTC (rev 1780)
@@ -6,7 +6,10 @@
}
dependencies {
- groovy module(':groovy-all:1.6.0') {
+ groovy module(':groovy:1.6.0') {
+ dependency("asm:asm-all:2.2.3")
+ dependency("antlr:antlr:2.7.7")
+ dependency("commons-cli:commons-cli:1.2")
See above :-)
This one is a sample. Some duplication is inevitable here. That's what
the integration test is for.
dependency(':commons-cli:1.0')
You can't have both 1.0 and 1.2 of Commons CLI? Anyway I thought Gradle
used JOpt Simple.
groovyc uses commons CLI. Gradle uses groovyc. That's why it's declared
as a transitive dependency.
Adam