]> git.frustrated-labs.net Git - gradle-changelog-plugin.git/commitdiff
feat: add git service to generate new changelog entry from current branch changes
authorAlexander Goussas <[email protected]>
Fri, 24 Oct 2025 16:31:18 +0000 (11:31 -0500)
committerAlexander Goussas <[email protected]>
Fri, 24 Oct 2025 16:47:10 +0000 (11:47 -0500)
17 files changed:
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogEntry.kt
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogTask.kt
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/AbstractGitCommand.kt [deleted file]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Branch.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommand.kt [deleted file]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommitsCommand.kt [deleted file]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentReleaseCommand.kt [deleted file]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitCommand.kt [deleted file]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitService.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/RawCommit.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Tag.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/AbstractGitCommand.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommand.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommitsCommand.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentReleaseCommand.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GitCommand.kt [new file with mode: 0644]
changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/parser/MarkdownChangelogParser.kt

index d8a06f71084825ab07bb2899ebfd432a1e2512f2..b08b64bafbc796b07d7b47dc5c56efafc95d103e 100644 (file)
@@ -7,6 +7,11 @@ data class ChangelogEntry(
     val commits: List<Commit> = emptyList(),
 ) : Comparable<ChangelogEntry> {
     override fun compareTo(other: ChangelogEntry): Int {
+
+        // Unreleased always goes at the top.
+        if (release == "Unreleased") return -1
+        if (other.release == "Unreleased") return 1
+
         val myRelease = release.split(".").map { it.toInt() }
         val otherRelease = other.release.split(".").map { it.toInt() }
         return Comparator
index 749dc2447cf3328a39cd267931d800ecb13ea547..7b1e4afff1ef142987867f8f90d0c8b0f73d29f2 100644 (file)
@@ -2,7 +2,10 @@ package io.github.aloussase.changelog
 
 import io.github.aloussase.changelog.config.Config
 import io.github.aloussase.changelog.formatter.ChangelogFormatterFactory
-import io.github.aloussase.changelog.git.GetCurrentBranchCommand
+import io.github.aloussase.changelog.git.GitService
+import io.github.aloussase.changelog.git.commands.GetCurrentBranchCommand
+import io.github.aloussase.changelog.git.commands.GetCurrentBranchCommitsCommand
+import io.github.aloussase.changelog.git.commands.GetCurrentReleaseCommand
 import io.github.aloussase.changelog.parser.ChangelogParserFactory
 import org.gradle.api.DefaultTask
 import org.gradle.api.tasks.Input
@@ -14,6 +17,12 @@ abstract class ChangelogTask : DefaultTask() {
     @Input
     lateinit var config: Config
 
+    private val gitService = GitService(
+        GetCurrentBranchCommand(),
+        GetCurrentBranchCommitsCommand(),
+        GetCurrentReleaseCommand(),
+    )
+
     @TaskAction
     fun run() {
         val parser = ChangelogParserFactory.createParser(config.documentFormat)
@@ -24,11 +33,34 @@ abstract class ChangelogTask : DefaultTask() {
         val document = changelogFile.readText()
         val changelog = parser.parse(document).getOrThrow()
 
-        // TODO: Add commits from current branch here.
-        println(GetCurrentBranchCommand().execute())
+        val changes = gitService.getCurrrentBranchChanges()
+        val releaseExists = changelog.entries.any { it.release == changes.release }
+
+        val newChangelog =
+            if (releaseExists) {
+                Changelog(
+                    changelog
+                        .entries
+                        .map {
+                            if (it.release == changes.release) {
+                                ChangelogEntry(
+                                    changes.release,
+                                    it.commits.toSet()
+                                        .union(changes.commits.toSet())
+                                        .toList()
+                                )
+                            } else {
+                                it
+                            }
+                        }
+                )
+            } else {
+                Changelog(listOf(changes) + changelog.entries)
+            }
 
         val formatter = ChangelogFormatterFactory.create(config.documentFormat)
-        changelogFile.writeText(formatter.format(changelog))
+
+        changelogFile.writeText(formatter.format(newChangelog))
     }
 
 }
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/AbstractGitCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/AbstractGitCommand.kt
deleted file mode 100644 (file)
index 1a4a9ed..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package io.github.aloussase.changelog.git
-
-abstract class AbstractGitCommand<T> : GitCommand<T> {
-
-    abstract fun transform(rawOutput: String): T
-
-    override fun execute(): T {
-        val runtime = Runtime.getRuntime()
-        val ary = arrayOf("/bin/sh", "-c", commandLine)
-        val process = runtime.exec(ary)
-        process.waitFor()
-        return process.inputReader().use { br ->
-            transform(br.readText().trim())
-        }
-    }
-
-}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Branch.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Branch.kt
new file mode 100644 (file)
index 0000000..842214e
--- /dev/null
@@ -0,0 +1,5 @@
+package io.github.aloussase.changelog.git
+
+data class Branch(
+    val name: String,
+)
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommand.kt
deleted file mode 100644 (file)
index 0853e6e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.aloussase.changelog.git
-
-class GetCurrentBranchCommand : AbstractGitCommand<String>() {
-    override fun transform(rawOutput: String): String = rawOutput
-
-    override val commandLine: String
-        get() = "git branch --show-current"
-}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommitsCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommitsCommand.kt
deleted file mode 100644 (file)
index aaff859..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package io.github.aloussase.changelog.git
-
-class GetCurrentBranchCommitsCommand : AbstractGitCommand<List<Pair<String, String>>>() {
-    override val commandLine: String
-        get() = "git log main..HEAD --no-merges --oneline --pretty=format:\"%an|%s\""
-
-    override fun transform(rawOutput: String): List<Pair<String, String>> =
-        rawOutput
-            .split("\n")
-            .map { it.split("|") }
-            .map { Pair(it[0], it[1]) }
-}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentReleaseCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentReleaseCommand.kt
deleted file mode 100644 (file)
index e9a52c3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.aloussase.changelog.git
-
-class GetCurrentReleaseCommand : AbstractGitCommand<String>() {
-    override val commandLine: String
-        get() = "git tag | tail -n1"
-
-    override fun transform(rawOutput: String): String = rawOutput
-}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitCommand.kt
deleted file mode 100644 (file)
index 1603d5f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.aloussase.changelog.git
-
-interface GitCommand<T> {
-
-    val commandLine: String
-
-    fun execute(): T
-
-}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitService.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitService.kt
new file mode 100644 (file)
index 0000000..47b3d38
--- /dev/null
@@ -0,0 +1,28 @@
+package io.github.aloussase.changelog.git
+
+import io.github.aloussase.changelog.ChangelogEntry
+import io.github.aloussase.changelog.git.commands.GitCommand
+
+class GitService(
+    val currentBranchCommand: GitCommand<Branch>,
+    val currentBranchCommitsCommand: GitCommand<List<RawCommit>>,
+    val currentReleaseCommand: GitCommand<Tag>
+) {
+
+    fun getCurrrentBranchChanges(): ChangelogEntry {
+        val currentBranch = currentBranchCommand.execute()
+        val commits = currentBranchCommitsCommand.execute()
+        val release = Tag("Unreleased")
+        return ChangelogEntry(
+            release.name,
+            commits.map {
+                Commit(
+                    it.author,
+                    currentBranch.name,
+                    it.message
+                )
+            }
+        )
+    }
+
+}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/RawCommit.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/RawCommit.kt
new file mode 100644 (file)
index 0000000..3a76e0a
--- /dev/null
@@ -0,0 +1,6 @@
+package io.github.aloussase.changelog.git
+
+data class RawCommit(
+    val author: String,
+    val message: String,
+)
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Tag.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Tag.kt
new file mode 100644 (file)
index 0000000..4f15691
--- /dev/null
@@ -0,0 +1,5 @@
+package io.github.aloussase.changelog.git
+
+data class Tag(
+    val name: String,
+)
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/AbstractGitCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/AbstractGitCommand.kt
new file mode 100644 (file)
index 0000000..ca5dda9
--- /dev/null
@@ -0,0 +1,17 @@
+package io.github.aloussase.changelog.git.commands
+
+abstract class AbstractGitCommand<T> : GitCommand<T> {
+
+    abstract fun transform(rawOutput: String): T
+
+    override fun execute(): T {
+        val runtime = Runtime.getRuntime()
+        val ary = arrayOf("/bin/sh", "-c", commandLine)
+        val process = runtime.exec(ary)
+        process.waitFor()
+        return process.inputReader().use { br ->
+            transform(br.readText().trim())
+        }
+    }
+
+}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommand.kt
new file mode 100644 (file)
index 0000000..4712e63
--- /dev/null
@@ -0,0 +1,10 @@
+package io.github.aloussase.changelog.git.commands
+
+import io.github.aloussase.changelog.git.Branch
+
+class GetCurrentBranchCommand : AbstractGitCommand<Branch>() {
+    override fun transform(rawOutput: String): Branch = Branch(rawOutput)
+
+    override val commandLine: String
+        get() = "git branch --show-current"
+}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommitsCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommitsCommand.kt
new file mode 100644 (file)
index 0000000..e2d440a
--- /dev/null
@@ -0,0 +1,14 @@
+package io.github.aloussase.changelog.git.commands
+
+import io.github.aloussase.changelog.git.RawCommit
+
+class GetCurrentBranchCommitsCommand : AbstractGitCommand<List<RawCommit>>() {
+    override val commandLine: String
+        get() = "git log main..HEAD --no-merges --oneline --pretty=format:\"%an|%s\""
+
+    override fun transform(rawOutput: String): List<RawCommit> =
+        rawOutput
+            .split("\n")
+            .map { it.split("|") }
+            .map { RawCommit(it[0], it[1]) }
+}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentReleaseCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentReleaseCommand.kt
new file mode 100644 (file)
index 0000000..4e21b3d
--- /dev/null
@@ -0,0 +1,10 @@
+package io.github.aloussase.changelog.git.commands
+
+import io.github.aloussase.changelog.git.Tag
+
+class GetCurrentReleaseCommand : AbstractGitCommand<Tag>() {
+    override val commandLine: String
+        get() = "git tag | tail -n1"
+
+    override fun transform(rawOutput: String): Tag = Tag(rawOutput)
+}
diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GitCommand.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GitCommand.kt
new file mode 100644 (file)
index 0000000..40d5b4c
--- /dev/null
@@ -0,0 +1,9 @@
+package io.github.aloussase.changelog.git.commands
+
+interface GitCommand<T> {
+
+    val commandLine: String
+
+    fun execute(): T
+
+}
index e15e413a26bdf16522469da01e8d777d032b3c82..8fcad69c3193a84261583918a170c1bd243e3258 100644 (file)
@@ -11,8 +11,8 @@ import org.gradle.api.GradleException
 class MarkdownChangelogParser : ChangelogParser {
 
     companion object {
-        private val RELEASE_VERSION_REGEX = Regex("## \\[(\\d+\\.\\d+\\.\\d+)]")
-        private val COMMIT_REGEX = Regex("- ([\\w-]+): ([\\w ]+) \\(([\\w.]+@[\\w.]+)\\)")
+        private val RELEASE_VERSION_REGEX = Regex("## (\\[(\\d+\\.\\d+\\.\\d+|Unreleased)])")
+        private val COMMIT_REGEX = Regex("- ([\\w-]+): ([\\w :]+) \\(([\\w.]+@[\\w.]+|[\\w ]+)\\)")
         private val DOC_TITLE_REGEX = Regex("# (Changelog|CHANGELOG)")
     }
 
@@ -36,7 +36,7 @@ class MarkdownChangelogParser : ChangelogParser {
                 )
             }
 
-            val releaseVersion = releaseMatch.groupValues[1]
+            val releaseVersion = releaseMatch.groupValues[2]
             val commits = arrayListOf<Commit>()
 
             for (line in lines.subList(1, lines.size)) {