main.name.remal.gradle_plugins.plugins.common.RebuildIfDependenciesAreChangedPlugin.kt Maven / Gradle / Ivy
package name.remal.gradle_plugins.plugins.common
import name.remal.createParentDirectories
import name.remal.forceDelete
import name.remal.gradle_plugins.dsl.ApplyPluginClasses
import name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin
import name.remal.gradle_plugins.dsl.EnvironmentVariable
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.PluginActionsGroup
import name.remal.gradle_plugins.dsl.PluginCondition
import name.remal.gradle_plugins.dsl.extensions.all
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.dsl.extensions.logDebug
import name.remal.gradle_plugins.dsl.extensions.logWarn
import name.remal.gradle_plugins.dsl.extensions.mustRunAfter
import name.remal.gradle_plugins.plugins.vcs.AutoVcsVersionExtension
import name.remal.gradle_plugins.plugins.vcs.AutoVcsVersionPlugin
import name.remal.gradle_plugins.plugins.vcs.BaseCreateTagTask
import name.remal.gradle_plugins.plugins.vcs.CreateDependenciesHashTag
import name.remal.gradle_plugins.plugins.vcs.CreateProjectVersionTag
import name.remal.gradle_plugins.plugins.vcs.VcsOperationsExtension
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin.ASSEMBLE_TASK_NAME
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.plugins.JavaBasePlugin.BUILD_TASK_NAME
import org.gradle.api.plugins.JavaBasePlugin.CHECK_TASK_NAME
import org.gradle.api.plugins.JavaPlugin.TEST_TASK_NAME
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
import org.gradle.api.tasks.TaskContainer
import java.io.File
import java.lang.System.getenv
@Deprecated(message = "Use automatic dependency updates software like Renovate, Dependabot, etc...")
@Plugin(
id = "name.remal.rebuild-if-dependencies-are-changed",
description = "Creates 'createDependenciesHashTag' and handles 'PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED' environment variable.",
tags = ["dependencies"],
isHidden = true
)
@ApplyPluginClasses(AutoVcsVersionPlugin::class)
@EnvironmentVariable("PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED", description = "Publish only if dependencies are changed")
class RebuildIfDependenciesAreChangedPlugin : BaseReflectiveProjectPlugin() {
companion object {
private val PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED: Boolean by lazy {
getenv("PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED")?.toBoolean() == true
|| System.getProperty("PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED")?.toBoolean() == true
}
private const val flagFilesName = "dependencies-changed"
}
@PluginAction
fun TaskContainer.`Create 'createDependenciesHashTag' task`() {
create("createDependenciesHashTag", CreateDependenciesHashTag::class.java) { task ->
task.failIfTagExists = false
task.failIfTagExistsOnCurrentCommit = false
task.project.rootProject.allprojects { project ->
project.tasks.all(CreateProjectVersionTag::class.java) { dependentTask ->
dependentTask.dependsOn(task)
}
}
task.mustRunAfter {
task.project.rootProject.allprojects.asSequence()
.map(Project::getTasks)
.flatMap {
sequenceOf(ASSEMBLE_TASK_NAME, TEST_TASK_NAME, CHECK_TASK_NAME, BUILD_TASK_NAME)
.mapNotNull(it::findByName)
}
.toList()
}
fun forEachDependentTask(action: (dependentTask: Task) -> Unit) {
arrayOf>(
CreateProjectVersionTag::class.java,
BaseCreateTagTask::class.java,
AbstractPublishToMaven::class.java
).forEach { dependentTaskClass ->
val processedTasks = hashSetOf()
task.project.rootProject.allprojects { project ->
project.tasks.all(dependentTaskClass) { dependentTask ->
if (dependentTask !is CreateDependenciesHashTag) {
if (processedTasks.add(dependentTask)) {
action(dependentTask)
}
}
}
}
}
}
forEachDependentTask { dependentTask ->
dependentTask.mustRunAfter(task)
}
task.doFirst {
task.project.tagCreatedFile.also { tagCreatedFile ->
task.logDebug("Removing tagCreatedFile: {}", tagCreatedFile)
tagCreatedFile.forceDelete()
}
task.project.tagNotCreatedFile.also { tagNotCreatedFile ->
task.logDebug("Removing tagNotCreatedFile: {}", tagNotCreatedFile)
tagNotCreatedFile.forceDelete()
}
}
task.onTagCreated {
task.project.tagCreatedFile.also { tagCreatedFile ->
task.logDebug("Creating tagCreatedFile: {}", tagCreatedFile)
tagCreatedFile.createParentDirectories().writeText("true")
}
}
if (PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED) {
task.onTagNotCreated {
task.project.tagNotCreatedFile.also { tagNotCreatedFile ->
task.logDebug("Creating tagNotCreatedFile: {}", tagNotCreatedFile)
tagNotCreatedFile.createParentDirectories().writeText("true")
}
forEachDependentTask { dependentTask ->
task.logWarn("Disabling {}", dependentTask)
dependentTask.enabled = false
}
}
}
}
}
@PluginActionsGroup(order = Int.MAX_VALUE)
inner class `If PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED environment variable equals to true` {
@PluginCondition(isHidden = true)
private fun condition(): Boolean {
return PUBLISH_ONLY_IF_DEPENDENCIES_ARE_CHANGED
}
@PluginAction
fun Project.`Disable publish tasks if project version tag hasn't been created`(extensions: ExtensionContainer) {
val autoVcsVersion = extensions[AutoVcsVersionExtension::class.java]
val vcsOperations = extensions[VcsOperationsExtension::class.java]
rootProject.allprojects { project ->
project.tasks.all(AbstractPublishToMaven::class.java) { publishTask ->
publishTask.onlyIf {
val prefixes: List = autoVcsVersion.versionTagPrefixes.let {
if (it.isEmpty()) {
listOf("")
} else {
it.sortedDescending()
}
}
val tagNames = vcsOperations.getAllTagNames()
return@onlyIf prefixes.any { prefix ->
"$prefix${publishTask.project.version}" in tagNames
}
}
}
}
}
@PluginAction(order = Int.MAX_VALUE)
fun ExtensionContainer.`Increment project version by 1`(project: Project) {
project.tagCreatedFile.let { tagCreatedFile ->
if (!tagCreatedFile.isFile) {
logger.debug("tagCreatedFile doesn't exist: {}", tagCreatedFile)
logger.lifecycle("Incrementing VCS version...")
this[AutoVcsVersionExtension::class.java].incrementVersionBy++
} else {
logger.debug("tagCreatedFile exists: {}", tagCreatedFile)
}
Unit
}
}
}
private val Project.tagCreatedFile: File get() = buildDir.resolve("$flagFilesName.tag-created")
private val Project.tagNotCreatedFile: File get() = buildDir.resolve("$flagFilesName.tag-not-created")
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy