Skip to content

Commit 114f53d

Browse files
committed
Use simple JGit-based versioning buildscript
1 parent 0f56481 commit 114f53d

File tree

4 files changed

+142
-14
lines changed

4 files changed

+142
-14
lines changed

.gitignore

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
.gradle/
2+
23
/build/
34
/out/
4-
/problem4j-core/out/
5-
/problem4j-core/build/
6-
/problem4j-jackson/out/
7-
/problem4j-jackson/build/
8-
/problem4j-spring-web/out/
9-
/problem4j-spring-web/build/
5+
6+
/buildSrc/build/
7+
/buildSrc/out/
108

119
### IDEs ###
1210
/.idea/

build.gradle

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
import com.diffplug.spotless.LineEnding
2+
13
plugins {
2-
id "java-library"
3-
id "maven-publish"
4-
id "com.diffplug.spotless" version "7.1.0"
5-
id "net.nemerosa.versioning" version "3.1.0"
4+
id("java-library")
5+
id("maven-publish")
6+
id("com.diffplug.spotless") version "7.2.1"
67
}
78

89
group = "com.github.malczuuu"
9-
version = (versioning.info.tag ?: "${versioning.info.lastTag}-${versioning.info.build}") \
10-
+ (versioning.info.dirty ? "-dirty" : "")
10+
11+
/**
12+
* Conditional approach to versioning. If `-Pversion=...` is specified on the command line, it will be used as the
13+
* version. Otherwise, the version is derived from the git tag and build number.
14+
*/
15+
if (version == null || version == "unspecified") {
16+
version = Versioning.getVersion(rootProject.rootDir)
17+
}
1118

1219
java {
1320
toolchain {
@@ -37,15 +44,14 @@ publishing {
3744
}
3845
}
3946

40-
import com.diffplug.spotless.LineEnding
41-
4247
spotless {
4348
format "misc", {
4449
target "*.gradle", ".gitattributes", ".gitignore"
4550

4651
trimTrailingWhitespace()
4752
leadingTabsToSpaces(4)
4853
endWithNewline()
54+
lineEndings = LineEnding.UNIX
4955
}
5056

5157
format "yaml", {
@@ -54,6 +60,7 @@ spotless {
5460
trimTrailingWhitespace()
5561
leadingTabsToSpaces(2)
5662
endWithNewline()
63+
lineEndings = LineEnding.UNIX
5764
}
5865

5966
java {
@@ -62,6 +69,19 @@ spotless {
6269
googleJavaFormat("1.28.0")
6370
lineEndings = LineEnding.UNIX
6471
}
72+
73+
groovy {
74+
target "src/**/*.groovy"
75+
76+
greclipse()
77+
lineEndings = LineEnding.UNIX
78+
}
79+
}
80+
81+
tasks.register("printVersion") {
82+
doLast {
83+
println "Project version: ${Versioning.getVersion(rootProject.rootDir)}"
84+
}
6585
}
6686

6787
tasks.named("test") {

buildSrc/build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
plugins {
2+
id "groovy"
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
dependencies {
10+
implementation("org.eclipse.jgit:org.eclipse.jgit:7.3.0.202506031305-r")
11+
implementation(localGroovy())
12+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import org.eclipse.jgit.api.Git
2+
import org.eclipse.jgit.errors.IncorrectObjectTypeException
3+
import org.eclipse.jgit.lib.ObjectId
4+
import org.eclipse.jgit.lib.Ref
5+
import org.eclipse.jgit.lib.Repository
6+
import org.eclipse.jgit.revwalk.RevCommit
7+
import org.eclipse.jgit.revwalk.RevTag
8+
import org.eclipse.jgit.revwalk.RevWalk
9+
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
10+
11+
/**
12+
* Utility class for determining the version of the project based on Git tags.
13+
*/
14+
class Versioning {
15+
16+
/**
17+
* Get the version of the project based on Git tags.
18+
* - If HEAD has a tag → return that tag.
19+
* - Otherwise → return latest tag by commit history + abbreviated commit hash.
20+
* - If no tags exist → return "0.0.0-<abbreviatedHash>".
21+
*
22+
* @param projectRootDir the root directory of the project (containing the .git directory)
23+
* @return the version string
24+
*/
25+
static String getVersion(File projectRootDir) {
26+
try (
27+
Repository repository = new FileRepositoryBuilder()
28+
.setGitDir(new File(projectRootDir, ".git"))
29+
.readEnvironment()
30+
.findGitDir()
31+
.build()
32+
Git git = new Git(repository)
33+
) {
34+
def headId = repository.resolve("HEAD")
35+
if (headId == null) {
36+
System.err.println("HEAD not found in repository")
37+
return "0.0.0"
38+
}
39+
40+
RevCommit headCommit
41+
try (RevWalk revWalk = new RevWalk(repository)) {
42+
headCommit = revWalk.parseCommit(headId)
43+
}
44+
45+
def tags = git.tagList().call()
46+
if (tags.isEmpty()) {
47+
def hash = headCommit.id.name().substring(0, 7)
48+
return "0.0.0-${hash}"
49+
}
50+
51+
// Check if HEAD is exactly on a tag
52+
Ref tagOnHead = tags.find {
53+
try (RevWalk revWalk = new RevWalk(repository)) {
54+
ObjectId commitId
55+
try {
56+
RevTag revTag = revWalk.parseTag(it.objectId)
57+
commitId = revTag.getObject().getId()
58+
} catch (IncorrectObjectTypeException ignored) {
59+
// Not a tag object, likely a lightweight tag
60+
commitId = it.getObjectId()
61+
}
62+
return commitId == headCommit.id
63+
}
64+
}
65+
if (tagOnHead != null) {
66+
return tagOnHead.getName().replaceAll("refs/tags/", "")
67+
}
68+
69+
// Map each tag to the commit it points to
70+
Map<Ref, RevCommit> tagToCommit = [:]
71+
try (RevWalk revWalk = new RevWalk(repository)) {
72+
tags.each {
73+
def commitId = it.getPeeledObjectId() ?: it.getObjectId()
74+
RevCommit commit = revWalk.parseCommit(commitId)
75+
tagToCommit[it] = commit
76+
}
77+
78+
// Walk history from HEAD backwards
79+
revWalk.markStart(headCommit)
80+
for (RevCommit c : revWalk) {
81+
def tagRef = tagToCommit.find { it.getValue() == c }?.getKey()
82+
if (tagRef != null) {
83+
def tagName = tagRef.getName().replaceAll("refs/tags/", "")
84+
def abbrevHash = headCommit.getId().name().substring(0, 7)
85+
return "${tagName}-${abbrevHash}"
86+
}
87+
}
88+
}
89+
90+
// Fallback if no tag found in history
91+
def fallbackHash = headCommit.getId().name().substring(0, 7)
92+
return "0.0.0-${fallbackHash}"
93+
} catch (Exception e) {
94+
System.err.println("Error determining version: " + e)
95+
return "0.0.0"
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)