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.7.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 "JDK: " + System.getProperty("java.version")

//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")
    int thisYear = java.time.Year.now().getValue()

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