// 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.kudu.gradle.DistTestTask

// This file is the entry-point for the gradle build and contains
// common logic for the various subprojects in the build.
// Plugins and scripts are applied in the natural "build order"
// they are used to ensure there are no dependency issues.

// Plugins and scripts applied at the root level only, instead of per module.
apply plugin: "idea"
apply plugin: "eclipse"
apply plugin: "org.barfuin.gradle.jacocolog"
apply from: "$rootDir/gradle/properties.gradle"
apply from: "$rootDir/gradle/dependencies.gradle"
apply from: "$rootDir/gradle/wrapper.gradle"

allprojects {
  // These are common to all projects, including this
  // top level parent project.
  repositories {
    mavenCentral()
    mavenLocal()
  }

  // Read the version.txt file to set the project version
  project.version = file("$rootDir/../version.txt").text.trim()

  apply from: "$rootDir/gradle/docs.gradle"
}

subprojects {
  // These are common to all subprojects. However, subprojects may
  // include their own plugins and scripts as well.
  apply plugin: "java"
  apply from: "$rootDir/gradle/scopes.gradle"
  apply from: "$rootDir/gradle/compile.gradle"
  apply from: "$rootDir/gradle/tests.gradle"
  apply from: "$rootDir/gradle/quality.gradle"
  apply from: "$rootDir/gradle/artifacts.gradle"
  apply from: "$rootDir/gradle/publishing.gradle"

  // Ignore the transitive annotations libraries that are
  // not marked as optional in Guava version 22.0+.
  // See https://github.com/google/guava/issues/2824
  configurations.compile {
    exclude group: "com.google.errorprone", module: "error_prone_annotations"
    exclude group: "com.google.code.findbugs", module: "jsr305"
    exclude group: "com.google.j2objc", module: "j2objc-annotations"
    exclude group: "org.checkerframework", module: "checker-compat-qual"
    exclude group: "org.codehaus.mojo", module: "animal-sniffer-annotations"
  }
}

// A task that does nothing, but is useful to ensure the Gradle build and tasks are initialized.
task initializeTasks() {
  doLast {
    println("Initialized Gradle tasks")
  }
}

task javadocAggregate(type: Javadoc, group: "Documentation") {
  description = "Generates Aggregate Javadoc API documentation for the main source code."
  source subprojects.collect { it.sourceSets.main.allJava }
  classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath })
  destinationDir = file("${buildDir}/docs/javadoc")
}

// Copies all the dependency jars locally so that we can reference
// them inside the project structure while running the distributed
// tests instead of in the gradle cache which is in the users home
// directory by default.
task copyDistTestJars(type: Copy) {
  into "$buildDir/jars/"
  from subprojects.collect {
    it.configurations.testRuntime
  }
  from subprojects.collect {
    it.configurations.provided
  }
}

// Task called by dist_test.py to generate the needed .isolate and .gen.json
// files needed to run the distributed tests.
task distTest(type: DistTestTask, dependsOn: copyDistTestJars) {
  subprojects.each {
    it.tasks.withType(Test).each {
      addTestTask it
    }
  }
}
