// 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.

// This file contains all of the dependencies required for the build.
// Centrally locating all of the dependencies ensures each subproject
// uses the same dependency version for all dependencies used.

ext {
  versions = [:]
  libs = [:]
}

versions += [
    async          : "1.4.1",
    checkstyle     : "8.36.1",
    clojure        : "1.10.3",
    clojureToolsCli: "1.0.206",
    commonsIo      : "2.11.0",
    errorProne     : "2.3.3",
    errorProneJavac: "9+181-r4173-1",
    gradle         : "6.9.2",
    guava          : "30.1-jre",
    hadoop         : "3.3.1",
    hamcrest       : "2.2",
    hdrhistogram   : "2.1.12",
    hive           : "3.1.2",
    httpClient     : "4.5.13",
    jacoco         : "0.8.6",
    jepsen         : "0.1.5",
    jetty          : "9.4.44.v20210927",
    jmh            : "1.34",
    jsr305         : "3.0.2",
    junit          : "4.13.2",
    log4j          : "2.17.1",
    micrometer     : "1.8.2",
    mockito        : "4.2.0",
    murmur         : "1.0.0",
    netty          : "4.1.73.Final",
    osdetector     : "1.6.2",
    protobuf       : "3.19.3",
    ranger         : "2.1.0",
    scala211       : "2.11.12",
    scala          : "2.12.15",
    scalatest      : "3.2.10",
    scopt          : "4.0.1",
    slf4j          : "1.7.33",
    spark2         : "2.4.8",
    spark          : "3.1.2",
    spotBugs       : "4.1.1",
    yetus          : "0.13.0"
]

// Log the Gradle version used vs defined.
if (gradle.gradleVersion != versions.gradle) {
  logger.warn("Using gradle version $gradle.gradleVersion (Build defines $versions.gradle)")
}

// If the `spark2` property is passed, override the `spark` and `scala` version
// to use the `spark2` and `scala211` versions.
if (propertyExists("spark2")) {
  versions["spark"] = "$versions.spark2"
  versions["scala"] = "$versions.scala211"
}

// Add base Scala version
versions["scalaBase"] = versions.scala.substring(0, versions.scala.lastIndexOf("."))

// Add base Spark version
versions["sparkBase"] = versions.spark.substring(0, versions.spark.indexOf("."))

libs += [
    async                : "com.stumbleupon:async:$versions.async",
    clojure              : "org.clojure:clojure:$versions.clojure",
    clojureToolsCli      : "org.clojure:tools.cli:$versions.clojureToolsCli",
    commonsIo            : "commons-io:commons-io:$versions.commonsIo",
    errorProne           : "com.google.errorprone:error_prone_core:$versions.errorProne",
    errorProneJavac      : "com.google.errorprone:javac:$versions.errorProneJavac",
    guava                : "com.google.guava:guava:$versions.guava",
    hadoopClient         : "org.apache.hadoop:hadoop-client:$versions.hadoop",
    hadoopCommon         : "org.apache.hadoop:hadoop-common:$versions.hadoop",
    hadoopMiniCluster    : "org.apache.hadoop:hadoop-minicluster:$versions.hadoop",
    hadoopMRClientCommon : "org.apache.hadoop:hadoop-mapreduce-client-common:$versions.hadoop",
    hadoopMRClientCore   : "org.apache.hadoop:hadoop-mapreduce-client-core:$versions.hadoop",
    hamcrest             : "org.hamcrest:hamcrest:$versions.hamcrest",
    hdrhistogram         : "org.hdrhistogram:HdrHistogram:$versions.hdrhistogram",
    hiveMetastore        : "org.apache.hive:hive-metastore:$versions.hive",
    hiveTestUtils        : "org.apache.hive:hive-testutils:$versions.hive",
    httpClient           : "org.apache.httpcomponents:httpclient:$versions.httpClient",
    httpMime             : "org.apache.httpcomponents:httpmime:$versions.httpClient",
    jepsen               : "jepsen:jepsen:$versions.jepsen",
    jetty                : "org.eclipse.jetty:jetty-server:$versions.jetty",
    jettyServlet         : "org.eclipse.jetty:jetty-servlet:$versions.jetty",
    jmhCore              : "org.openjdk.jmh:jmh-core:$versions.jmh",
    jmhGenerator         : "org.openjdk.jmh:jmh-generator-annprocess:$versions.jmh",
    jsr305               : "com.google.code.findbugs:jsr305:$versions.jsr305",
    junit                : "junit:junit:$versions.junit",
    log4jApi             : "org.apache.logging.log4j:log4j-api:$versions.log4j",
    log4jCompat          : "org.apache.logging.log4j:log4j-1.2-api:$versions.log4j",
    log4jCore            : "org.apache.logging.log4j:log4j-core:$versions.log4j",
    log4jSlf4jImpl       : "org.apache.logging.log4j:log4j-slf4j-impl:$versions.log4j",
    micrometerCore       : "io.micrometer:micrometer-core:$versions.micrometer",
    mockitoCore          : "org.mockito:mockito-core:$versions.mockito",
    murmur               : "com.sangupta:murmur:$versions.murmur",
    netty                : "io.netty:netty-all:$versions.netty",
    osdetector           : "com.google.gradle:osdetector-gradle-plugin:$versions.osdetector",
    protobufJava         : "com.google.protobuf:protobuf-java:$versions.protobuf",
    protobufJavaUtil     : "com.google.protobuf:protobuf-java-util:$versions.protobuf",
    protoc               : "com.google.protobuf:protoc:$versions.protobuf",
    rangerPlugin         : "org.apache.ranger:ranger-plugins-common:$versions.ranger",
    scalaLibrary         : "org.scala-lang:scala-library:$versions.scala",
    scalap               : "org.scala-lang:scalap:$versions.scala",
    scalatest            : "org.scalatest:scalatest_$versions.scalaBase:$versions.scalatest",
    scopt                : "com.github.scopt:scopt_$versions.scalaBase:$versions.scopt",
    slf4jApi             : "org.slf4j:slf4j-api:$versions.slf4j",
    sparkAvro            : "org.apache.spark:spark-avro_$versions.scalaBase:$versions.spark",
    sparkCore            : "org.apache.spark:spark-core_$versions.scalaBase:$versions.spark",
    sparkSql             : "org.apache.spark:spark-sql_$versions.scalaBase:$versions.spark",
    sparkSqlTest         : "org.apache.spark:spark-sql_$versions.scalaBase:$versions.spark:tests",
    yetusAnnotations     : "org.apache.yetus:audience-annotations:$versions.yetus"
]
