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

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

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

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