From: Alexander Goussas Date: Fri, 24 Oct 2025 16:31:18 +0000 (-0500) Subject: feat: add git service to generate new changelog entry from current branch changes X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=8f3ac4bcba2fa26d78d1688453f81c5d5bd82d98;p=gradle-changelog-plugin.git feat: add git service to generate new changelog entry from current branch changes --- diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogEntry.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogEntry.kt index d8a06f7..b08b64b 100644 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogEntry.kt +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogEntry.kt @@ -7,6 +7,11 @@ data class ChangelogEntry( val commits: List = emptyList(), ) : Comparable { 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 diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogTask.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogTask.kt index 749dc24..7b1e4af 100644 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogTask.kt +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/ChangelogTask.kt @@ -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 index 1a4a9ed..0000000 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/AbstractGitCommand.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.aloussase.changelog.git - -abstract class AbstractGitCommand : GitCommand { - - 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 index 0000000..842214e --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Branch.kt @@ -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 index 0853e6e..0000000 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommand.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.aloussase.changelog.git - -class GetCurrentBranchCommand : AbstractGitCommand() { - 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 index aaff859..0000000 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentBranchCommitsCommand.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.aloussase.changelog.git - -class GetCurrentBranchCommitsCommand : AbstractGitCommand>>() { - override val commandLine: String - get() = "git log main..HEAD --no-merges --oneline --pretty=format:\"%an|%s\"" - - override fun transform(rawOutput: String): List> = - 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 index e9a52c3..0000000 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GetCurrentReleaseCommand.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.aloussase.changelog.git - -class GetCurrentReleaseCommand : AbstractGitCommand() { - 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 index 1603d5f..0000000 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitCommand.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.aloussase.changelog.git - -interface GitCommand { - - 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 index 0000000..47b3d38 --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/GitService.kt @@ -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, + val currentBranchCommitsCommand: GitCommand>, + val currentReleaseCommand: GitCommand +) { + + 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 index 0000000..3a76e0a --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/RawCommit.kt @@ -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 index 0000000..4f15691 --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/Tag.kt @@ -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 index 0000000..ca5dda9 --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/AbstractGitCommand.kt @@ -0,0 +1,17 @@ +package io.github.aloussase.changelog.git.commands + +abstract class AbstractGitCommand : GitCommand { + + 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 index 0000000..4712e63 --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommand.kt @@ -0,0 +1,10 @@ +package io.github.aloussase.changelog.git.commands + +import io.github.aloussase.changelog.git.Branch + +class GetCurrentBranchCommand : AbstractGitCommand() { + 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 index 0000000..e2d440a --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentBranchCommitsCommand.kt @@ -0,0 +1,14 @@ +package io.github.aloussase.changelog.git.commands + +import io.github.aloussase.changelog.git.RawCommit + +class GetCurrentBranchCommitsCommand : AbstractGitCommand>() { + override val commandLine: String + get() = "git log main..HEAD --no-merges --oneline --pretty=format:\"%an|%s\"" + + override fun transform(rawOutput: String): List = + 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 index 0000000..4e21b3d --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GetCurrentReleaseCommand.kt @@ -0,0 +1,10 @@ +package io.github.aloussase.changelog.git.commands + +import io.github.aloussase.changelog.git.Tag + +class GetCurrentReleaseCommand : AbstractGitCommand() { + 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 index 0000000..40d5b4c --- /dev/null +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/git/commands/GitCommand.kt @@ -0,0 +1,9 @@ +package io.github.aloussase.changelog.git.commands + +interface GitCommand { + + val commandLine: String + + fun execute(): T + +} diff --git a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/parser/MarkdownChangelogParser.kt b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/parser/MarkdownChangelogParser.kt index e15e413..8fcad69 100644 --- a/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/parser/MarkdownChangelogParser.kt +++ b/changelog-plugin/src/main/kotlin/io/github/aloussase/changelog/parser/MarkdownChangelogParser.kt @@ -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() for (line in lines.subList(1, lines.size)) {