description = "Apache Tapestry 5 Project"

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

apply plugin: "base"

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

project.ext.versions = [
    jetty: "8.1.19.v20160209",
    tomcat: "7.0.70",
    testng: "6.8.21",
    easymock: "3.3.1",
    servletapi: "3.0.1",
    spock: "1.1-groovy-2.4",
    hibernate: "5.1.1.Final",
    slf4j: "1.7.25",
    geb: "2.0",
    selenium: "3.12.0"
]

ext.continuousIntegrationBuild = Boolean.getBoolean("ci")

// 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 Git.
// 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.5.0"
    def minor = "-beta-3"

    // 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.
    continuousIntegrationBuild ? major + "-SNAPSHOT" : major + minor
}

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

project.ext {

    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, "apacheArchivesFolder"].every { project.hasProperty(it) }

    // These are all deferred inside closures, to allow people without the necessary values in their
    // gradle.properties to build locally, just not deploy. getProperty() throws an exception if the property
    // is not present.
    deployUsername = { getProperty(deployUsernameProperty) }
    deployPassword = { getProperty(deployPasswordProperty) }

    archiveDeployFolder = { getProperty("apacheArchivesFolder") }
}

//println "Can deploy? $canDeploy"
//println "Is snapshot? isSnapshot"
//println "deployUsernameProperty $deployUsernameProperty"
//println "deployPasswordProperty $deployPasswordProperty"
//println "continuousIntegrationBuild? $continuousIntegrationBuild"

allprojects {

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


    repositories {
        mavenCentral()

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

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

}

idea {
    project {
        languageLevel = "1.8"
    }
}

// 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 }
}

String jdkVersion = System.properties['java.version']
def jdkMajorVersion = jdkVersion.substring(0, jdkVersion.indexOf(".")) // 1, 9, 10...

subprojects {

    def specifyMaxPermSize = jdkVersion ==~ /1\.[67].+/
    
    version = parent.version

    group = "org.apache.tapestry"

    configurations {
        provided
    }

    apply plugin: "java"
    apply plugin: "groovy" // mostly for testing
    apply plugin: "maven"  // for deployment
    // TODO: replace the "maven" plugin above with the newer "maven-publish"

    apply plugin: "project-report"
    apply plugin: "jacoco"

    sourceCompatibility = "1.8"
    targetCompatibility = "1.8"

    // 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 {
        
        testCompile "org.spockframework:spock-core:${versions.spock}"
         
        testRuntime "org.slf4j:slf4j-log4j12:${versions.slf4j}"
    }

    compileTestGroovy {
        configure(groovyOptions.forkOptions) {
            memoryMaximumSize = '1g'
            jvmArgs = ['-Xms512m', '-Xmx1g']
            if (specifyMaxPermSize){
              jvmArgs << '-XX:MaxPermSize=512m'
            }
        }
    }

    tasks.withType(Test) {
        useTestNG()

        options.suites("src/test/conf/testng.xml")
        if (specifyMaxPermSize){
          maxHeapSize "400M"
          jvmArgs("-XX:MaxPermSize=200m")
        }else{
          maxHeapSize "600M"
        }

        // Turn off live service reloading

        systemProperties["tapestry.service-reloading-enabled"] = "false"
        systemProperties["java.io.tmpdir"] = temporaryDir.absolutePath

        jvmArgs("-Dfile.encoding=UTF-8")
        if (jdkMajorVersion != "1"){
          // TODO: make these regular dependencies instead
          jvmArgs += ["--add-modules", "java.xml.ws.annotation,java.xml.bind"]
        }

        environment.LANG = 'en_US.UTF-8'
        
        if (continuousIntegrationBuild){
          // Travis runs our builds with TERM=dumb and kills it if we don't produce any
          // output for 10 minutes, so we log some task execution progress 

          testLogging {
            exceptionFormat "full"
          }

          def numberOfTestsExecuted = 0
          afterTest { descriptor, result->
            numberOfTestsExecuted++
            if (numberOfTestsExecuted % 25 == 0){
              logger.lifecycle "$numberOfTestsExecuted tests executed"
            }
          }
        }
    }

    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 {
        archives sourcesJar
        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) }

subprojects {

    configurations.all {

        resolutionStrategy.force "antlr:antlr:2.7.7",
            "cglib:cglib-nodep:2.2",
            "commons-codec:commons-codec:1.10",
            "commons-io:commons-io:2.4",
            "commons-logging:commons-logging:1.1.3",
            "hsqldb:hsqldb:2.2.8",
            "org.antlr:antlr-runtime:3.5.2",
            "org.apache.tomcat:dbcp:6.0.32",
            "org.hamcrest:hamcrest-core:1.3",
            "org.json:json:20140107",
            "org.yaml:snakeyaml:1.8",
            "xml-apis:xml-apis:1.4.01"

    }
}

// 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")

    def tapestryStylesheet = file("src/javadoc/stylesheet7.css")

    configure(options) {
        splitIndex true
        linkSource true
        stylesheetFile tapestryStylesheet
        windowTitle "Tapestry API - ${project.version}"
        header "Tapestry API - ${project.version}"
        docTitle "Tapestry API - ($project.version)"
        bottom '${project.version} - Copyright &copy; 2003-2015 <a href="http://tapestry.apache.org">The Apache Software Foundation</a>.'
        use = true // 'use' seems to be a reserved word for the DSL
        links "https://docs.oracle.com/javase/8/docs/api/"
        links "https://docs.oracle.com/javaee/7/api/"
        addStringOption "tagletpath", configurations.javadoc.asPath
        addStringOption "taglet", "org.apache.tapestry5.javadoc.TapestryDocTaglet"
        exclude "org/apache/tapestry5/internal/plastic/asm/**"
        exclude "org/apache/tapestry5/internal/webresources/**"
        exclude "org/apache/tapestry5/webresources/modules/**"
    }

    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"
    dependsOn project(":tapestry-core").tasks.preprocessCoffeeScript

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

    def sources = files()

    subprojects.each { sub ->
        sources += sub.fileTree("src/main/coffeescript", { include "**/*.coffee" })
    }

    sources += project(":tapestry-core").tasks.preprocessCoffeeScript.outputs.files.asFileTree

    // Needs to be installed via "npm install -g docco@0.6.3"
    executable isWindows() ? "docco.cmd" : "docco"
    args "--output", outputDir
    args sources.files.sort({ a, b -> a.name.compareTo b.name })
}



dependencies {
    meta aggregateJavadoc.outputs.files
}

task combinedJacocoReport(type:JacocoReport){
  def subprojectsToConsider = subprojects.findAll {it.name != 'quickstart'}
  dependsOn = subprojectsToConsider.test
  additionalSourceDirs = files(subprojectsToConsider.sourceSets.main.allSource.srcDirs)
  sourceDirectories = files(subprojectsToConsider.sourceSets.main.allSource.srcDirs)
  classDirectories = files(subprojectsToConsider.sourceSets.main.output)
  executionData = files(subprojectsToConsider.jacocoTestReport.executionData)
  jacocoClasspath = files(subprojectsToConsider.jacocoTestReport.jacocoClasspath)
  reports {
      html {
        enabled = true
        destination = file("$buildDir/reports/jacoco")
      }
      xml {
        enabled = false
      }
      csv {
        enabled = false
      }
  }
  onlyIf = {
      true
  }
  doFirst {
      executionData = files(executionData.findAll {
          it.exists()
      })
  }
}

task continuousIntegration {
    dependsOn subprojects.build, 'tapestry-core:testWithPrototype', aggregateJavadoc, combinedJacocoReport
    description "Task executed on Jenkins CI server after Git commits"
}

task wrapper(type: Wrapper) {
    gradleVersion = '4.3.1'
    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 zippedApidoc(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 "apidocs"

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

    from file("src/docroot-template"), {
        exclude "*.html"
    }

    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.files

    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 zippedApidoc, 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"
    }

    task generateSHA256Checksums(type: GenSHA256) {
        group "Release artifact"
        description "Creates SHA-256 checksums for archives of source and JavaDoc"
        source tasks.withType(Zip)
        outputDir "$buildDir/sha256"
    }

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

    // This requires that you have the apacheArchivesFolder property configured in your
    // ~/.gradle/gradle.properties. The folder should be a Subversion workspace for
    // https://dist.apache.org/repos/dist/dev/tapestry
    // after the build, you must manually add the new files to the workspace (using "svn add")
    // then commit ("svn commit").

    // The files will be visible in https://dist.apache.org/repos/dist/dev/tapestry/, allowing
    // committers to download and verify them.

    // After a successful release vote, the files can be moved to a second Subversion workspace
    // for https://dist.apache.org/repos/dist/release/tapestry. Adding the files and committing
    // there will publish them to http://www.apache.org/dist/tapestry ... and from there
    // to all Apache mirrors (after about a 24 hour delay).

    task copyArchives(type: Copy) {
        group "Release artifact"
        description "Copies build archives (source, bin, docs) to a configured deployment folder, along with MD5 and SHA-256 checksums and PGP signatures (if signing is enabled)"

        destinationDir file(archiveDeployFolder())

        from generateMD5Checksums
        //from generateSHA256Checksums
        from configurations.uploads.allArtifacts.files
    }

    task generateRelease {
        dependsOn subprojects.uploadPublished, copyArchives
        group "Release artifact"
        description "Generates and uploads a final release to Apache Nexus and copies archives for deployment"
    }
}

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

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

task updateBootstrap {
  doLast {
	  def bootstrapVersion = '3.3.7'
	  def target = new File(temporaryDir, 'bootstrap.zip')
	  ant.get(src: "https://github.com/twbs/bootstrap/archive/v${bootstrapVersion}.zip", dest: target)
	
	  def adjustDirectory = {
	      def relativePath = it.relativePath
	      if (relativePath.pathString.contains('/dist/')){
	          relativePath = new RelativePath(!it.file.isDirectory(), relativePath.segments[2..-1] as String[])
	      } else {
	          relativePath = new RelativePath(!it.file.isDirectory(), relativePath.segments[1..-1] as String[])
	      }
	      println "copying $it.relativePath to $relativePath"
	      it.relativePath = relativePath
	
	  }
	
	  copy {
	    from(zipTree(target)){
	        include('*/js/*.js')
	        include('*/dist/fonts/*')
	        eachFile adjustDirectory
	    }
	    from(zipTree(target)){
	        include('*/dist/css/bootstrap.css')
	        include('*/dist/css/bootstrap-theme.css')
	        eachFile adjustDirectory
	        // TAP5-2351: remove source map reference from css files
	        filter({ (it ==~ /\/\*\s*# sourceMappingURL=[\S]+\s*\*\//) ? "" : it })
	    }
	    into('tapestry-core/src/main/resources/META-INF/assets/tapestry5/bootstrap/')
	  }
	
	  copy {
	    from(zipTree(target)){
	        include('*/js/*.js')
	        include('*/dist/fonts/*')
	        include('*/less/**/*.less')
	
	        eachFile adjustDirectory
	    }
	    into('tapestry-webresources/src/test/webapp/bootstrap/')
	  }
  }
}
