All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.autonomousapps.internal.advice.SeverityHandler.kt Maven / Gradle / Ivy

There is a newer version: 2.6.1
Show newest version
// Copyright (c) 2024. Tony Robalik.
// SPDX-License-Identifier: Apache-2.0
package com.autonomousapps.internal.advice

import com.autonomousapps.model.PluginAdvice
import com.autonomousapps.extension.Behavior
import com.autonomousapps.extension.Fail
import com.autonomousapps.internal.DependencyScope
import com.autonomousapps.internal.utils.filterToSet
import com.autonomousapps.internal.utils.lowercase
import com.autonomousapps.model.Advice
import com.autonomousapps.model.ModuleAdvice
import com.autonomousapps.model.Advice as DependencyAdvice

/** Given the set of all behaviors, determine whether the analysis should fail the build. */
internal class SeverityHandler(
  private val anyBehavior: Pair>,
  private val unusedDependenciesBehavior: Pair>,
  private val usedTransitiveDependenciesBehavior: Pair>,
  private val incorrectConfigurationBehavior: Pair>,
  private val compileOnlyBehavior: Pair>,
  private val unusedProcsBehavior: Pair>,
  private val redundantPluginsBehavior: Behavior,
  private val moduleStructureBehavior: Behavior,
) {

  fun shouldFailDeps(advice: Set): Boolean {
    return shouldFailFor(anyBehavior, advice) ||
      shouldFailFor(unusedDependenciesBehavior, advice.filterToSet { it.isRemove() }) ||
      shouldFailFor(usedTransitiveDependenciesBehavior, advice.filterToSet { it.isAdd() }) ||
      shouldFailFor(incorrectConfigurationBehavior, advice.filterToSet { it.isChange() }) ||
      shouldFailFor(compileOnlyBehavior, advice.filterToSet { it.isCompileOnly() }) ||
      shouldFailFor(unusedProcsBehavior, advice.filterToSet { it.isProcessor() })
  }

  private fun shouldFailFor(
    spec: Pair>,
    advice: Set,
  ): Boolean {
    // Seed the "global" advice with the set of all possible advice. Later on we'll drain this set as elements of it are
    // "consumed" by sourceSet-specific behaviors.
    val globalAdvice = advice.toMutableSet()

    val bySourceSets: (Advice) -> Boolean = { a ->
      // These are the custom behaviors, if any, associated with the source sets represented by this advice.
      val behaviors = spec.second.filter { b ->
        val from = a.fromConfiguration?.let { DependencyScope.sourceSetName(it) }
        val to = a.toConfiguration?.let { DependencyScope.sourceSetName(it) }

        b.sourceSetName == from || b.sourceSetName == to
      }


      // Looking for a match between sourceSet-specific behavior and advice.
      var shouldFail = false
      behaviors.forEach { b ->
        val s = b.sourceSetName.lowercase()
        val from = a.fromConfiguration?.lowercase()?.startsWith(s) == true
        val to = a.toConfiguration?.lowercase()?.startsWith(s) == true

        if (from || to) {
          shouldFail = shouldFail || b.isFail()
          globalAdvice.remove(a)
        }
      }

      shouldFail
    }

    // If all advice is sourceSet-specific, then globalAdvice will be empty.
    return advice.any(bySourceSets) || (spec.first.isFail() && globalAdvice.isNotEmpty())
  }

  fun shouldFailPlugins(pluginAdvice: Set): Boolean {
    return (redundantPluginsBehavior.isFail() || anyBehavior.first.isFail()) && pluginAdvice.isNotEmpty()
  }

  fun shouldFailModuleStructure(moduleAdvice: Set): Boolean {
    return (moduleStructureBehavior.isFail() || anyBehavior.first.isFail()) && ModuleAdvice.isNotEmpty(moduleAdvice)
  }

  private fun Behavior.isFail(): Boolean = this is Fail
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy