allprojects {
    apply plugin: 'maven'
    apply from: "${rootProject.projectDir}/gradle/pomconfigurer.gradle"

    configurations {
        deployerJars
    }

    dependencies {
        deployerJars 'org.apache.maven.wagon:wagon-webdav:1.0-beta-2'
    }

    uploadArchives {
        repositories {
            mavenDeployer {
                def credentials = [
                        userName: System.getProperty('groovy.deploy.username'),
                        password: System.getProperty('groovy.deploy.password')
                ]
                configuration = configurations.deployerJars
                repository(id:'codehaus.org',url: uri('dav:https://dav.codehaus.org/repository/groovy'), authentication: credentials)
                snapshotRepository(id:'codehaus.org',url: uri('dav:https://dav.codehaus.org/snapshots.repository/groovy'), authentication: credentials)
                pom pomConfigureClosure
            }
        }
    }

    install {
        repositories {
            mavenInstaller {
                pom pomConfigureClosure
            }
        }
    }

    artifacts {
        archives jar
        archives sourceJar
        archives javadocJar
        archives groovydocJar
    }

    [uploadArchives, install]*.with {
        // dependency on jarAllAll should in theory be replaced with jar, jarWithIndy but
        // in practice, it is faster
        dependsOn([jarAllAll, sourceJar, javadocJar, groovydocJar])
        doFirst {
            if (rootProject.useIndy()) {
                new GradleException('You cannot use uploadArchives or install task with the flag [indy] turned'
                        +' on because the build handles indy artifacts by itself in that case.')
            }
            def archive = jar.archivePath
            def indyJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1]+'-indy.jar')
            if (indyJar.exists()) {
                project.artifacts.add('archives', indyJar)
            }
        }
    }
}

// the root project generates an alternate 'groovy-all' artifact
[uploadArchives, install]*.with {
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar])
    doFirst {
        project.artifacts.add('archives', jarAll)
        project.artifacts.add('archives', sourceAllJar)
        project.artifacts.add('archives', javadocAllJar)
        project.artifacts.add('archives', groovydocAllJar)
        def archive = jarAll.archivePath
        def indyJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1]+'-indy.jar')
        if (indyJar.exists()) {
            project.artifacts.add('archives', indyJar)
        }
    }
}
ext.pomAll = {
    addFilter('groovy') { artifact, file ->
        !(artifact.name.contains('groovy-all'))
    }
    addFilter('all') { artifact, file ->
        artifact.name.contains('groovy-all')
    }

    // regular pom
    def groovypom = pom('groovy',pomConfigureClosure)

    // pom for 'all'
    def allpom = pom('all', pomConfigureClosure)
    allpom.artifactId = 'groovy-all'

    subprojects.each { sp ->
        sp.install.repositories.mavenInstaller.pom.whenConfigured { subpom ->
            // add dependencies of other modules
            allpom.dependencies.addAll(subpom.dependencies)
        }
        sp.uploadArchives.repositories.mavenDeployer.pom.whenConfigured { subpom ->
            // add dependencies of other modules
            allpom.dependencies.addAll(subpom.dependencies)
        }
    }

    allpom.whenConfigured { p ->
        p.dependencies.removeAll(p.dependencies.findAll {
            it.groupId == 'org.codehaus.groovy' ||
                    (['asm', 'asm-util', 'asm-analysis', 'asm-tree', 'asm-commons', 'antlr', 'commons-cli'].contains(it.artifactId))
        })
    }
}



install {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(subprojects*.install)
    repositories {
        mavenInstaller pomAll
    }
}

uploadArchives {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(subprojects*.uploadArchives)
    repositories {
        mavenDeployer pomAll
    }
}
