Skip to content

Commit

Permalink
Merge pull request #60 from ilovemilk/hotfix/59-conventional-commits-…
Browse files Browse the repository at this point in the history
…dirty-tree

fix dirty working tree detection and version formatting
  • Loading branch information
ilovemilk authored Nov 26, 2020
2 parents ea5998c + 9e55ad1 commit 65a8249
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.3.3]
### Fixed
- Fix dirty working tree in the conventional commits incrementer.

## [2.3.2]
### Fixed
- Fix conventional commits incrementer for BREAKING CHANGES marked by a ! after the scope.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Gradle 2.1 and higher

```
plugins {
id("io.wusa.semver-git-plugin").version("2.3.2")
id("io.wusa.semver-git-plugin").version("2.3.3")
}
```

Expand All @@ -25,7 +25,7 @@ buildscript {
}
}
dependencies {
classpath 'io.wusa:semver-git-plugin:2.3.0'
classpath 'io.wusa:semver-git-plugin:2.3.3'
}
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
}

group = "io.wusa"
version = "2.3.2"
version = "2.3.3"

dependencies {
implementation(kotlin("stdlib-jdk8"))
Expand Down
14 changes: 8 additions & 6 deletions src/main/kotlin/io/wusa/GitService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class GitService {

@Throws(NoLastTagFoundException::class)
fun lastTag(project : Project, tagPrefix : String = "", tagType : TagType = TagType.ANNOTATED): String {
var cmdArgs = arrayOf("describe", "--dirty", "--abbrev=7", "--match", "$tagPrefix*")
var cmdArgs = arrayOf("describe", "--abbrev=7", "--match", "$tagPrefix*")
if (tagType == TagType.LIGHTWEIGHT){
cmdArgs = arrayOf("describe", "--tags", "--dirty", "--abbrev=7", "--match", "$tagPrefix*")
cmdArgs = arrayOf("describe", "--tags", "--abbrev=7", "--match", "$tagPrefix*")
}
return try {
GitCommandRunner.execute(project.projectDir, cmdArgs)
Expand All @@ -69,9 +69,9 @@ class GitService {
}

fun getCommitsSinceLastTag(project: Project, tagPrefix : String = "", tagType : TagType = TagType.ANNOTATED): List<String> {
var cmdArgs = arrayOf("describe", "--dirty", "--abbrev=0", "--match", "$tagPrefix*")
var cmdArgs = arrayOf("describe", "--abbrev=0", "--match", "$tagPrefix*")
if (tagType == TagType.LIGHTWEIGHT) {
cmdArgs = arrayOf("describe", "--tags", "--dirty", "--abbrev=0", "--match", "$tagPrefix*")
cmdArgs = arrayOf("describe", "--tags", "--abbrev=0", "--match", "$tagPrefix*")
}
return try {
val lastTag = GitCommandRunner.execute(project.projectDir, cmdArgs)
Expand All @@ -81,8 +81,10 @@ class GitService {
}
}

private fun isGitDifferent(project: Project) =
GitCommandRunner.execute(project.projectDir, arrayOf("diff", "--stat")) != ""
private fun isGitDifferent(project: Project): Boolean {
print(GitCommandRunner.execute(project.projectDir, arrayOf("status", "-s")))
return GitCommandRunner.execute(project.projectDir, arrayOf("status", "-s")).isNotBlank()
}

private fun getCurrentCommit(project: Project): String {
return try {
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/io/wusa/VersionService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.wusa.extension.SemverGitPluginExtension
import io.wusa.incrementer.VersionIncrementer
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.internal.impldep.org.eclipse.jgit.api.Git

class VersionService(private var project: Project) {
private val semverGitPluginExtension: SemverGitPluginExtension = project.extensions.getByType(SemverGitPluginExtension::class.java)
Expand All @@ -19,6 +20,22 @@ class VersionService(private var project: Project) {
throw GradleException("The current tag is not a semantic version.")
} catch (ex: NoCurrentTagFoundException) {
handleNoCurrentTagFound(versionFactory, project)
} catch (ex: DirtyWorkingTreeException) {
handleDirtyWorkingTree(versionFactory, project)
}
}

@Throws(GradleException::class)
private fun handleDirtyWorkingTree(versionFactory: IVersionFactory, project: Project): Version {
return try {
val lastVersion = getLastVersion(versionFactory)
incrementVersion(lastVersion, project)
} catch (ex: NoValidSemverTagFoundException) {
throw GradleException(ex.localizedMessage)
} catch (ex: NoIncrementerFoundException) {
throw GradleException(ex.localizedMessage)
} catch (ex: NoLastTagFoundException) {
buildInitialVersion(versionFactory)
}
}

Expand Down Expand Up @@ -71,6 +88,10 @@ class VersionService(private var project: Project) {
if ( !curTag.startsWith(tagPrefix)) {
throw NoCurrentTagFoundException("$curTag doesn't match $tagPrefix")
}
val isDirty = GitService.isDirty(project)
if (isDirty) {
throw DirtyWorkingTreeException("The current working tree is dirty.")
}

return versionFactory.createFromString(curTag.substring(tagPrefix.length))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.wusa.exception

class DirtyWorkingTreeException: Exception {
constructor(message: String, ex: Throwable?): super(message, ex) {}
constructor(message: String): super(message) {}
constructor(ex: Throwable): super(ex) {}
}
28 changes: 15 additions & 13 deletions src/main/kotlin/io/wusa/formatter/SemanticVersionFormatter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.wusa.formatter

import io.wusa.Info
import io.wusa.RegexResolver
import io.wusa.Suffix
import io.wusa.extension.Branches
import io.wusa.extension.SemverGitPluginExtension
import org.gradle.api.Transformer
Expand All @@ -12,12 +11,12 @@ class SemanticVersionFormatter {
fun format(info: Info, branches: Branches, snapshotSuffix: String, dirtyMarker: String): String {
if (!hasFirstCommit(info)) return appendSuffix(buildVersionString(info), snapshotSuffix)

if (hasTag(info)) {
if (hasTag(info) && !isDirty(info)) {
return formatVersionWithTag(info)
}

val formattedVersion = formatVersionWithoutTag(branches, info, dirtyMarker)
if (!hasTag(info)) {
val formattedVersion = formatVersion(branches, info, dirtyMarker)
if (!hasTag(info) || hasTag(info) && isDirty(info)) {
return appendSuffix(formattedVersion, snapshotSuffix)
}
return formattedVersion
Expand Down Expand Up @@ -48,19 +47,25 @@ class SemanticVersionFormatter {

private fun buildVersionString(info: Info) = "${info.version.major}.${info.version.minor}.${info.version.patch}"

private fun formatVersionWithoutTag(branches: Branches, info: Info, dirtyMarker: String): String {
private fun formatVersion(branches: Branches, info: Info, dirtyMarker: String): String {
val regexFormatterPair = RegexResolver.findMatchingRegex(branches, info.branch.name)
var formattedVersion = transform(SemverGitPluginExtension.DEFAULT_FORMATTER, info)
formattedVersion = appendDirtyMarker(formattedVersion, info.version.suffix, dirtyMarker)
if (isDirty(info)) {
formattedVersion = appendDirtyMarker(formattedVersion, dirtyMarker)
}
regexFormatterPair?.let {
formattedVersion = transform(regexFormatterPair.formatter, info)
formattedVersion = appendDirtyMarker(formattedVersion, info.version.suffix, dirtyMarker)
if (isDirty(info)) {
formattedVersion = appendDirtyMarker(formattedVersion, dirtyMarker)
}
}
return formattedVersion
}

private fun hasTag(info: Info) = info.version.suffix == null

private fun isDirty(info: Info) = info.dirty

private fun hasVersionBuildInformation(info: Info) = info.version.build != ""

private fun hasVersionPrerelease(info: Info) = info.version.prerelease != ""
Expand All @@ -79,12 +84,9 @@ class SemanticVersionFormatter {
return true
}

private fun appendDirtyMarker(version: String, suffix: Suffix?, dirtyMarker: String): String {
if (suffix != null && suffix.dirty) {
if (dirtyMarker != "") {
return "$version-$dirtyMarker"
}
return version
private fun appendDirtyMarker(version: String, dirtyMarker: String): String {
if (dirtyMarker != "") {
return "$version-$dirtyMarker"
}
return version
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ConventionalCommitsIncrementer: IIncrementer {
val fix = "^fix$optionalScope"
val breakingChange = "\\bBREAKING CHANGE\\b:"

if (semverGitPluginExtension.info.dirty) patch = 1

listOfCommits.forEach {
when {
it.contains("$feat!:".toRegex()) -> major += 1
Expand Down
12 changes: 12 additions & 0 deletions src/test/kotlin/io/wusa/FunctionalBaseTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,41 @@ import java.io.File
abstract class FunctionalBaseTest {

fun initializeGitWithBranch(directory: File, tag: String = "0.1.0", branch: String = "develop"): Git {
val gitIgnore = File(directory, ".gitignore")
gitIgnore.writeText(".gradle")
val git = Git.init().setDirectory(directory).call()
git.add().addFilepattern(".").call()
val commit = git.commit().setMessage("").call()
git.checkout().setCreateBranch(true).setName(branch).call()
git.tag().setName(tag).setObjectId(commit).call()
return git
}

fun initializeGitWithoutBranchAnnotated(directory: File, tag: String = "0.1.0"): Git {
val gitIgnore = File(directory, ".gitignore")
gitIgnore.writeText(".gradle")
val git = Git.init().setDirectory(directory).call()
git.add().addFilepattern(".").call()
val commit = git.commit().setMessage("").call()
git.tag().setName(tag).setMessage(tag).setAnnotated(true).setObjectId(commit).call()
return git
}

fun initializeGitWithoutBranchLightweight(directory: File, tag: String = "0.1.0"): Git {
val gitIgnore = File(directory, ".gitignore")
gitIgnore.writeText(".gradle")
val git = Git.init().setDirectory(directory).call()
git.add().addFilepattern(".").call()
val commit = git.commit().setMessage("").call()
git.tag().setName(tag).setObjectId(commit).setAnnotated(false).call()
return git
}

fun initializeGitWithoutBranchAndWithoutTag(directory: File): Git {
val gitIgnore = File(directory, ".gitignore")
gitIgnore.writeText(".gradle")
val git = Git.init().setDirectory(directory).call()
git.add().addFilepattern(".").call()
git.commit().setMessage("").call()
return git
}
Expand Down
80 changes: 80 additions & 0 deletions src/test/kotlin/io/wusa/SemverGitPluginKotlinFunctionalTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -649,4 +649,84 @@ class SemverGitPluginKotlinFunctionalTest : FunctionalBaseTest() {
println(result.output)
Assertions.assertTrue(result.output.contains("Version: 2.1.0-SNAPSHOT"))
}

@Test
fun `issue-59 increment minor by one with a dirty working tree`() {
val testProjectDirectory = createTempDir()
val buildFile = File(testProjectDirectory, "build.gradle.kts")
buildFile.writeText("""
import io.wusa.Info
import io.wusa.TagType
plugins {
id("io.wusa.semver-git-plugin")
}
semver {
tagPrefix = ""
tagType = TagType.ANNOTATED
branches {
branch {
regex = ".+"
incrementer = "CONVENTIONAL_COMMITS_INCREMENTER"
formatter = Transformer<Any, Info>{ info:Info -> "${'$'}{info.version.major}.${'$'}{info.version.minor}.${'$'}{info.version.patch}" }
}
}
}
""")
val git = initializeGitWithoutBranchAnnotated(testProjectDirectory, "2.0.42")
git.commit().setMessage("feat: another commit").call()
git.commit().setMessage("feat: added semver plugin incrementer parameter").call()
git.commit().setMessage("feat: added semver plugin incrementer parameter").call()
git.commit().setMessage("feat: added semver plugin incrementer parameter").call()
val dirty = File(testProjectDirectory, "dirty.file")
dirty.writeText("dirty")
git.add().addFilepattern(".").call()

val result = gradleRunner
.withProjectDir(testProjectDirectory)
.withArguments("showInfo")
.withPluginClasspath()
.build()
println(result.output)
Assertions.assertTrue(result.output.contains("Version: 2.1.0-dirty-SNAPSHOT"))
}

@Test
fun `issue-59 dirty working tree with no commits`() {
val testProjectDirectory = createTempDir()
val buildFile = File(testProjectDirectory, "build.gradle.kts")
buildFile.writeText("""
import io.wusa.Info
import io.wusa.TagType
plugins {
id("io.wusa.semver-git-plugin")
}
semver {
tagPrefix = ""
tagType = TagType.ANNOTATED
branches {
branch {
regex = ".+"
incrementer = "CONVENTIONAL_COMMITS_INCREMENTER"
formatter = Transformer<Any, Info>{ info:Info -> "${'$'}{info.version.major}.${'$'}{info.version.minor}.${'$'}{info.version.patch}" }
}
}
}
""")
val git = initializeGitWithoutBranchAnnotated(testProjectDirectory, "2.0.42")
val dirty = File(testProjectDirectory, "dirty.file")
dirty.writeText("dirty")
git.add().addFilepattern(".").call()

val result = gradleRunner
.withProjectDir(testProjectDirectory)
.withArguments("showInfo")
.withPluginClasspath()
.build()
println(result.output)
Assertions.assertTrue(result.output.contains("Version: 2.0.43-dirty-SNAPSHOT"))
}
}

0 comments on commit 65a8249

Please sign in to comment.