blob: 4be3ecfba6de4d97c5ac2bbd783a869f9459e6d2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
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
}
}
|