aboutsummaryrefslogtreecommitdiff
path: root/buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt
diff options
context:
space:
mode:
Diffstat (limited to 'buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt')
-rw-r--r--buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt105
1 files changed, 105 insertions, 0 deletions
diff --git a/buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt b/buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt
new file mode 100644
index 0000000..20e8eef
--- /dev/null
+++ b/buildSrc/src/main/kotlin/kau/ChangelogGenerator.kt
@@ -0,0 +1,105 @@
+package kau
+
+import groovy.util.Node
+import groovy.util.XmlParser
+import org.gradle.api.GradleException
+import java.io.File
+
+/**
+ * Given an xml of the format
+ *
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <resources>
+ * <version title="v0.1" />
+ * <item text="Initial Changelog" />
+ * <item text="Bullet point here" />
+ * <item text="More points" />
+ * <item text="" /> <!-- this one is empty and therefore ignored -->
+ * </resources>
+ *
+ * Outputs a changelog in markdown format
+ */
+object ChangelogGenerator {
+
+ class ChangelogException(message: String) : GradleException(message)
+
+ private fun fail(message: String): Nothing =
+ throw ChangelogException(message)
+
+ class ChangelogEntry(val version: String, val items: Array<String>)
+
+ private fun Node.forEachNode(action: (Node) -> Unit) {
+ children().forEach {
+ action(it as Node)
+ }
+ }
+
+ @JvmStatic
+ fun read(inputUri: String): List<ChangelogEntry> {
+ val input = File(inputUri)
+ if (!input.exists()) {
+ fail("Could not generate changelog from ${input.absolutePath}")
+ }
+
+ val parser = XmlParser().parse(inputUri)
+
+ val entries: MutableList<ChangelogEntry> = mutableListOf()
+ var version: String? = null
+ val items: MutableList<String> = mutableListOf()
+
+ fun addEntry() {
+ version?.also { v ->
+ entries.add(ChangelogEntry(v, items.toTypedArray()))
+ items.clear()
+ }
+ }
+
+ parser.depthFirst().mapNotNull { it as? Node }.forEach { n ->
+ when (n.name()) {
+ "version" -> {
+ addEntry()
+ version = n.attribute("title")?.toString() ?: ""
+ }
+ "item" -> {
+ n.attribute("text")?.toString()?.takeIf(String::isNotBlank)?.let {
+ items.add(it)
+ }
+ }
+ }
+ }
+ addEntry()
+ return entries
+ }
+
+ @JvmStatic
+ fun generate(inputUri: String, outputUri: String): List<ChangelogEntry> {
+ val entries = read(inputUri)
+ val output = File(outputUri)
+ if (output.exists()) {
+ if (output.isDirectory) {
+ fail("Cannot save changelog at directory ${output.absolutePath}")
+ }
+ if (output.isFile && !output.delete()) {
+ fail("Could not delete changelog at ${output.absolutePath}")
+ }
+ } else {
+ output.parentFile.mkdirs()
+ }
+
+ if (!output.createNewFile()) {
+ fail("Could not create changelog file at ${output.absolutePath}")
+ }
+ val markdown = buildString {
+ append("# Changelog\n")
+ entries.forEach { e ->
+ append("\n## ${e.version}\n")
+ e.items.forEach {
+ append("* $it\n")
+ }
+ }
+ }
+ output.writeText(markdown)
+ println("Generated changelog at ${output.absolutePath}")
+ return entries
+ }
+} \ No newline at end of file