// 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 common tasks and configuration for artifact publishing.

apply plugin: "maven"
apply plugin: "signing"

ext {
  // This allows simplified builds and local maven installs.
  forceSigning = propertyExists("forceSigning")
  skipSigning = propertyExists("skipSigning")
  shouldSign =
      // Always sign artifacts if -PforceSigning is passed.
      forceSigning ||
          // Skip signing artifacts by default if -PskipSigning is passed.
          (!skipSigning
              // Sign artifacts if the version is not a snapshot, and we are uploading them to maven.
              && !version.endsWith("SNAPSHOT")
              && project.gradle.startParameter.taskNames.any { it.contains("upload") })
  // These properties can be set in ~/.gradle/gradle.properties file,
  // though it would be open text. They can also be set on the cli via
  // -PmavenUsername and -PmavenPassword.
  mavenPublishUrl = propertyWithDefault("mavenPublishUrl", "")
  mavenUsername = propertyWithDefault("mavenUsername", "")
  mavenPassword = propertyWithDefault("mavenPassword", "")
}

uploadArchives {
  repositories {
    signing {
      required { shouldSign }
      // Check if we are going to sign, because CI environments may not have
      // gpg on their path and useGpgCmd evaluates eagerly.
      if (shouldSign) {
        useGpgCmd() // Use gpg-agent to sign
      }
      sign configurations.archives
      mavenDeployer {
        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
        repository(url: "${mavenPublishUrl}") {
          authentication(userName: "${mavenUsername}", password: "${mavenPassword}")
        }
        afterEvaluate {
          pom.project {
            url = "$url"
            licenses {
              license {
                name = "The Apache Software License, Version 2.0"
                url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
                distribution = "repo"
              }
            }
          }
        }
      }
    }
  }
}

// Add the install task to the "Upload" group so it's visible in the tasks output.
install.group = "Upload"

// Sort the generated maven dependencies to make pom comparisons easier.
tasks.withType(Upload) {
  def installer = install.repositories.mavenInstaller
  def deployer = uploadArchives.repositories.mavenDeployer

  [installer, deployer]*.pom*.whenConfigured { pom ->
    pom.dependencies = pom.dependencies.sort { dep ->
      "$dep.scope:$dep.optional:$dep.groupId:$dep.artifactId"
    }
  }
}


