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 = ""

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