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

name.remal.gradle_plugins.dsl.extensions.org.gradle.api.Task.kt Maven / Gradle / Ivy

package name.remal.gradle_plugins.dsl.extensions

import com.google.common.annotations.VisibleForTesting
import name.remal.KotlinAllOpen
import name.remal.Ordered
import name.remal.copyOnWriteListOf
import name.remal.gradle_plugins.dsl.PluginId
import name.remal.gradle_plugins.dsl.ProjectPluginClass
import name.remal.gradle_plugins.dsl.utils.findPluginId
import name.remal.uncheckedCast
import org.gradle.api.Task
import java.util.concurrent.Callable
import java.util.concurrent.atomic.AtomicLong
import kotlin.reflect.KFunction0
import kotlin.reflect.KProperty0

val Task.dependencyTasks: Set get() = taskDependencies.getDependencies(this)

val Task.isInTaskGraph: Boolean get() = project.gradle.taskGraph.hasTask(this)
val Task.isRequested: Boolean get() = project.gradle.startParameter.taskNames.any { name == it }
val Task.isParentProjectTaskWithSameNameInGraph: Boolean get() = project.parents.any { it.tasks.findByName(name)?.isInTaskGraph == true }
val Task.isThereTaskWithSameNameInGraphBefore: Boolean get() = project.gradle.taskGraph.allTasks.filter { it.name == name }.indexOf(this) >= 1

fun Task.dependsOn(configurer: () -> Iterable<*>) = dependsOnIf({ true }, configurer)
fun  TaskType.dependsOnIf(condition: KFunction0, configurer: () -> Iterable<*>) = dependsOnIf({ condition() }, configurer)
fun  TaskType.dependsOnIf(condition: KProperty0, configurer: () -> Iterable<*>) = dependsOnIf({ condition() }, configurer)
fun  TaskType.dependsOnIf(condition: TaskType.() -> Boolean, configurer: () -> Iterable<*>) = apply {
    dependsOn(Callable> {
        if (condition()) {
            configurer()
        } else {
            emptyList()
        }
    })
}

fun Task.shouldRunAfter(configurer: () -> Iterable<*>) = shouldRunAfterIf({ true }, configurer)
fun  TaskType.shouldRunAfterIf(condition: KFunction0, configurer: () -> Iterable<*>) = shouldRunAfterIf({ condition() }, configurer)
fun  TaskType.shouldRunAfterIf(condition: KProperty0, configurer: () -> Iterable<*>) = shouldRunAfterIf({ condition() }, configurer)
fun  TaskType.shouldRunAfterIf(condition: TaskType.() -> Boolean, configurer: () -> Iterable<*>) = apply {
    shouldRunAfter(Callable> {
        if (condition()) {
            configurer()
        } else {
            emptyList()
        }
    })
}

fun Task.mustRunAfter(configurer: () -> Iterable<*>) = mustRunAfterIf({ true }, configurer)
fun  TaskType.mustRunAfterIf(condition: KFunction0, configurer: () -> Iterable<*>) = mustRunAfterIf({ condition() }, configurer)
fun  TaskType.mustRunAfterIf(condition: KProperty0, configurer: () -> Iterable<*>) = mustRunAfterIf({ condition() }, configurer)
fun  TaskType.mustRunAfterIf(condition: TaskType.() -> Boolean, configurer: () -> Iterable<*>) = apply {
    mustRunAfter(Callable> {
        if (condition()) {
            configurer()
        } else {
            emptyList()
        }
    })
}


fun Task.requirePlugin(pluginId: PluginId) {
    if (!project.isPluginApplied(pluginId)) {
        logDebug(
            "Task '{}'({}) requires {} plugin applied. Applying the plugin...",
            name,
            javaClass.unwrapGradleGenerated(),
            if (pluginId.alternateIds.isEmpty())
                pluginId.id
            else
                buildString {
                    append(pluginId.id)
                    append(" (")
                    pluginId.alternateIds.joinTo(this, " / ")
                    append('}')
                }
        )
        project.applyPlugin(pluginId)
    }
}

fun Task.requirePlugin(pluginClass: ProjectPluginClass) {
    if (!project.isPluginApplied(pluginClass)) {
        if (isDebugLogEnabled) {
            logDebug(
                "Task '{}'({}) requires {} plugin applied. Applying the plugin...",
                name,
                javaClass.unwrapGradleGenerated(),
                findPluginId(pluginClass) ?: pluginClass.name
            )
        }
        project.applyPlugin(pluginClass)
    }
}


fun Task.skipIfOffline() {
    onlyIf {
        if (project.gradle.startParameter.isOffline) {
            logWarn("Skip because Gradle is running in offline mode")
            return@onlyIf false
        }
        return@onlyIf true
    }
}


private val noSourcePropertySuffix = AtomicLong(0)
fun  T.noSourceIf(noSourceIfSpec: (task: T) -> Boolean) {
    doSetup {} // we want to register setup actions first
    onlyIf {
        if (noSourceIfSpec(this)) {
            it.inputs.files()
                .withPropertyName("\$noSourceIf_${noSourcePropertySuffix.incrementAndGet()}")
                .skipWhenEmpty()
        }
        return@onlyIf true
    }
}


fun  T.doSetup(order: Int, configureAction: (task: T) -> Unit) {
    val actionsContainerTask: TaskSetupActionsContainer = this.extensions.getOrCreateWithAutoName(
        TaskSetupActionsContainer::class.java,
        { onlyIf { executeSetupActions(); true } }
    )

    actionsContainerTask.actions.add(object : TaskSetupAction() {
        override fun getOrder() = order
        override fun setup(task: Task) = configureAction(task.uncheckedCast())
    })
}

fun  T.doSetup(configureAction: (task: T) -> Unit) = doSetup(0, configureAction)

fun  T.doSetupIf(order: Int, condition: (task: T) -> Boolean, configureAction: (task: T) -> Unit) = doSetup(order) {
    if (condition(it)) {
        configureAction(it)
    }
}

fun  T.doSetupIf(condition: (task: T) -> Boolean, configureAction: (task: T) -> Unit) = doSetupIf(0, condition, configureAction)


fun  T.doSetupAndAfterEvaluate(order: Int, configureAction: (task: T) -> Unit) {
    project.afterEvaluateOrNow(order) { _ -> configureAction(this) }
    doSetup(order, configureAction)
}

fun  T.doSetupAndAfterEvaluate(configureAction: (task: T) -> Unit) {
    project.afterEvaluateOrNow { _ -> configureAction(this) }
    doSetup(configureAction)
}

fun  T.doSetupIfAndAfterEvaluate(order: Int, condition: (task: T) -> Boolean, configureAction: (task: T) -> Unit) {
    project.afterEvaluateOrNow(order) { _ -> if (condition(this)) configureAction(this) }
    doSetupIf(order, condition, configureAction)
}

fun  T.doSetupIfAndAfterEvaluate(condition: (task: T) -> Boolean, configureAction: (task: T) -> Unit) {
    project.afterEvaluateOrNow { _ -> if (condition(this)) configureAction(this) }
    doSetupIf(condition, configureAction)
}


@VisibleForTesting
internal fun Task.executeSetupActions() {
    val actionsContainer = this.extensions.findByType(TaskSetupActionsContainer::class.java) ?: return
    actionsContainer.actions.sorted().forEach { it.setup(this) }
}


private abstract class TaskSetupAction : Ordered {

    companion object {
        private val setupActionNextIndex = AtomicLong(Long.MIN_VALUE)
    }

    abstract fun setup(task: Task)

    private val actionIndex = setupActionNextIndex.getAndIncrement()

    override fun compareTo(other: TaskSetupAction): Int {
        super.compareTo(other).let { if (it != 0) return it }
        return actionIndex.compareTo(other.actionIndex)
    }

}

@KotlinAllOpen
private class TaskSetupActionsContainer {
    val actions = copyOnWriteListOf()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy