/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

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

// Get database property, use HAWQ as a default database
def database = System.getProperty("database", "hawq");
def databaseFileName = "gradle/profiles/" + database + ".properties";
assert file(databaseFileName).exists()
def databaseProperties = new Properties()
file(databaseFileName).withInputStream { databaseProperties.load(it) }

buildscript {
    repositories {
        // mavenCentral without https:
        maven {
            url 'http://repo1.maven.org/maven2'
        }
        mavenLocal()
        jcenter {
            url 'http://jcenter.bintray.com/'
        }
        maven {
            url 'http://repository.jboss.org/nexus/content/groups/public'
        }
    }

    dependencies {
        classpath "com.netflix.nebula:gradle-ospackage-plugin:2.2.6"
        classpath "de.undercouch:gradle-download-task:2.1.0"
        classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:2.2.+'
    }   
}

// Hadoop distribution (can be hdp or null which would default to apache) - needed to set correct classpaths
// can be set with -Dhd=<value>
def hddist = System.properties['hd'] ?: '';
if (hddist != 'hdp' && hddist != '') {
    throw new GradleException("hadoop distribution parameter (hd) set to invalid value: $hddist")
}

// Some package names need to be renamed to include the version number
// as part of the package name to enable side by side install of two versions of the same package.

def versionedPackageName(packageName) {
    if (System.properties['hd'] == 'hdp') {
        packageName + "_" + "${version}".replace(".", "_")
    } else {
        packageName
    }
}

subprojects { subProject ->
    group = 'org.apache.hawq.pxf'
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'eclipse'
    apply plugin: 'os-package'
    apply plugin: 'maven-publish'

    compileJava.options*.compilerArgs = [
            "-g", "-Xlint:varargs", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann", "-Xlint:divzero", "-Xlint:empty",
            "-Xlint:finally", "-Xlint:overrides", "-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try",
            "-Xlint:fallthrough", "-Xlint:deprecation", "-Xlint:unchecked", "-Xlint:-options", "-Werror"
    ]

    compileTestJava.options*.compilerArgs = [
            "-Xlint:varargs", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann", "-Xlint:divzero", "-Xlint:empty",
            "-Xlint:finally", "-Xlint:overrides", "-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try",
            "-Xlint:fallthrough", "-Xlint:deprecation", "-Xlint:unchecked", "-Xlint:-options"
    ]

    // Add LICENSE, DISCLAIMER and NOTICE to generated jar files.
    sourceSets {
        main {
            resources {
                srcDir '../resources'
                include '**/*'
            }
        }
    }

    repositories {
        // mavenCentral without https:
        maven { url 'http://repo1.maven.org/maven2' }
        mavenLocal()
        maven { url 'http://repo.hortonworks.com/content/repositories/releases/'}
    }

    dependencies {
        compile 'commons-logging:commons-logging:1.1.3'
        compile 'commons-collections:commons-collections:3.2.1'
        compile 'commons-codec:commons-codec:1.4'
        compile 'commons-configuration:commons-configuration:1.6'
        compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
        testCompile 'junit:junit:4.11'
        testCompile 'org.powermock:powermock-core:1.5.1'
        testCompile 'org.powermock:powermock-module-junit4:1.5.1'
        testCompile 'org.powermock:powermock-api-mockito:1.5.1'
        testCompile 'org.mockito:mockito-core:1.9.5'
    }

    configurations.all {
        resolutionStrategy {
            // force versions that were specified in dependencies:
            // hbase/hive has a different versions than other hadoop components
            force 'commons-codec:commons-codec:1.4'
            force 'commons-collections:commons-collections:3.2.1'
            force 'commons-logging:commons-logging:1.1.3'
            force 'org.apache.avro:avro:1.7.4'
            force 'org.apache.zookeeper:zookeeper:3.4.6'
            force 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
            force 'junit:junit:4.11'
        }
    }

    task distTar(type: Tar) {
        classifier = buildNumber()
        compression = Compression.GZIP
        extension = 'tar.gz'
        from jar.outputs.files
        into "${project.name}-${project.version}"
    }

    //buildRpm
    ospackage {
        vendor = project.vendor
        release = buildNumber()
        version = subProject.version.split('-')[0];
        os = LINUX
        license = project.license
        obsoletes('gpxf')
        user = 'root'
        permissionGroup = 'root'
    }
}

project('pxf-service') {

// Copy existing sources and replace any occurrences of @tokenName@ with desired values
    task generateSources {
        doFirst {
            copy {
                from('src/main/java') {
                    include '**/*.java'
                    filter(ReplaceTokens,
                        tokens:['pxfProtocolVersion': project.pxfProtocolVersion ])}
                into "tmp/generatedSources"
            }
        }
    }

// Call cleanup taskAfter Java code compilation
    compileJava.doLast {
        tasks.cleanGeneratedSources.execute()
    }

// Delete "tmp" directory under current project directory
// rm -r pxf-service/tmp
    task cleanGeneratedSources() {
        doFirst {
            delete "tmp"
        }
    }

// Call generateSources task before Java compilation
    gradle.projectsEvaluated {
        compileJava.dependsOn(generateSources)
    }

// Use custom sources directory with generated sources
    sourceSets {
        main {
            java {
                srcDirs = ["tmp/generatedSources"]
            }
        }
    }

    apply plugin: 'war'
    tasks.war {
        archiveName = 'pxf.war'
        filter(ReplaceTokens, tokens: ['pxfProtocolVersion': project.pxfProtocolVersion])
        processResources {
            filesMatching('**/pxf-*') {
                details ->
                    details.exclude()
            }
        }

    }
    dependencies {
        compile(project(':pxf-api'))
        compile 'com.sun.jersey:jersey-core:1.9'
        providedCompile "org.apache.hadoop:hadoop-common:$hadoopVersion"
        providedCompile "org.apache.hadoop:hadoop-hdfs:$hadoopVersion"
        providedCompile "org.apache.hadoop:hadoop-auth:$hadoopVersion"
        providedCompile "org.apache.hadoop:hadoop-annotations:$hadoopVersion"
        providedCompile "org.apache.hadoop:hadoop-mapreduce-client-core:$hadoopVersion"
        providedCompile "org.apache.tomcat:tomcat-catalina:$tomcatVersion"
        providedCompile("org.apache.hive:hive-exec:$hiveVersion") {
            exclude module: 'calcite-core'
            exclude module: 'calcite-avatica'
        }
        runtime "org.apache.parquet:parquet-hadoop-bundle:$parquetVersion"
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), service REST API'
        description = 'Rest API for the HAWQ Extenstion framework'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires('apache-tomcat', "$tomcatVersion", GREATER | EQUAL)
        requires('hadoop', "$hadoopVersion", GREATER | EQUAL)
        requires('hadoop-hdfs', "$hadoopVersion", GREATER | EQUAL)

        // Upgrades pxf-core, pxf-api to pxf-service
        obsoletes('pxf-core')
        obsoletes('pxf-api')

        from('src/main/resources/pxf-profiles.xml') {
            fileType CONFIG | NOREPLACE
            into "/etc/pxf-${project.version}/conf"
        }

        from('src/configs/pxf-site.xml') {
            fileType CONFIG | NOREPLACE
            into "/etc/pxf-${project.version}/conf"
        }

        from("src/main/resources") {
            into("/etc/pxf-${project.version}/conf")
            include("**/pxf-private*.classpath")
            exclude("**/pxf-private.classpath")
        }

        from("src/main/resources/pxf-private${hddist}.classpath") {
            into("/etc/pxf-${project.version}/conf")
            rename("pxf-private${hddist}.classpath", "pxf-private.classpath") 
        }

        from('src/main/resources/pxf-public.classpath') {
            fileType CONFIG | NOREPLACE
            into "/etc/pxf-${project.version}/conf"
        }

        from('src/scripts/pxf-env.sh') {
            fileMode 0755
            fileType NOREPLACE
            filter(ReplaceTokens,
                    tokens: ['pxfLogDir'     :  databaseProperties.pxfLogDir,
                             'pxfRunDir'     :  databaseProperties.pxfRunDir,
                             'pxfPortNum'    :  databaseProperties.pxfPortNum,
                             'pxfDefaultUser': (databaseProperties.pxfDefaultUser == null ? "" : databaseProperties.pxfDefaultUser),
                             'pxfDefaultUserImpersonation': (databaseProperties.pxfDefaultUserImpersonation == null ? "" : databaseProperties.pxfDefaultUserImpersonation)])
            into "/etc/pxf-${project.version}/conf"
        }
        
        from('src/main/resources/pxf-log4j.properties') {
            fileType CONFIG | NOREPLACE
            into "/etc/pxf-${project.version}/conf"
        }

        from(war.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }
        
        //tomcat configuration files
        from('src/configs/tomcat') {
            fileType CONFIG | NOREPLACE
            into "/opt/pxf-${project.version}/tomcat-templates"
        }

        from('src/scripts/pxf-service') {
            fileMode 0755
            addParentDirs false
            into "/opt/pxf-${project.version}"
            filter(ReplaceTokens,
                    tokens: [
                            'pxfPortNum'    :  databaseProperties.pxfPortNum,
                            'pxfDefaultUser': (databaseProperties.pxfDefaultUser == null ? "" : databaseProperties.pxfDefaultUser)])
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")

    }

    project.distTar {
        from('src/main/resources/pxf-profiles.xml') { into 'conf' }
        from("src/main/resources") { into 'conf' include '**/pxf-private*.classpath'}
        from("src/main/resources/pxf-private${hddist}.classpath") { into 'conf' rename {'pxf-private.classpath'} }
        from('src/main/resources/pxf-public.classpath') { into 'conf' }
        from(project(':pxf-api').jar.outputs.files)
        from(war.outputs.files)
    }
}

project('pxf') {
    jar.enabled = false
    ospackage {
        summary = 'HAWQ Extension Framework (PXF)'
        description = 'HAWQ Extension framework Virtual RPM'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-hdfs'), project.version, GREATER | EQUAL)
        requires(versionedPackageName('pxf-hive'), project.version, GREATER | EQUAL)
        requires(versionedPackageName('pxf-hbase'), project.version, GREATER | EQUAL)
        requires(versionedPackageName('pxf-json'), project.version, GREATER | EQUAL)
        requires(versionedPackageName('pxf-jdbc'), project.version, GREATER | EQUAL)
        requires(versionedPackageName('pxf-ignite'), project.version, GREATER | EQUAL)

        preInstall file('src/scripts/pre-install.sh')
        postInstall file('src/scripts/post-install.sh')

        link('/usr/lib/pxf', "/usr/lib/pxf-${project.version}")
        link('/etc/pxf', "/etc/pxf-${project.version}")
        link('/opt/pxf', "/opt/pxf-${project.version}")
        link('/etc/init.d/pxf-service', "/opt/pxf/pxf-service")

        from('../resources/META-INF/DISCLAIMER') {
            into "/opt/pxf-${project.version}"
        }

        from('../resources/META-INF/LICENSE') {
            into "/opt/pxf-${project.version}"
        }

        from('../resources/META-INF/NOTICE') {
            into "/opt/pxf-${project.version}"
        }
    }
}

project('pxf-hdfs') {
    dependencies {
        compile(project(':pxf-api'))
        compile 'org.apache.avro:avro-mapred:1.7.4'
        compile "org.apache.hadoop:hadoop-mapreduce-client-core:$hadoopVersion"
        compile "org.apache.hadoop:hadoop-common:$hadoopVersion"
        compile "org.apache.hadoop:hadoop-hdfs:$hadoopVersion"
        compile "org.apache.parquet:parquet-hadoop-bundle:$parquetVersion"
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), HDFS plugin'
        description = 'Querying external data stored in HDFS'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-service'), project.version, GREATER | EQUAL)
        requires('hadoop', "$hadoopVersion", GREATER | EQUAL)
        requires('hadoop-mapreduce', "$hadoopVersion", GREATER | EQUAL)

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }
}

project('pxf-hive') {
    dependencies {
        compile(project(':pxf-hdfs'))
        compile(project(':pxf-service'))
        compile("org.apache.hive:hive-exec:$hiveVersion") {
            exclude module: 'calcite-core'
            exclude module: 'calcite-avatica'
        }
        compile "org.apache.hive:hive-metastore:$hiveVersion"
        compile "org.apache.hive:hive-common:$hiveVersion"
        compile "org.apache.hive:hive-serde:$hiveVersion"
        testCompile 'pl.pragmatists:JUnitParams:1.0.2'
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), Hive plugin'
        description = 'Querying external data stored in Hive'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-hdfs'), project.version, GREATER | EQUAL)

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }
}

project('pxf-json') {
    dependencies {
      compile(project(':pxf-hdfs'))
      compile(project(':pxf-service'))
      testCompile 'pl.pragmatists:JUnitParams:1.0.2'
    }

    ospackage {
      requires(versionedPackageName('pxf-hdfs'), project.version, GREATER | EQUAL)
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), Json plugin'
        description = 'Querying external data stored in HDFS in Json format'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

      from(jar.outputs.files) {
        into "/usr/lib/pxf-${project.version}"
      }

      link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }

    task create_tweets_tgz(type: Exec){
      commandLine 'tar', '-zcf', 'src/test/resources/tweets.tar.gz', '-C', 'src/test/resources', 'tweets-pp.json'
    }
    
    tasks['test'].dependsOn('create_tweets_tgz')
}

project('pxf-hbase') {
    dependencies {
        compile(project(':pxf-api'))
        compile "org.apache.hadoop:hadoop-common:$hadoopVersion"
        compile "org.apache.hbase:hbase-client:$hbaseVersionJar"
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), HBase plugin'
        description = 'Querying external data stored in HBase'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-service'), project.version, GREATER | EQUAL)

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }
}

project('pxf-jdbc') {
    dependencies {
        compile(project(':pxf-api'))
        compile(project(':pxf-service'))
        compile "org.apache.hadoop:hadoop-common:$hadoopVersion"
        compile "org.apache.hadoop:hadoop-hdfs:$hadoopVersion"
        testCompile "mysql:mysql-connector-java:5.1.6"
    }
    tasks.withType(JavaCompile) {
        options.encoding = "UTF-8"
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), JDBC plugin'
        description = 'Querying external data stored in Relation Database using JDBC.'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-service'), project.version, GREATER | EQUAL)

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }
}

project('pxf-ignite') {
    dependencies {
        compile(project(':pxf-api'))
        compile(project(':pxf-service'))
        compile 'com.google.code.gson:gson:2.8.2'
        compile 'org.apache.commons:commons-compress:1.16.1'
        testCompile 'com.google.code.gson:gson:2.8.2'
        testCompile 'org.apache.commons:commons-compress:1.16.1'
    }

    ospackage {
        packageName = versionedPackageName("${project.name}")
        summary = 'HAWQ Extension Framework (PXF), Apache Ignite plugin'
        description = 'Querying external data stored in the Apache Ignite database.'
        packager = ' '
        packageGroup = 'Development/Libraries'
        release = buildNumber() + '.' + project.osFamily
        buildHost = ' '

        requires(versionedPackageName('pxf-service'), project.version, GREATER | EQUAL)

        from(jar.outputs.files) {
            into "/usr/lib/pxf-${project.version}"
        }

        link("/usr/lib/pxf-${project.version}/${project.name}.jar", "${project.name}-${project.version}.jar")
    }
}


def buildNumber() {
    System.getenv('BUILD_NUMBER') ?: System.getProperty('user.name')
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.13'
}

def distSubprojects = subprojects - project(':pxf-api')

task release(type: Copy, dependsOn: [subprojects.build, subprojects.javadoc, distSubprojects.buildRpm, distSubprojects.distTar]) {
    delete 'build'
    into 'build'
    subprojects { subProject ->
        from("${project.name}/build/libs") { into 'libs' }
        from("${project.name}/build/distributions") { into 'distributions' }
        from("${project.name}/build/test-results") { into 'test-results' }
    }
}

task tar(type: Copy, dependsOn: [subprojects.build, distSubprojects.distTar]) {
    into 'build'
    distSubprojects.each { project ->
        from("${project.name}/build/distributions") { into 'distributions' }
    }
}

task jar(type: Copy, dependsOn: [subprojects.build]) {
    into 'build'
    subprojects { subProject ->
        from("${project.name}/build/libs") { into 'libs' }
    }
}

task rpm(type: Copy, dependsOn: [subprojects.build, distSubprojects.buildRpm]) {
    into 'build'
    distSubprojects.each { project ->
        from("${project.name}/build/distributions") { into 'distributions' }
    }
}

// tomcat 
def tomcatName = "apache-tomcat-${tomcatVersion}"
def tomcatTargetDir = "tomcat/build"

task tomcatGet << {

    apply plugin: 'de.undercouch.download'

    def TarGzSuffix = ".tar.gz"
    def tomcatTar = "${tomcatName}${TarGzSuffix}"
    def tomcatUrl = "http://archive.apache.org/dist/tomcat/tomcat-7/v${tomcatVersion}/bin/${tomcatTar}"

    if (file("${tomcatTargetDir}/${tomcatName}").exists()) {
        println "${tomcatName} already exists, nothing to do"
        return 0
    }

    println "About to download from ${tomcatUrl}..."
    // download tar ball
    download {
        src tomcatUrl
        dest "${tomcatTargetDir}/${tomcatTar}"
    }
    // extract tar ball
    println "Extracting..."
    copy {
        from tarTree(resources.gzip("${tomcatTargetDir}/${tomcatTar}"))
        into tomcatTargetDir
    }
}

apply plugin: 'os-package'

task tomcatRpm(type: Rpm) {
    buildDir = "${tomcatTargetDir}"

    // clean should not delete the downloaded tarball
    // and RPM, so this is a bogus directory to delete instead.
    clean {
        delete = "${tomcatTargetDir}/something"
    }

    ospackage {
        packageName 'apache-tomcat'
        summary = 'Apache Tomcat RPM'
        vendor = project.vendor
        version = tomcatVersion
        os = LINUX
        license = project.license
        user = 'root'
        permissionGroup = 'root'
        packager = ' '
        packageDescription = 'Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies.'
        packageGroup = 'Development/Libraries'
        release = project.osFamily
        buildHost = ' '

        preInstall file('tomcat/src/scripts/pre-install.sh')

        from("${tomcatTargetDir}/${tomcatName}") {
            user 'tomcat'
            permissionGroup 'tomcat'
            addParentDirs false
            into "/opt/${tomcatName}"
        }

        link("/opt/${packageName}", "${tomcatName}")
    }
}

tomcatRpm.dependsOn tomcatGet

def pxfTargetDir = System.properties['deployPath'] ?: "build/"

task install(type: Copy, dependsOn: [subprojects.build, tomcatGet]) {
    into "${pxfTargetDir}"
    subprojects { project ->
        from("${project.name}/build/libs") { into 'lib' }
    }
    from("pxf-service/src/scripts/pxf-service") {
        into 'bin'
        fileMode 0755
        rename('pxf-service', 'pxf')
        filter(ReplaceTokens,
                tokens: [
                        'pxfPortNum'    : databaseProperties.pxfPortNum,
                        'pxfDefaultUser': (databaseProperties.pxfDefaultUser == null ? "" : databaseProperties.pxfDefaultUser)])
    }

    from("${tomcatTargetDir}/${tomcatName}") { into 'apache-tomcat' }
    from("pxf-service/src/main/resources") { into 'conf' }
    from("pxf-service/src/configs/pxf-site.xml") { into 'conf' }
    from("pxf-service/src/scripts/pxf-env.sh") {
        filter(ReplaceTokens,
                tokens: ['pxfLogDir'     : databaseProperties.pxfLogDir,
                         'pxfRunDir'     : databaseProperties.pxfRunDir,
                         'pxfPortNum'    : databaseProperties.pxfPortNum,
                         'pxfDefaultUser': (databaseProperties.pxfDefaultUser == null ? "" : databaseProperties.pxfDefaultUser),
                         'pxfDefaultUserImpersonation': (databaseProperties.pxfDefaultUserImpersonation == null ? "" : databaseProperties.pxfDefaultUserImpersonation)]) into 'conf'
    }
    from("pxf-service/src/configs/tomcat") { into 'tomcat-templates' }
    from("pxf-service/src/configs/templates") { into 'conf-templates' }
}

task bundle(type: Tar) {
    baseName = "${project.name}"
    compression = Compression.GZIP
    extension = 'tar.gz'
    from install.outputs.files
    into "${project.name}"
}

buildDir = '.'
apply plugin: 'nebula-aggregate-javadocs'
