1
+ package io.wusa
2
+
3
+ import org.gradle.api.Plugin
4
+ import org.gradle.api.Project
5
+ import java.io.File
6
+
7
+ data class Version (var major : Int , var minor : Int , var patch : Int , var suffix : String )
8
+
9
+ class SemverGitPlugin : Plugin <Project > {
10
+ override fun apply (project : Project ) {
11
+ val nextVersion = " minor"
12
+ val snapshotSuffix = " SNAPSHOT"
13
+ val dirtyMarker = " -dirty"
14
+ val gitDescribeArgs = " --match *[0-9].[0-9]*.[0-9]*"
15
+
16
+ project.version = getGitVersion(nextVersion, snapshotSuffix, dirtyMarker, gitDescribeArgs, project.projectDir)
17
+ project.task(" showVersion" ) {
18
+ it.group = " Help"
19
+ it.description = " Show the project version"
20
+ }
21
+ project.tasks.getByName(" showVersion" ).doLast {
22
+ println (" Version: " + project.version)
23
+ }
24
+ }
25
+
26
+ private fun checkVersion (version : String ): Version {
27
+ return parseVersion(version)
28
+ }
29
+
30
+ private fun parseVersion (version : String ): Version {
31
+ val regex = " /^([0-9]+).([0-9]+).([0-9]+)(-([a-zA-Z0-9.-]+))?$/" .toRegex()
32
+ val matchResults = regex.find(version)
33
+ val (major, minor, patch, suffix) = matchResults!! .destructured
34
+ return Version (major.toInt(), minor.toInt(), patch.toInt(), suffix)
35
+ }
36
+
37
+ private fun getNextVersion (version : String , nextVersion : String , snapshotSuffix : String ): Version {
38
+ when (nextVersion) {
39
+ " major" -> {
40
+ val v = parseVersion(version)
41
+ if (v.suffix == null ) {
42
+ v.major + = 1
43
+ v.minor = 0
44
+ v.patch = 0
45
+ }
46
+ v.suffix = snapshotSuffix
47
+ return v
48
+ }
49
+ " minor" -> {
50
+ val v = parseVersion(version)
51
+ if (v.suffix == null ) {
52
+ v.minor + = 1
53
+ v.patch = 0
54
+ }
55
+ v.suffix = snapshotSuffix
56
+ return v
57
+ }
58
+ " patch" -> {
59
+ val v = parseVersion(version)
60
+ if (v.suffix == null ) {
61
+ v.patch + = 1
62
+ }
63
+ v.suffix = snapshotSuffix
64
+ return v
65
+ }
66
+ else -> {
67
+ return checkVersion(nextVersion)
68
+ }
69
+ }
70
+ }
71
+
72
+ private fun getGitVersion (nextVersion : String , snapshotSuffix : String , dirtyMarker : String , gitArgs : String , projectDir : File ): Version {
73
+ var process = ProcessBuilder (" git describe --exact-match " + gitArgs)
74
+ .directory(projectDir)
75
+ .redirectError(ProcessBuilder .Redirect .INHERIT )
76
+ .start()
77
+ process.waitFor()
78
+ if (process.exitValue() == 0 ) {
79
+ val output = process.inputStream.bufferedReader().use { it.readText() }
80
+ return checkVersion(output)
81
+ }
82
+ process = ProcessBuilder (" git describe --dirty --abbrev=7 " + gitArgs)
83
+ .directory(projectDir)
84
+ .redirectError(ProcessBuilder .Redirect .INHERIT )
85
+ .start()
86
+ process.waitFor()
87
+ if (process.exitValue() == 0 ) {
88
+ val output = process.inputStream.bufferedReader().use { it.readText() }
89
+ var describe = output.trim()
90
+ val dirty = describe.endsWith(" -dirty" )
91
+ if (dirty)
92
+ describe = describe.substring(0 , describe.length - 6 )
93
+ val versionRegex = " /-[0-9]+-g[0-9a-f]+\$ /" .toRegex()
94
+ val (version) = versionRegex.find(describe)!! .destructured
95
+ val suffixRegex = " /-([0-9]+)-g([0-9a-f]+)\$ /" .toRegex()
96
+ val (count, sha) = suffixRegex.find(describe)!! .destructured
97
+ var suffix = snapshotSuffix
98
+ suffix = suffix.replace(" <count>" , count)
99
+ suffix = suffix.replace(" <sha>" , sha)
100
+ if (dirty)
101
+ suffix = suffix.replace(" <dirty>" , dirtyMarker);
102
+ else
103
+ suffix = suffix.replace(" <dirty>" , dirtyMarker);
104
+ return getNextVersion(version, nextVersion, suffix)
105
+ }
106
+ return getNextVersion(" 0.0.0" , nextVersion, " SNAPSHOT" )
107
+ }
108
+ }
0 commit comments