gradle-tools/src/main/kotlin/ru/mipt/npm/gradle/KScienceProjectPlugin.kt

223 lines
7.5 KiB
Kotlin
Raw Normal View History

2020-09-22 16:21:09 +03:00
package ru.mipt.npm.gradle
import groovy.text.SimpleTemplateEngine
2020-09-30 20:43:02 +03:00
import kotlinx.validation.BinaryCompatibilityValidatorPlugin
2020-09-22 16:21:09 +03:00
import org.gradle.api.Plugin
import org.gradle.api.Project
2020-09-27 17:45:40 +03:00
import org.gradle.kotlin.dsl.*
2020-09-22 16:21:09 +03:00
import org.jetbrains.changelog.ChangelogPlugin
2020-09-27 17:45:40 +03:00
import org.jetbrains.dokka.gradle.DokkaPlugin
import org.jetbrains.dokka.gradle.DokkaTask
2020-09-25 09:55:01 +03:00
import java.io.File
2020-09-22 16:21:09 +03:00
import kotlin.collections.component1
import kotlin.collections.component2
class KSciencePublishingExtension(val project: Project) {
var githubOrg: String? by project.extra
var githubProject: String? by project.extra
var spaceRepo: String? by project.extra
var spaceUser: String? by project.extra
var spaceToken: String? by project.extra
var bintrayOrg: String? by project.extra
var bintrayUser: String? by project.extra
var bintrayApiKey: String? by project.extra
var bintrayRepo: String? by project.extra
}
2020-09-25 09:55:01 +03:00
enum class Maturity {
PROTOTYPE,
EXPERIMENTAL,
DEVELOPMENT,
PRODUCTION
}
2020-09-22 16:21:09 +03:00
class KScienceReadmeExtension(val project: Project) {
2020-09-25 09:55:01 +03:00
var description: String = ""
var maturity: Maturity = Maturity.EXPERIMENTAL
2020-09-27 17:45:40 +03:00
var readmeTemplate: File = project.file("docs/README-TEMPLATE.md")
2020-09-22 16:21:09 +03:00
data class Feature(val id: String, val ref: String, val description: String, val name: String = id)
2020-09-25 09:55:01 +03:00
val features = ArrayList<Feature>()
2020-09-22 16:21:09 +03:00
fun feature(id: String, ref: String, description: String, name: String = id) {
features.add(Feature(id, ref, description, name))
}
2020-09-27 17:45:40 +03:00
val properties: MutableMap<String, () -> Any?> = mutableMapOf(
"name" to { project.name },
"group" to { project.group },
"version" to { project.version },
"features" to { featuresString() }
2020-09-25 09:55:01 +03:00
)
2020-09-27 17:45:40 +03:00
private fun getActualizedProperties() = properties.mapValues { (_, value) ->
value.invoke()
2020-09-25 09:55:01 +03:00
}
fun property(key: String, value: Any?) {
2020-09-27 17:45:40 +03:00
properties[key] = {value}
2020-09-25 09:55:01 +03:00
}
2020-09-27 17:45:40 +03:00
fun propertyByTemplate(key: String, template: String) {
val actual = getActualizedProperties()
properties[key] = {SimpleTemplateEngine().createTemplate(template).make(actual).toString()}
2020-09-25 09:55:01 +03:00
}
2020-09-27 17:45:40 +03:00
internal val additionalFiles = ArrayList<File>()
fun propertyByTemplate(key: String, template: File) {
val actual = getActualizedProperties()
properties[key] = {SimpleTemplateEngine().createTemplate(template).make(actual).toString()}
additionalFiles.add(template)
2020-09-25 09:55:01 +03:00
}
2020-09-22 16:21:09 +03:00
/**
* Generate a markdown string listing features
*/
fun featuresString(itemPrefix: String = " - ", pathPrefix: String = "") = buildString {
features.forEach {
appendln("$itemPrefix[${it.id}]($pathPrefix${it.ref}) : ${it.description}")
}
}
/**
* Generate a readme string from the stub
*/
fun readmeString(): String? {
2020-09-25 09:55:01 +03:00
return if (readmeTemplate.exists()) {
2020-09-27 17:45:40 +03:00
val actual = getActualizedProperties()
SimpleTemplateEngine().createTemplate(readmeTemplate).make(actual).toString()
2020-09-22 16:21:09 +03:00
} else {
null
}
}
}
/**
* Apply extension and repositories
*/
open class KScienceProjectPlugin : Plugin<Project> {
override fun apply(target: Project): Unit = target.run {
apply<ChangelogPlugin>()
2020-09-27 17:45:40 +03:00
apply<DokkaPlugin>()
2020-09-30 20:43:02 +03:00
apply<BinaryCompatibilityValidatorPlugin>()
2020-09-22 16:21:09 +03:00
val rootReadmeExtension = KScienceReadmeExtension(this)
extensions.add("ksciencePublish", KSciencePublishingExtension(this))
2020-09-25 09:55:01 +03:00
extensions.add("readme", rootReadmeExtension)
2020-09-22 16:21:09 +03:00
//Add readme generators to individual subprojects
subprojects {
val readmeExtension = KScienceReadmeExtension(this)
2020-09-25 09:55:01 +03:00
extensions.add("readme", readmeExtension)
2020-09-27 17:45:40 +03:00
val generateReadme by tasks.creating {
2020-09-22 16:21:09 +03:00
group = "documentation"
description = "Generate a README file if stub is present"
2020-09-27 17:45:40 +03:00
if(readmeExtension.readmeTemplate.exists()) {
inputs.file(readmeExtension.readmeTemplate)
}
readmeExtension.additionalFiles.forEach {
if(it.exists()){
inputs.file(it)
}
}
val readmeFile = this@subprojects.file("README.md")
outputs.file(readmeFile)
2020-09-22 16:21:09 +03:00
doLast {
val readmeString = readmeExtension.readmeString()
if (readmeString != null) {
readmeFile.writeText(readmeString)
}
}
}
2020-09-27 17:45:40 +03:00
tasks.withType<DokkaTask>{
dependsOn(generateReadme)
}
2020-09-22 16:21:09 +03:00
}
2020-09-27 17:45:40 +03:00
val generateReadme by tasks.creating {
2020-09-22 16:21:09 +03:00
group = "documentation"
description = "Generate a README file and a feature matrix if stub is present"
2020-09-27 17:45:40 +03:00
subprojects {
tasks.findByName("generateReadme")?.let {
dependsOn(it)
}
}
if(rootReadmeExtension.readmeTemplate.exists()) {
inputs.file(rootReadmeExtension.readmeTemplate)
}
rootReadmeExtension.additionalFiles.forEach {
if(it.exists()){
inputs.file(it)
}
}
val readmeFile = project.file("README.md")
outputs.file(readmeFile)
2020-09-22 16:21:09 +03:00
doLast {
val projects = subprojects.associate {
it.name to it.extensions.findByType<KScienceReadmeExtension>()
}
2020-09-25 09:55:01 +03:00
if (rootReadmeExtension.readmeTemplate.exists()) {
2020-09-22 16:21:09 +03:00
val modulesString = buildString {
2020-09-25 09:55:01 +03:00
projects.entries.forEach { (name, ext) ->
2020-09-27 17:45:40 +03:00
appendln("<hr/>")
appendln("\n* ### [$name]($name)")
2020-09-25 09:55:01 +03:00
if (ext != null) {
2020-09-27 17:45:40 +03:00
appendln("> ${ext.description}")
appendln(">\n> **Maturity**: ${ext.maturity}")
val featureString = ext.featuresString(itemPrefix = "> - ", pathPrefix = "$name/")
if(featureString.isNotBlank()) {
appendln(">\n> **Features:**")
appendln(featureString)
}
2020-09-25 09:55:01 +03:00
}
2020-09-22 16:21:09 +03:00
}
2020-09-27 17:45:40 +03:00
appendln("<hr/>")
2020-09-22 16:21:09 +03:00
}
2020-09-25 09:55:01 +03:00
val rootReadmeProperties: Map<String, Any?> = mapOf(
2020-09-22 16:21:09 +03:00
"name" to project.name,
"group" to project.group,
"version" to project.version,
2020-09-25 09:55:01 +03:00
"modules" to modulesString
2020-09-22 16:21:09 +03:00
)
readmeFile.writeText(
2020-09-27 17:45:40 +03:00
SimpleTemplateEngine().createTemplate(rootReadmeExtension.readmeTemplate)
.make(rootReadmeProperties).toString()
2020-09-22 16:21:09 +03:00
)
}
}
}
2020-09-27 17:45:40 +03:00
tasks.withType<DokkaTask>{
dependsOn(generateReadme)
}
val patchChangelog by tasks.getting
val release by tasks.creating{
group = RELEASE_GROUP
description = "Publish development or production release based on version suffix"
dependsOn(generateReadme, patchChangelog)
tasks.findByName("publishAllPublicationsToBintrayRepository")?.let {
dependsOn(it)
}
}
}
companion object{
const val RELEASE_GROUP = "release"
2020-09-22 16:21:09 +03:00
}
}