Browse Source

Generate Maven Central-compatible poms

Understanding Gradle pom generation
-------------------------------------------

All spring-* subprojects have had Gradle's 'maven' plugin applied to
them. This means that one can run `gradle install`, and POMs will be
generated according to the metadata in the build.gradle file.

The 'customizePom' routine added by this commit hooks into this
generation process in order to add elements to the pom required for
entry into Maven Central via oss.sonatype.org[1].

This pom generation happens on-the-fly during `gradle install` and
the generated poms exist only in your local .m2 cache. Therefore,
you will not see the poms on the source tree after this command.

Handling optional and provided dependencies
-------------------------------------------

Note particularly the handling of 'optional' and 'provided'
dependencies. Gradle does not have a first class notion for these
concepts, nor are they significant to the actual Gradle build process,
but they are important when publishing POMs for consumption via Maven
Central and other Maven-compatible repositories.

<optional>true</optional> indicates that a dependency need not be
downloaded when resolving artifacts. e.g. spring-context has an
compile-time dependency on cglib, but when a Spring user resolves
spring-context from Maven Central, cglib should *not* automatically
be downloaded at the same time. This is because the core functionality
within spring-context can operate just fine without cglib on the
classpath; it is only if the user chooses explicitly to use certain
functionality, e.g. @Configuration classes, which do require cglib,
that the user must declare an explicit dependency in their own build
script on cglib.

Marking these kinds of dependencies as 'optional' provides a kind of
built in 'documentation' about which version of cglib the user should
declare if in fact he wishes to.

Spring has a great many compile-time dependencies, but in fact very
few mandatory runtime dependencies. Therefore, *most* of Spring's
dependencies are optional.

<scope>provided</scope> is similar to 'optional', in that dependencies
so marked should not be automatically downloaded during dependency
resolution, but indicates rather that they are expected to have been
provided by the user application runtime environment. For example, the
Servlet API is in fact a required runtime dependency for spring-webmvc,
but it is expected that it will be available via the user's servlet
container classpath. Again, it serves here as a kind of 'documentation'
that spring-webmvc does in fact expect the servlet api to be available,
and furthermore which (minimum) version.

This commit adds two closures named 'optional' and 'provided' as well as
two arrays (optionalDeps, providedDeps) for tracking which dependencies
are optional or provided. An optional dependency is declared as follows:

    compile("group:artifact:version", optional)

Here, the optional closure accepts the dependency argument implicitly,
and appends it to the 'optionalDeps' array. Then, during pom generation
(again, the customizePom routine), these arrays are interrogated, and
pom <dependency> elements are updated with <optional>true</optional> or
<scope>provided</scope> as appropriate. Thanks to the Spock framework
for inspiration on this approach[2].

[1] http://bit.ly/wauOqP (Sonatype's central sync requirements)
[2] https://github.com/spockframework/spock/blob/groovy-1.7/gradle/publishMaven.gradle#L63
pull/22/head
Chris Beams 13 years ago
parent
commit
b6cb514d38
  1. 193
      build.gradle
  2. 60
      publish-maven.gradle

193
build.gradle

@ -13,6 +13,8 @@ configure(allprojects) {
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
group = 'org.springframework'
sourceCompatibility=1.5 sourceCompatibility=1.5
targetCompatibility=1.5 targetCompatibility=1.5
@ -44,9 +46,8 @@ configure(allprojects) {
} }
} }
configure(subprojects) { configure(subprojects) { subproject ->
apply plugin: 'maven' apply from: "${rootProject.projectDir}/publish-maven.gradle"
group = 'org.springframework'
jar { jar {
from("${rootProject.projectDir}/src/dist") { from("${rootProject.projectDir}/src/dist") {
@ -141,11 +142,13 @@ project('spring-core') {
builtBy project(":spring-asm").jar builtBy project(":spring-asm").jar
} }
compile "commons-logging:commons-logging:1.1.1" compile "commons-logging:commons-logging:1.1.1"
compile("org.aspectj:aspectjweaver:1.6.8") { optional = true } compile("org.aspectj:aspectjweaver:1.6.8", optional)
compile("net.sf.jopt-simple:jopt-simple:3.0") { optional = true compile("net.sf.jopt-simple:jopt-simple:3.0") { dep ->
optional dep
exclude group: 'org.apache.ant', module: 'ant' exclude group: 'org.apache.ant', module: 'ant'
} }
compile("log4j:log4j:1.2.15") { optional = true compile("log4j:log4j:1.2.15") { dep ->
optional dep
exclude group: 'javax.mail', module: 'mail' exclude group: 'javax.mail', module: 'mail'
exclude group: 'javax.jms', module: 'jms' exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jdmk', module: 'jmxtools' exclude group: 'com.sun.jdmk', module: 'jmxtools'
@ -160,9 +163,9 @@ project('spring-beans') {
description = 'Spring Beans' description = 'Spring Beans'
dependencies { dependencies {
compile project(":spring-core") compile project(":spring-core")
compile("javax.el:el-api:1.0") { provided = true } compile("javax.el:el-api:1.0", provided)
compile("javax.inject:javax.inject:1") { provided = true } compile("javax.inject:javax.inject:1", provided)
compile("cglib:cglib-nodep:2.2") { optional = true } compile("cglib:cglib-nodep:2.2", optional)
} }
} }
@ -170,9 +173,9 @@ project('spring-aop') {
description = 'Spring AOP' description = 'Spring AOP'
dependencies { dependencies {
compile project(":spring-beans") compile project(":spring-beans")
compile("com.jamonapi:jamon:2.4") { optional = true } compile("com.jamonapi:jamon:2.4", optional)
compile("aopalliance:aopalliance:1.0") { optional = true } compile("aopalliance:aopalliance:1.0", optional)
compile("commons-pool:commons-pool:1.5.3") { optional = true } compile("commons-pool:commons-pool:1.5.3", optional)
} }
} }
@ -193,7 +196,7 @@ project('spring-instrument') {
project('spring-instrument-tomcat') { project('spring-instrument-tomcat') {
description = 'Spring Instrument Tomcat' description = 'Spring Instrument Tomcat'
dependencies { dependencies {
compile("org.apache.tomcat:catalina:6.0.16") { provided = true } compile("org.apache.tomcat:catalina:6.0.16", provided)
} }
} }
@ -203,24 +206,25 @@ project('spring-context') {
compile project(":spring-aop") compile project(":spring-aop")
compile project(":spring-expression") compile project(":spring-expression")
compile project(":spring-instrument") compile project(":spring-instrument")
compile("backport-util-concurrent:backport-util-concurrent:3.0") { optional = true } compile("backport-util-concurrent:backport-util-concurrent:3.0", optional)
compile("javax.annotation:jsr250-api:1.0") { optional = true } compile("javax.annotation:jsr250-api:1.0", optional)
compile("javax.ejb:ejb-api:3.0") { optional = true } compile("javax.ejb:ejb-api:3.0", optional)
compile("javax.inject:javax.inject:1") { optional = true } compile("javax.inject:javax.inject:1", optional)
compile("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1") { optional = true } compile("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1", optional)
compile("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1") { optional = true } compile("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1", optional)
compile("javax.persistence:persistence-api:1.0") { optional = true } compile("javax.persistence:persistence-api:1.0", optional)
compile("javax.validation:validation-api:1.0.0.GA") { optional = true } compile("javax.validation:validation-api:1.0.0.GA", optional)
compile("javax.xml.ws:jaxws-api:2.1-1") { optional = true compile("javax.xml.ws:jaxws-api:2.1-1") { dep ->
optional dep
exclude group: 'javax.jws', module: 'jsr181' exclude group: 'javax.jws', module: 'jsr181'
} }
compile("org.beanshell:bsh:2.0b4") { optional = true } compile("org.beanshell:bsh:2.0b4", optional)
compile("org.codehaus.groovy:groovy-all:1.6.3") { optional = true } compile("org.codehaus.groovy:groovy-all:1.6.3", optional)
compile("org.jruby:jruby:1.4.0") { optional = true } compile("org.jruby:jruby:1.4.0", optional)
compile("org.hibernate:hibernate-validator:4.2.0.Final") { optional = true } compile("org.hibernate:hibernate-validator:4.2.0.Final", optional)
compile("joda-time:joda-time:1.6") { optional = true } compile("joda-time:joda-time:1.6", optional)
compile("net.sf.ehcache:ehcache-core:2.0.0") { optional = true } compile("net.sf.ehcache:ehcache-core:2.0.0", optional)
compile("org.codehaus.jsr166-mirror:jsr166:1.7.0") { provided = true } compile("org.codehaus.jsr166-mirror:jsr166:1.7.0", provided)
testCompile "commons-dbcp:commons-dbcp:1.2.2" testCompile "commons-dbcp:commons-dbcp:1.2.2"
testCompile("javax.xml:jaxrpc-api:1.1") testCompile("javax.xml:jaxrpc-api:1.1")
testCompile("javax.inject:com.springsource.org.atinject.tck:1.0.0") testCompile("javax.inject:com.springsource.org.atinject.tck:1.0.0")
@ -231,8 +235,8 @@ project('spring-tx') {
description = 'Spring Transaction' description = 'Spring Transaction'
dependencies { dependencies {
compile project(":spring-context") compile project(":spring-context")
compile("com.ibm.websphere:uow:6.0.2.17") { provided = true } compile("com.ibm.websphere:uow:6.0.2.17", provided)
compile("javax.resource:connector-api:1.5") { optional = true } compile("javax.resource:connector-api:1.5", optional)
compile "aopalliance:aopalliance:1.0" // NOT optional, as opposed to in :spring-aop compile "aopalliance:aopalliance:1.0" // NOT optional, as opposed to in :spring-aop
testCompile "org.easymock:easymockclassextension:2.3" testCompile "org.easymock:easymockclassextension:2.3"
} }
@ -244,11 +248,11 @@ project('spring-oxm') {
dependencies { dependencies {
compile project(":spring-context") compile project(":spring-context")
compile "commons-lang:commons-lang:2.5" compile "commons-lang:commons-lang:2.5"
compile("com.thoughtworks.xstream:xstream:1.3.1") { optional = true } compile("com.thoughtworks.xstream:xstream:1.3.1", optional)
compile("com.sun.xml.bind:jaxb-impl:2.1.7") { optional = true } compile("com.sun.xml.bind:jaxb-impl:2.1.7", optional)
compile("org.jibx:jibx-run:1.1.5") { optional = true } compile("org.jibx:jibx-run:1.1.5", optional)
compile("org.apache.xmlbeans:xmlbeans:2.4.0") { optional = true } compile("org.apache.xmlbeans:xmlbeans:2.4.0", optional)
compile("org.codehaus.castor:castor-xml:1.3.2") { optional = true } compile("org.codehaus.castor:castor-xml:1.3.2", optional)
testCompile "org.codehaus.jettison:jettison:1.0.1" testCompile "org.codehaus.jettison:jettison:1.0.1"
testCompile "xmlunit:xmlunit:1.2" testCompile "xmlunit:xmlunit:1.2"
testCompile "xmlpull:xmlpull:1.1.3.4a" testCompile "xmlpull:xmlpull:1.1.3.4a"
@ -263,7 +267,7 @@ project('spring-jms') {
dependencies { dependencies {
compile project(":spring-oxm") compile project(":spring-oxm")
compile project(":spring-tx") compile project(":spring-tx")
compile("org.codehaus.jackson:jackson-mapper-asl:1.4.2") { optional = true } compile("org.codehaus.jackson:jackson-mapper-asl:1.4.2", optional)
} }
} }
@ -271,11 +275,11 @@ project('spring-jdbc') {
description = 'Spring JDBC' description = 'Spring JDBC'
dependencies { dependencies {
compile project(":spring-tx") compile project(":spring-tx")
compile("c3p0:c3p0:0.9.1.2") { optional = true } compile("c3p0:c3p0:0.9.1.2", optional)
compile("hsqldb:hsqldb:1.8.0.7") { optional = true } compile("hsqldb:hsqldb:1.8.0.7", optional)
compile("com.h2database:h2:1.0.71") { optional = true } compile("com.h2database:h2:1.0.71", optional)
compile("org.apache.derby:derby:10.5.3.0_1") { optional = true } compile("org.apache.derby:derby:10.5.3.0_1", optional)
compile("org.apache.derby:derbyclient:10.5.3.0_1") { optional = true } compile("org.apache.derby:derbyclient:10.5.3.0_1", optional)
} }
} }
@ -283,16 +287,16 @@ project('spring-context-support') {
description = 'Spring Context Support' description = 'Spring Context Support'
dependencies { dependencies {
compile project(":spring-jdbc") compile project(":spring-jdbc")
compile("org.codehaus.fabric3.api:commonj:1.1.0") { optional = true } compile("org.codehaus.fabric3.api:commonj:1.1.0", optional)
compile("opensymphony:quartz:1.6.2") { optional = true } compile("opensymphony:quartz:1.6.2", optional)
compile("javax.mail:mail:1.4") { optional = true } compile("javax.mail:mail:1.4", optional)
compile("velocity:velocity:1.5") { optional = true } compile("velocity:velocity:1.5", optional)
compile("commons-collections:commons-collections:3.2") { optional = true } compile("commons-collections:commons-collections:3.2", optional)
compile("org.freemarker:freemarker:2.3.15") { optional = true } compile("org.freemarker:freemarker:2.3.15", optional)
compile("jasperreports:jasperreports:2.0.5") { transitive = false; optional = true } compile("jasperreports:jasperreports:2.0.5") { transitive = false; optional = true }
compile("commons-digester:commons-digester:1.8.1") { optional = true } compile("commons-digester:commons-digester:1.8.1", optional)
compile("commons-beanutils:commons-beanutils:1.8.0") { optional = true } compile("commons-beanutils:commons-beanutils:1.8.0", optional)
compile("com.lowagie:itext:2.0.8") { optional = true } compile("com.lowagie:itext:2.0.8", optional)
testCompile "hsqldb:hsqldb:1.8.0.10" testCompile "hsqldb:hsqldb:1.8.0.10"
testCompile("org.apache.poi:poi:3.0.2-FINAL") { testCompile("org.apache.poi:poi:3.0.2-FINAL") {
exclude group: 'log4j', module: 'log4j' exclude group: 'log4j', module: 'log4j'
@ -307,22 +311,23 @@ project('spring-web') {
description = 'Spring Web' description = 'Spring Web'
dependencies { dependencies {
compile project(":spring-oxm") compile project(":spring-oxm")
compile("com.caucho:hessian:3.2.1") { optional = true } // NOTE: unavailable in maven central compile("com.caucho:hessian:3.2.1", optional)
compile("rome:rome:1.0") { optional = true } compile("rome:rome:1.0", optional)
compile("javax.el:el-api:1.0") { optional = true } // as opposed to 'provided' in spring-core compile("javax.el:el-api:1.0", optional)
compile("javax.faces:jsf-api:1.2_08") { optional = true } compile("javax.faces:jsf-api:1.2_08", optional)
compile("javax.portlet:portlet-api:2.0") { provided = true } compile("javax.portlet:portlet-api:2.0", provided)
compile("org.apache.tomcat:tomcat-servlet-api:7.0.8") { provided = true } // servlet-api 3.0 compile("org.apache.tomcat:tomcat-servlet-api:7.0.8", provided) // servlet-api 3.0
compile("javax.servlet.jsp:jsp-api:2.1") { provided = true } compile("javax.servlet.jsp:jsp-api:2.1", provided)
compile("javax.xml.soap:saaj-api:1.3") { provided = true } compile("javax.xml.soap:saaj-api:1.3", provided)
compile("axis:axis:1.4") { optional = true } compile("axis:axis:1.4", optional)
compile("commons-fileupload:commons-fileupload:1.2") { optional = true } compile("commons-fileupload:commons-fileupload:1.2", optional)
runtime("commons-io:commons-io:1.3") { optional = true } runtime("commons-io:commons-io:1.3", optional)
compile("commons-httpclient:commons-httpclient:3.1") { optional = true } compile("commons-httpclient:commons-httpclient:3.1", optional)
compile("org.apache.httpcomponents:httpclient:4.1.1") { optional = true } compile("org.apache.httpcomponents:httpclient:4.1.1", optional)
compile("org.codehaus.jackson:jackson-mapper-asl:1.4.2") { optional = true } compile("org.codehaus.jackson:jackson-mapper-asl:1.4.2", optional)
compile("taglibs:standard:1.1.2") { optional = true } compile("taglibs:standard:1.1.2", optional)
compile("org.mortbay.jetty:jetty:6.1.9") { optional = true compile("org.mortbay.jetty:jetty:6.1.9") { dep ->
optional dep
exclude group: 'org.mortbay.jetty', module: 'servlet-api-2.5' exclude group: 'org.mortbay.jetty', module: 'servlet-api-2.5'
} }
testCompile "xmlunit:xmlunit:1.2" testCompile "xmlunit:xmlunit:1.2"
@ -337,17 +342,17 @@ project('spring-orm') {
dependencies { dependencies {
// compiling against both hibernate 3 and 4 here in order to support // compiling against both hibernate 3 and 4 here in order to support
// our respective orm.hibernate3 and orm.hibernate4 packages // our respective orm.hibernate3 and orm.hibernate4 packages
compile("org.hibernate:com.springsource.org.hibernate:3.3.1.GA") { optional = true } compile("org.hibernate:com.springsource.org.hibernate:3.3.1.GA", optional)
compile("org.hibernate:hibernate-core:4.0.0.CR7") { optional = true } compile("org.hibernate:hibernate-core:4.0.0.CR7", optional)
compile("org.hibernate:hibernate-cglib-repack:2.1_3") { optional = true } compile("org.hibernate:hibernate-cglib-repack:2.1_3", optional)
compile("org.hibernate:hibernate-annotations:3.4.0.GA") { optional = true } compile("org.hibernate:hibernate-annotations:3.4.0.GA", optional)
compile("org.hibernate:hibernate-entitymanager:4.0.0.CR4") { optional = true } compile("org.hibernate:hibernate-entitymanager:4.0.0.CR4", optional)
compile("org.apache.openjpa:openjpa:1.1.0") { optional = true } compile("org.apache.openjpa:openjpa:1.1.0", optional)
compile("org.eclipse.persistence:org.eclipse.persistence.core:1.0.1") { optional = true } compile("org.eclipse.persistence:org.eclipse.persistence.core:1.0.1", optional)
compile("org.eclipse.persistence:org.eclipse.persistence.jpa:1.0.1") { optional = true } compile("org.eclipse.persistence:org.eclipse.persistence.jpa:1.0.1", optional)
compile("toplink.essentials:toplink-essentials:2.0-41b") { optional = true } compile("toplink.essentials:toplink-essentials:2.0-41b", optional)
compile("javax.jdo:jdo-api:3.0") { optional = true } compile("javax.jdo:jdo-api:3.0", optional)
compile("org.apache.ibatis:ibatis-sqlmap:2.3.4.726") { optional = true } compile("org.apache.ibatis:ibatis-sqlmap:2.3.4.726", optional)
testCompile "javax.servlet:servlet-api:2.5" testCompile "javax.servlet:servlet-api:2.5"
testCompile "org.slf4j:slf4j-jcl:1.5.3" testCompile "org.slf4j:slf4j-jcl:1.5.3"
testCompile "commons-dbcp:commons-dbcp:1.2.2" testCompile "commons-dbcp:commons-dbcp:1.2.2"
@ -366,19 +371,21 @@ project('spring-webmvc') {
compile project(":spring-web") compile project(":spring-web")
compile project(":spring-orm") compile project(":spring-orm")
compile project(":spring-context-support") compile project(":spring-context-support")
compile("org.apache.tiles:tiles-api:2.1.2") { optional = true } compile("org.apache.tiles:tiles-api:2.1.2", optional)
compile("org.apache.tiles:tiles-core:2.1.2") { optional = true } compile("org.apache.tiles:tiles-core:2.1.2", optional)
compile("org.apache.tiles:tiles-jsp:2.1.2") { optional = true } compile("org.apache.tiles:tiles-jsp:2.1.2", optional)
compile("org.apache.tiles:tiles-servlet:2.1.2") { optional = true } compile("org.apache.tiles:tiles-servlet:2.1.2", optional)
compile("velocity-tools:velocity-tools-view:1.4") { optional = true } compile("velocity-tools:velocity-tools-view:1.4", optional)
compile("net.sourceforge.jexcelapi:jxl:2.6.3") { optional = true compile("net.sourceforge.jexcelapi:jxl:2.6.3") { dep ->
optional dep
exclude group: 'log4j', module: 'log4j' exclude group: 'log4j', module: 'log4j'
} }
compile("org.apache.poi:poi:3.0.2-FINAL") { optional = true compile("org.apache.poi:poi:3.0.2-FINAL") { dep ->
optional dep
exclude group: 'log4j', module: 'log4j' exclude group: 'log4j', module: 'log4j'
} }
compile("javax.servlet:jstl:1.1.2") { provided = true } compile("javax.servlet:jstl:1.1.2", provided)
compile("org.apache.tomcat:tomcat-servlet-api:7.0.8") { provided = true } // servlet-api 3.0 compile("org.apache.tomcat:tomcat-servlet-api:7.0.8", provided) // servlet-api 3.0
testCompile("org.slf4j:slf4j-log4j12:${slf4jLog4jVersion}") { testCompile("org.slf4j:slf4j-log4j12:${slf4jLog4jVersion}") {
exclude group: 'log4j', module: 'log4j' exclude group: 'log4j', module: 'log4j'
} }
@ -401,7 +408,7 @@ project('spring-webmvc') {
project('spring-webmvc-portlet') { project('spring-webmvc-portlet') {
description = 'Spring Web Portlet' description = 'Spring Web Portlet'
dependencies { dependencies {
compile("javax.servlet:servlet-api:2.5") { provided = true } compile("javax.servlet:servlet-api:2.5", provided)
compile project(":spring-webmvc") compile project(":spring-webmvc")
} }
@ -413,10 +420,10 @@ project('spring-test') {
description = 'Spring TestContext Framework' description = 'Spring TestContext Framework'
dependencies { dependencies {
compile project(":spring-webmvc-portlet") compile project(":spring-webmvc-portlet")
compile("javax.activation:activation:1.0") { provided = true } compile("javax.activation:activation:1.0", provided)
compile("org.testng:testng:5.10:jdk15") { optional = true } compile("org.testng:testng:5.10:jdk15", optional)
compile("junit:junit:4.9") { optional = true } compile("junit:junit:4.9", optional)
compile("javax.servlet:servlet-api:2.5") { provided = true } compile("javax.servlet:servlet-api:2.5", provided)
testCompile "org.slf4j:slf4j-jcl:1.5.3" testCompile "org.slf4j:slf4j-jcl:1.5.3"
} }
} }
@ -427,7 +434,7 @@ project('spring-struts') {
compile project(":spring-webmvc") compile project(":spring-webmvc")
compile "struts:struts:1.2.9" compile "struts:struts:1.2.9"
compile "commons-beanutils:commons-beanutils:1.7.0" compile "commons-beanutils:commons-beanutils:1.7.0"
compile("javax.servlet:servlet-api:2.5") { provided = true } compile("javax.servlet:servlet-api:2.5", provided)
testCompile project(":spring-test") testCompile project(":spring-test")
} }
} }

60
publish-maven.gradle

@ -0,0 +1,60 @@
apply plugin: 'maven'
optionalDeps = []
providedDeps = []
optional = { optionalDeps << it }
provided = { providedDeps << it }
install {
repositories.mavenInstaller {
customizePom(pom, project)
}
}
def customizePom(pom, gradleProject) {
pom.whenConfigured { generatedPom ->
// respect 'optional' and 'provided' dependencies
gradleProject.optionalDeps.each { dep ->
generatedPom.dependencies.find { it.artifactId == dep.name }?.optional = true
}
gradleProject.providedDeps.each { dep ->
generatedPom.dependencies.find { it.artifactId == dep.name }?.scope = 'provided'
}
// eliminate test-scoped dependencies (no need in maven central poms)
generatedPom.dependencies.removeAll { dep ->
dep.scope == 'test'
}
// add all items necessary for maven central publication
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = 'https://github.com/SpringSource/spring-framework'
organization {
name = 'SpringSource'
url = 'http://springsource.org/spring-framework'
}
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
scm {
url = 'https://github.com/SpringSource/spring-framework'
connection = 'scm:git:git://github.com/SpringSource/spring-framework'
developerConnection = 'scm:git:git://github.com/SpringSource/spring-framework'
}
developers {
developer {
id = 'jhoeller'
name = 'Juergen Hoeller'
email = 'jhoeller@vmware.com'
}
}
}
}
}
Loading…
Cancel
Save