pcimcioch.gitlabci.dsl.GitlabCiDsl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gitlab-ci-kotlin-dsl Show documentation
Show all versions of gitlab-ci-kotlin-dsl Show documentation
Library providing Kotlin DSL to configure GitlabCI file
package pcimcioch.gitlabci.dsl
import com.charleskorn.kaml.Yaml
import com.charleskorn.kaml.YamlConfiguration
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
import pcimcioch.gitlabci.dsl.default.DefaultDsl
import pcimcioch.gitlabci.dsl.include.IncludeDsl
import pcimcioch.gitlabci.dsl.job.JobDsl
import pcimcioch.gitlabci.dsl.serializer.ValueSerializer
import pcimcioch.gitlabci.dsl.stage.StagesDsl
import pcimcioch.gitlabci.dsl.workflow.WorkflowDsl
import java.io.FileWriter
import java.io.Writer
import kotlin.collections.set
@Serializable(with = GitlabCiDsl.GitlabCiDslSerializer::class)
class GitlabCiDsl : DslBase() {
private val jobs: MutableList = mutableListOf()
private var stages: StagesDsl? = null
private var default: DefaultDsl? = null
private var workflow: WorkflowDsl? = null
private var include: IncludeDsl? = null
fun job(name: String, block: JobDsl.() -> Unit) = addAndReturn(jobs, JobDsl(name)).apply(block)
operator fun JobDsl.unaryPlus() = [email protected](this)
fun stages(block: StagesDsl.() -> Unit) = ensureStages().apply(block)
fun stages(vararg elements: String) = stages(elements.toList())
fun stages(elements: Iterable) = ensureStages().apply { elements.forEach { stage(it) } }
fun default(block: DefaultDsl.() -> Unit) = ensureDefault().apply(block)
fun workflow(block: WorkflowDsl.() -> Unit) = ensureWorkflow().apply(block)
fun include(block: IncludeDsl.() -> Unit) = ensureInclude().apply(block)
fun include(vararg elements: String) = include(elements.toList())
fun include(elements: Iterable) = ensureInclude().apply { elements.forEach { local(it) } }
fun pages(block: JobDsl.() -> Unit) = job("pages") {
artifacts("public")
only("master")
}.apply(block)
override fun validate(errors: MutableList) {
addErrors(errors, "", workflow, stages, default, include)
addErrors(errors, "", jobs)
}
private fun ensureStages() = stages ?: StagesDsl().also { stages = it }
private fun ensureDefault() = default ?: DefaultDsl().also { default = it }
private fun ensureWorkflow() = workflow ?: WorkflowDsl().also { workflow = it }
private fun ensureInclude() = include ?: IncludeDsl().also { include = it }
private fun asMap(): Map {
val map = mutableMapOf()
workflow?.also { map["workflow"] = it }
include?.also { map["include"] = it }
stages?.also { map["stages"] = it }
default?.also { map["default"] = it }
jobs.forEach { map[it.name] = it }
return map
}
object GitlabCiDslSerializer : ValueSerializer>(MapSerializer(String.serializer(), DslBase.serializer()), GitlabCiDsl::asMap)
companion object {
init {
addSerializer(GitlabCiDsl::class, serializer())
}
}
}
fun gitlabCi(validate: Boolean = true, writer: Writer? = null, block: GitlabCiDsl.() -> Unit) {
val dsl = GitlabCiDsl().apply(block)
if (validate) {
val errors = mutableListOf()
dsl.validate(errors)
if (errors.isNotEmpty()) {
throw IllegalArgumentException(errors.joinToString(
"\n",
"Configuration validation failed\n",
"\nValidation can be disabled by calling 'gitlabCi(validate = false) {}'"))
}
}
if (writer != null) {
serializeToYaml(GitlabCiDsl.serializer(), dsl, writer)
} else {
FileWriter(".gitlab-ci.yml").use {
serializeToYaml(GitlabCiDsl.serializer(), dsl, it)
}
}
}
internal fun serializeToYaml(strategy: SerializationStrategy, value: T, writer: Writer) {
val config = YamlConfiguration(encodeDefaults = false)
val yaml = Yaml(configuration = config)
val yamlString = yaml.stringify(strategy, value)
writer.write(yamlString)
}