description = "Apache Tapestry 5 Project"

import org.apache.tools.ant.filters.ReplaceTokens

apply plugin: "base"
apply plugin: "sonar"

apply from: "ssh.gradle"
apply from: "md5.gradle"

project.ext.versions = [
    jetty: "7.6.11.v20130520",
    tomcat: "6.0.30",
    testng: "6.5.2",
    easymock: "3.0",
    servletapi: "2.5",
    spock: "0.7-groovy-2.0",
    hibernate: "4.1.2.Final",
    groovy: "2.0.6",
    slf4j: "1.7.2",
    wro4j: "1.6.3",
    geb: "0.9.0",
    selenium: "2.33.0"
]

// Provided so that the CI server can override the normal version number for nightly builds.
project.version = tapestryVersion()

// Remember that when generating a release, this should be incremented. Also don"t forget to
// tag the release in Subversion.
// Version number is always "5.x(.y)?-SNAPSHOT" and only gets fixed, e.g. to 5.4-alpha-1
// during a release

def tapestryVersion() {

    def major = "5.4"
    def minor = "-alpha-7"

    // When building on the CI server, make sure -SNAPSHOT is appended, as it is a nightly build.
    // When building normally, or for a release, no suffix is desired.
    Boolean.getBoolean("ci") ? major + "-SNAPSHOT" : major + minor
}

// Let analysis.apache.org get in touch with our builds

project.ext {
    sonarUrl = System.getProperty("sonarUrl", "http://analysis.apache.org");
    sonarDbUrl = System.getProperty("sonarDbUrl", "");
    sonarDbUsername = System.getProperty("sonarDbUsername", "");
    sonarDbPassword = System.getProperty("sonarDbPassword", "");
    sonarDbDriverClassName = "com.mysql.jdbc.Driver"

    stagingUrl = "https://repository.apache.org/service/local/staging/deploy/maven2/"
    snapshotUrl = "https://repository.apache.org/content/repositories/snapshots"

    doSign = !project.hasProperty("noSign") && project.hasProperty("signing.keyId")

    // apacheDeployUserName and apacheDeployPassword should be specified in ~/.gradle/gradle.properties

    deployUsernameProperty = isSnapshot() ? "snapshotDeployUserName" : "apacheDeployUserName"
    deployPasswordProperty = isSnapshot() ? "snapshotDeployPassword" : "apacheDeployPassword"

    canDeploy = [deployUsernameProperty, deployPasswordProperty].every { project.hasProperty(it) }

    deployUsername = { getProperty(deployUsernameProperty) }
    deployPassword = { getProperty(deployPasswordProperty) }
}

sonar {
    server {
        url = sonarUrl
    }
    database {
        url = sonarDbUrl
        driverClassName = sonarDbDriverClassName
        username = sonarDbUsername
        password = sonarDbPassword
    }
}

allprojects {

    apply plugin: "eclipse"
    apply plugin: "idea"
    apply plugin: "signing"


    repositories {
        mavenCentral()

        // All things JBoss/Hibernate
        mavenRepo name: "JBoss", url: "https://repository.jboss.org/nexus/content/repositories/releases/"
    }

    idea {
        project {
            // Leave at 1.5 to make sure that IDEA doesn't break the build for non-IDEA users by inserting
            // @Override on implementations all over the place.
            jdkName = "1.5"
        }
    }

    configurations {
        // Non-code artifacts, such as sources JARs and zipped JavaDocs
        meta
    }

}

// Specific to top-level build, not set for subprojects:

configurations {
    javadoc
    published.extendsFrom archives, meta
    if (doSign) {
        published.extendsFrom signatures
    }
    binaries // additional dependencies included in the binary archive
}

dependencies {
    javadoc project(":tapestry-javadoc")

    // From tapestry-ioc:
    binaries "javax.inject:javax.inject:1"
    binaries "org.slf4j:slf4j-api:${versions.slf4j}"
    binaries "commons-codec:commons-codec:1.5"
    binaries "org.antlr:antlr-runtime:3.3", { transitive = false }
}

subprojects {
    version = parent.version

    group = "org.apache.tapestry"

    configurations {
        provided
        deployerJars
    }

    apply plugin: "java"
    apply plugin: "groovy" // mostly for testing
    apply plugin: "maven"  // for deployment
    apply plugin: "project-report"

    sourceCompatibility = "1.5"
    targetCompatibility = "1.5"

    // See http://jira.codehaus.org/browse/GRADLE-784

    sourceSets {
        main {
            compileClasspath += configurations.provided
        }
        test {
            compileClasspath += configurations.provided
            runtimeClasspath += configurations.provided
        }
    }

    idea.module {
        scopes.PROVIDED.plus += configurations.provided
    }
    
    eclipse.classpath.plusConfigurations += configurations.provided

    dependencies {
        groovy "org.codehaus.groovy:groovy-all:${versions.groovy}"

        deployerJars "org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-6"

        testRuntime "org.slf4j:slf4j-log4j12:${versions.slf4j}"
    }

    test {
        useTestNG()

        options.suites("src/test/conf/testng.xml")

        maxHeapSize "400M"

        // Turn off live service reloading

        systemProperties["tapestry.service-reloading-enabled"] = "false"

        jvmArgs("-XX:MaxPermSize=512m", "-Dfile.encoding=UTF-8")
    }

    jar {
        from(projectDir) {
            include "*.txt"
            into "META-INF"
        }
    }

    task sourcesJar(type: Jar) {
        dependsOn classes
        classifier "sources"
        from sourceSets.main.allSource
        from(projectDir) {
            include "*.txt"
            into "META-INF"
        }
    }

    artifacts {
        meta sourcesJar
    }


    configurations {
        // published -- what gets uploaded to the Nexus repository
        published.extendsFrom archives, meta

        if (rootProject.doSign) {
            published.extendsFrom signatures
        }
    }

    if (rootProject.doSign) {
        // sign (create PGP signature for) archives (standard JARs)
        // and meta (sources JARs)
        signing { sign configurations.archives, configurations.meta }
    }

    uploadPublished {

        doFirst {
            if (!canDeploy) {
                throw new InvalidUserDataException("Missing upload credentials. Set '$deployUsernameProperty' and '$deployPasswordProperty' root project properties.")
            }
        }

        if (canDeploy) {
            repositories {

                project.ext.deployer = repositories.mavenDeployer {

                    if (doSign) {
                        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
                    }

                    repository(url: stagingUrl) {
                        authentication(userName: deployUsername(), password: deployPassword())
                    }

                    snapshotRepository(url: snapshotUrl) {
                        authentication(userName: deployUsername(), password: deployPassword())
                    }
                }
            }
        }
    }
}

subprojects.each { project.evaluationDependsOn(it.name) }

// Cribbed from https://github.com/hibernate/hibernate-core/blob/master/release/release.gradle#L19


task aggregateJavadoc(type: Javadoc) {

    dependsOn configurations.javadoc
    group "Documentation"

    description "Build the aggregated JavaDocs for all modules"
    maxMemory "512m"
    destinationDir file("$buildDir/documentation/javadocs")
    configure(options) {
        splitIndex true
        linkSource true
        stylesheetFile file("src/javadoc/stylesheet.css")
        windowTitle "Tapestry API Documentation"
        docTitle "Tapestry JavaDoc ($project.version)"
        bottom 'Copyright &copy; 2003-2012 <a href="http://tapestry.apache.org">The Apache Software Foundation</a>.'
        use = true // 'use' seems to be a reserved word for the DSL
        links "http://download.oracle.com/javase/6/docs/api/"
        links "http://download.oracle.com/javaee/6/api/"
        addStringOption "tagletpath", configurations.javadoc.asPath
        addStringOption "taglet", "org.apache.tapestry5.javadoc.TapestryDocTaglet"
        exclude "org/apache/tapestry5/internal/plastic/asm/**"
    }

    def allMainSourceSets = subprojects*.sourceSets*.main.flatten()
    def allMainJavaFiles = allMainSourceSets*.java
    def allMainJavaSrcDirs = allMainJavaFiles*.srcDirs

    source allMainJavaFiles

    classpath += files(allMainSourceSets*.compileClasspath)

    inputs.files allMainJavaSrcDirs

    // As part of generating the documentation, ALSO copy any related files:
    // Any extra images (Tapestry logo)
    // Any images stored under src/main/java ... everything but .java, .xdoc and package.html

    doLast {
        copy {
            from allMainJavaSrcDirs
            into aggregateJavadoc.destinationDir
            exclude "**/*.java"
            exclude "**/*.xdoc"
            exclude "**/package.html"
        }

        copy {
            from file("src/javadoc/images")
            into aggregateJavadoc.destinationDir
        }
    }
}

task coffeeScriptDocs(type: Exec) {
    group "Documentation"
    description "Build docco documentation for all CoffeeScript sources"

    def outputDir = file("$buildDir/documentation/coffeescript")

    def sources = subprojects*.fileTree("src/main", {
        include "**/*.coffee"
    })*.files.flatten()

    // Needs to be installed via "npm install -g docco"
    executable isWindows() ? "docco.cmd" : "docco"
    args "--output", outputDir
    args sources

    inputs.files sources
    outputs.dir outputDir
}



dependencies {
    meta aggregateJavadoc.outputs.files
}

task continuousIntegration {
    dependsOn subprojects.build, aggregateJavadoc, subprojects.uploadPublished
    description "Task executed on Jenkins CI server after SVN commits"
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.3'
    description "Regenerates the Gradle Wrapper files"
}

task zippedSources(type: Zip) {
    description "Creates a combined Zip file of all sub-project's sources"
    group "Release artifact"

    destinationDir buildDir
    baseName "apache-tapestry"
    version project.version
    classifier "sources"

    from project.projectDir
    exclude "out/**"
    exclude "**/*.iml"
    exclude "**/*.ipr"
    exclude "**/*.iws"
    exclude "**/.*/**"
    exclude "**/bin/**"
    exclude "**/target/**"
    exclude "**/build/**"
    exclude "**/test-output/**"  // Left around by TestNG sometimes
}

task zippedJavadoc(type: Zip) {
    dependsOn aggregateJavadoc
    description "Zip archive of the project's aggregate JavaDoc and CoffeeScript documentation"
    group "Release artifact"

    destinationDir buildDir
    baseName "apache-tapestry"
    version project.version
    classifier "javadocs"

    from file("src/docroot-template"), {
        filter ReplaceTokens, tokens: [version: project.version]
    }

    into "apidocs", { from aggregateJavadoc.outputs.files }


    into "coffeescript", { from coffeeScriptDocs.outputs.files }

}

task zippedBinaries(type: Zip) {
    description "Zip archive of binaries of each sub-project"
    // TODO: Plus dependencies?
    group "Release artifact"
    // This may create a few unwanted dependencies, but does
    // seem to ensure that the subprojects are created
    inputs.files subprojects*.configurations*.archives.artifacts

    destinationDir buildDir
    baseName "apache-tapestry"
    version project.version
    classifier "bin"

    // This is via some experimentation
    from subprojects*.configurations*.archives.artifacts*.file*.findAll {
        !(it.name.endsWith(".asc") || it.name.startsWith("quickstart"))
    }

    from configurations.binaries

    // Pick up various licenses and notices

    from(projectDir) {
        include "*.txt"
    }

    subprojects.each { sub ->
        from(sub.projectDir) {
            include "*.txt"
            into sub.name
        }
    }
}

if (canDeploy) {

    configurations {
        archives
        uploads.extendsFrom archives, signatures
    }


    artifacts {
        archives zippedJavadoc, zippedSources, zippedBinaries
    }

    configurations {
        upload.extendsFrom archives, signatures
    }

    task generateMD5Checksums(type: GenMD5) {
        group "Release artifact"
        description "Creates MD5 checksums for archives of source and JavaDoc"
        source tasks.withType(Zip)
        outputDir "$buildDir/md5"
    }

    if (doSign) {
        signing {
            sign configurations.archives
        }
    }

    task uploadArtifacts(type: Scp) {
        group "Release artifact"
        description "Uploads top-level artifacts to people.apache.org, along with MD5 checksums and PGP signatures (if signing is enabled)"

        source files(generateMD5Checksums, configurations.uploads.allArtifacts.files)

        host "people.apache.org"
        userName deployUsername()
        password deployPassword()

        // The destination folder at people.apache.org needs to already exist.
        destination "public_html/tapestry-releases"

        doFirst {
            logger.info "Uploading the following files to people.apache.org (as user '${userName}'):"
            source.files.each { logger.info "  $it" }
        }
    }

    task generateRelease {
        dependsOn "quickstart:clean", continuousIntegration, subprojects.uploadPublished, uploadArtifacts
        group "Release artifact"
        description "Generates and uploads a final release to Apache Nexus"
    }
}

boolean isSnapshot() {
    project.version.contains("SNAPSHOT")
}

boolean isWindows() {
    System.properties['os.name'].toLowerCase().contains('windows')
}
