Skip to content

Commit 597fa62

Browse files
authored
Merge pull request #67 from CoppernicSoftware/versionCode
Add a version code in VersioningExtension
2 parents 0bbf5c8 + d4964c9 commit 597fa62

File tree

14 files changed

+599
-23
lines changed

14 files changed

+599
-23
lines changed

.gitignore

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
.gradle
1+
# Build
22
build/
3-
.idea
4-
*.iml
3+
/out
4+
5+
# Mac
56
.DS_Store
67
userHome
8+
9+
# IntelliJ
10+
.idea
11+
*.iml
12+
13+
# Gradle
14+
.gradletasknamecache
15+
.gradle
16+
17+
# Other
18+
local.properties
719
*.swp
8-
/out

README.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ Property | Description | Git: `master` | Git: `feature/great` | Git: `release/2.
9797
`tag` (1) | Current tag | (2) | (2) | (2)
9898
`lastTag` (1) | Last tag | (4) | (4) | (4)
9999
`dirty` | Current state of the working copy | (3) | (3) | (3)
100+
`versionNumber` | Version number containing major, minor, patch, qualifier and versionCode | | |
101+
`versionNumber.major` | Major version | 0 | 0 | 2
102+
`versionNumber.minor` | Minor version | 0 | 0 | 0
103+
`versionNumber.patch` | Patch version | 0 | 0 | 0, 1, 2, ...
104+
`versionNumber.qualifier` | Version qualifier (alpha, beta, engineer, ...)| '' | '' | ''
105+
`versionNumber.versionCode` | Version code | 0 | 0 | 20000, 20001, 20002, ...
100106

101107
(1) not supported for Subversion
102108
(2) will be the name of the current tag if any, or `null` if no tag is associated to the current `HEAD`.
@@ -119,6 +125,18 @@ For branches to type `release`, an additional computation occurs:
119125

120126
By using the `display` version when tagging a release, the `display` version will be automatically incremented, patch after patch, using the `release` base at a prefix.
121127

128+
### Version number
129+
130+
Version number is a container of several numbers computed from `display` by default . It is hosting major, minor, patch,
131+
qualifier and versionCode.
132+
133+
- In a tag like `1.2.3`, then major is `1`, minor is `2` and patch is `3`
134+
- Qualifier are taken from tags formatted like `1.2-beta.0` where qualifier is `-beta` here
135+
- Version code is a integer computed from major, minor and patch version.
136+
- `1.2.3` will give 10203
137+
- `21.5.16` will give 210516
138+
- `2.0-alpha.0` will give 20000
139+
122140
## Tasks
123141

124142
The `versioning` plug-in provides two tasks.
@@ -142,6 +160,11 @@ Displays the version information in the standard output. For example:
142160
[version] tag =
143161
[version] lastTag = 0.2.0
144162
[version] dirty = false
163+
[version] versionCode = 0
164+
[version] major = 0
165+
[version] minor = 0
166+
[version] patch = 0
167+
[version] qualifier =
145168
```
146169

147170
### `versionFile`
@@ -163,6 +186,11 @@ VERSION_SCM=git
163186
VERSION_TAG=
164187
VERSION_LAST_TAG=0.2.0
165188
VERSION_DIRTY=false
189+
VERSION_VERSIONCODE=0
190+
VERSION_MAJOR=0
191+
VERSION_MINOR=0
192+
VERSION_PATCH=0
193+
VERSION_QUALIFIER=
166194
```
167195

168196
This makes this file easy to integrate in a Bash script:
@@ -202,7 +230,7 @@ versioning {
202230
* present, the type is the branch and the base is empty.
203231
* F.e. if you want use tag name instead of branch you may provide something like:
204232
*/
205-
releaseParser = { scmInfo, separator = '/' -> ->
233+
releaseParser = { scmInfo, separator = '/' ->
206234
List<String> part = scmInfo.tag.split('/') + ''
207235
new net.nemerosa.versioning.ReleaseInfo(type: part[0], base: part[1])
208236
}
@@ -226,7 +254,6 @@ versioning {
226254
* the tags in Git.
227255
*/
228256
lastTagPattern = /(\d+)$/
229-
*/
230257
}
231258
```
232259

@@ -387,6 +414,83 @@ versioning {
387414
}
388415
}
389416
```
417+
### Version number
418+
419+
Version number computation can be customised by setting some properties in the `versioning` extension.
420+
421+
```groovy
422+
versioning {
423+
/**
424+
* Digit precision for computing version code.
425+
*
426+
* With a precision of 2, 1.25.3 will become 12503.
427+
* With a precision of 3, 1.25.3 will become 1250003.
428+
*/
429+
int precision = 2
430+
431+
/**
432+
* Default number to use when no version number can be extracted from version string.
433+
*/
434+
int defaultNumber = 0
435+
436+
/**
437+
* Closure that takes major, minor and patch integers in parameter and is computing versionCode number.
438+
*/
439+
Closure<Integer> computeVersionCode = { int major, int minor, int patch ->
440+
return (major * 10**(2 * precision)) + (minor * 10**precision) + patch
441+
}
442+
443+
/**
444+
* Compute version number
445+
*
446+
* Closure that compute VersionNumber from <i>scmInfo</i>, <i>versionReleaseType</i>, <i>versionBranchId</i>,
447+
* <i>versionFull</i>, <i>versionBase</i> and <i>versionDisplay</i>
448+
*
449+
* By default it tries to find this pattern in display : '([0-9]+)[.]([0-9]+)[.]([0-9]+)(.*)$'.
450+
* Version code is computed with this algo : code = group(1) * 10^2precision + group(2) * 10^precision + group(3)
451+
*
452+
* Example :
453+
*
454+
* - with precision = 2
455+
*
456+
* 1.2.3 -> 10203
457+
* 10.55.62 -> 105562
458+
* 20.3.2 -> 200302
459+
*
460+
* - with precision = 3
461+
*
462+
* 1.2.3 -> 1002003
463+
* 10.55.62 -> 100055062
464+
* 20.3.2 -> 20003002
465+
**/
466+
Closure<VersionNumber> parseVersionNumber = { SCMInfo scmInfo, String versionReleaseType, String versionBranchId,
467+
String versionFull, String versionBase, String versionDisplay ->
468+
// We are specifying all these parameters because we want to leave the choice to the developer
469+
// to use data that's right to him
470+
// Regex explained :
471+
// - 1st group one digit that is major version
472+
// - 2nd group one digit that is minor version
473+
// - It can be followed by a qualifier name
474+
// - 3rd group and last part is one digit that is patch version
475+
Matcher m = (versionDisplay =~ '([0-9]+)[.]([0-9]+).*[.]([0-9]+)(.*)$')
476+
if (m.find()) {
477+
try {
478+
int n1 = Integer.parseInt(m.group(1))
479+
int n2 = Integer.parseInt(m.group(2))
480+
int n3 = Integer.parseInt(m.group(3))
481+
String q = m.group(4) ?: ''
482+
return new VersionNumber(n1, n2, n3, q, computeVersionCode(n1, n2, n3).intValue(), versionDisplay)
483+
} catch (Exception ignore) {
484+
// Should never go here
485+
return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
486+
}
487+
} else {
488+
return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
489+
}
490+
}
491+
492+
}
493+
```
390494

391495
## Detached and shallow clone support
392496

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ dependencies {
6161
/**
6262
* Plug-in definition
6363
*/
64-
6564
pluginBundle {
6665
website = 'https://github.com/nemerosa/versioning/'
6766
vcsUrl = 'https://github.com/nemerosa/versioning/'
67+
description = 'Gradle plug-in that computes version information from the SCM'
6868
tags = ['gradle', 'plugin', 'scm', 'git', 'svn', 'version']
6969
}
7070

src/main/groovy/net/nemerosa/versioning/ReleaseInfo.groovy

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,32 @@ package net.nemerosa.versioning
22

33
import groovy.transform.Canonical
44

5+
/**
6+
* Information about the branch coming from its name.
7+
*
8+
* For instance :
9+
*
10+
* release/2.0
11+
* type : 'release'
12+
* base : '2.0'
13+
*
14+
* master
15+
* type : 'master'
16+
* base : ''
17+
*/
518
@Canonical
619
class ReleaseInfo {
720

21+
/**
22+
* Type of branch.
23+
*
24+
* Could be "release", "feature" or what ever has been configured
25+
*/
826
String type
27+
28+
/**
29+
* Base of release or feature branch. This is what comes after type in branch's name.
30+
*/
931
String base
1032

1133
}

src/main/groovy/net/nemerosa/versioning/SCMInfoService.groovy

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,37 @@ import org.gradle.api.Project
44

55
interface SCMInfoService {
66

7+
/**
8+
* Get SCM Info
9+
* @param project Gradle's project
10+
* @param extension Plugin data holder
11+
* @return Information got from scm
12+
*/
713
SCMInfo getInfo(Project project, VersioningExtension extension)
814

15+
/**
16+
* Get last tags
17+
*
18+
* @param project Gradle's project
19+
* @param extension Plugin data holder
20+
* @param tagPattern Tag pattern
21+
* @return List of tags
22+
*/
923
List<String> getLastTags(Project project, VersioningExtension extension, String tagPattern)
1024

25+
/**
26+
* Get base tags
27+
*
28+
* @param project Gradle's project
29+
* @param extension Plugin data holder
30+
* @param base Base of branch in case where name of branch is something/base
31+
* @return List of base tags
32+
*/
1133
List<String> getBaseTags(Project project, VersioningExtension extension, String base)
1234

35+
/**
36+
*
37+
* @return Separator used for separating branch type and branch base
38+
*/
1339
String getBranchTypeSeparator()
1440
}

src/main/groovy/net/nemerosa/versioning/VersionInfo.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ class VersionInfo {
2323
String lastTag = null
2424
boolean dirty = false
2525
boolean shallow = false
26+
VersionNumber versionNumber = null
2627

2728
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package net.nemerosa.versioning
2+
3+
/**
4+
* Representation of a version number.
5+
*
6+
* This is generally a combination of three digits with an optional qualifier.
7+
* These digits are major, minor and path numbers.
8+
*
9+
* This representation is one of many interpretation of version number format. It is let to developer's appreciation.
10+
*/
11+
class VersionNumber {
12+
/**
13+
* Major version
14+
*/
15+
final int major
16+
17+
/**
18+
* Minor version
19+
*/
20+
final int minor
21+
22+
/**
23+
* Patch version
24+
*/
25+
final int patch
26+
27+
/**
28+
* Optional qualifier
29+
*/
30+
final String qualifier
31+
32+
/**
33+
* version code
34+
*/
35+
final int versionCode
36+
37+
/**
38+
* Original full version string
39+
*/
40+
final String versionString
41+
42+
VersionNumber(int major, int minor, int patch, String qualifier, int versionCode, String versionString) {
43+
this.major = major
44+
this.minor = minor
45+
this.patch = patch
46+
this.qualifier = qualifier
47+
this.versionCode = versionCode
48+
this.versionString = versionString
49+
}
50+
}

0 commit comments

Comments
 (0)