Skip to content

Commit

Permalink
Adding version number information into VersionningExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
bastienpaulfr committed Nov 21, 2019
1 parent f00810c commit d4964c9
Show file tree
Hide file tree
Showing 12 changed files with 541 additions and 166 deletions.
108 changes: 106 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ Property | Description | Git: `master` | Git: `feature/great` | Git: `release/2.
`tag` (1) | Current tag | (2) | (2) | (2)
`lastTag` (1) | Last tag | (4) | (4) | (4)
`dirty` | Current state of the working copy | (3) | (3) | (3)
`versionNumber` | Version number containing major, minor, patch, qualifier and versionCode | | |
`versionNumber.major` | Major version | 0 | 0 | 2
`versionNumber.minor` | Minor version | 0 | 0 | 0
`versionNumber.patch` | Patch version | 0 | 0 | 0, 1, 2, ...
`versionNumber.qualifier` | Version qualifier (alpha, beta, engineer, ...)| '' | '' | ''
`versionNumber.versionCode` | Version code | 0 | 0 | 20000, 20001, 20002, ...

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

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.

### Version number

Version number is a container of several numbers computed from `display` by default . It is hosting major, minor, patch,
qualifier and versionCode.

- In a tag like `1.2.3`, then major is `1`, minor is `2` and patch is `3`
- Qualifier are taken from tags formatted like `1.2-beta.0` where qualifier is `-beta` here
- Version code is a integer computed from major, minor and patch version.
- `1.2.3` will give 10203
- `21.5.16` will give 210516
- `2.0-alpha.0` will give 20000

## Tasks

The `versioning` plug-in provides two tasks.
Expand All @@ -142,6 +160,11 @@ Displays the version information in the standard output. For example:
[version] tag =
[version] lastTag = 0.2.0
[version] dirty = false
[version] versionCode = 0
[version] major = 0
[version] minor = 0
[version] patch = 0
[version] qualifier =
```

### `versionFile`
Expand All @@ -163,6 +186,11 @@ VERSION_SCM=git
VERSION_TAG=
VERSION_LAST_TAG=0.2.0
VERSION_DIRTY=false
VERSION_VERSIONCODE=0
VERSION_MAJOR=0
VERSION_MINOR=0
VERSION_PATCH=0
VERSION_QUALIFIER=
```

This makes this file easy to integrate in a Bash script:
Expand Down Expand Up @@ -202,7 +230,7 @@ versioning {
* present, the type is the branch and the base is empty.
* F.e. if you want use tag name instead of branch you may provide something like:
*/
releaseParser = { scmInfo, separator = '/' -> ->
releaseParser = { scmInfo, separator = '/' ->
List<String> part = scmInfo.tag.split('/') + ''
new net.nemerosa.versioning.ReleaseInfo(type: part[0], base: part[1])
}
Expand All @@ -226,7 +254,6 @@ versioning {
* the tags in Git.
*/
lastTagPattern = /(\d+)$/
*/
}
```

Expand Down Expand Up @@ -387,6 +414,83 @@ versioning {
}
}
```
### Version number

Version number computation can be customised by setting some properties in the `versioning` extension.

```groovy
versioning {
/**
* Digit precision for computing version code.
*
* With a precision of 2, 1.25.3 will become 12503.
* With a precision of 3, 1.25.3 will become 1250003.
*/
int precision = 2
/**
* Default number to use when no version number can be extracted from version string.
*/
int defaultNumber = 0
/**
* Closure that takes major, minor and patch integers in parameter and is computing versionCode number.
*/
Closure<Integer> computeVersionCode = { int major, int minor, int patch ->
return (major * 10**(2 * precision)) + (minor * 10**precision) + patch
}
/**
* Compute version number
*
* Closure that compute VersionNumber from <i>scmInfo</i>, <i>versionReleaseType</i>, <i>versionBranchId</i>,
* <i>versionFull</i>, <i>versionBase</i> and <i>versionDisplay</i>
*
* By default it tries to find this pattern in display : '([0-9]+)[.]([0-9]+)[.]([0-9]+)(.*)$'.
* Version code is computed with this algo : code = group(1) * 10^2precision + group(2) * 10^precision + group(3)
*
* Example :
*
* - with precision = 2
*
* 1.2.3 -> 10203
* 10.55.62 -> 105562
* 20.3.2 -> 200302
*
* - with precision = 3
*
* 1.2.3 -> 1002003
* 10.55.62 -> 100055062
* 20.3.2 -> 20003002
**/
Closure<VersionNumber> parseVersionNumber = { SCMInfo scmInfo, String versionReleaseType, String versionBranchId,
String versionFull, String versionBase, String versionDisplay ->
// We are specifying all these parameters because we want to leave the choice to the developer
// to use data that's right to him
// Regex explained :
// - 1st group one digit that is major version
// - 2nd group one digit that is minor version
// - It can be followed by a qualifier name
// - 3rd group and last part is one digit that is patch version
Matcher m = (versionDisplay =~ '([0-9]+)[.]([0-9]+).*[.]([0-9]+)(.*)$')
if (m.find()) {
try {
int n1 = Integer.parseInt(m.group(1))
int n2 = Integer.parseInt(m.group(2))
int n3 = Integer.parseInt(m.group(3))
String q = m.group(4) ?: ''
return new VersionNumber(n1, n2, n3, q, computeVersionCode(n1, n2, n3).intValue(), versionDisplay)
} catch (Exception ignore) {
// Should never go here
return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
}
} else {
return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
}
}
}
```

## Detached and shallow clone support

Expand Down
22 changes: 22 additions & 0 deletions src/main/groovy/net/nemerosa/versioning/ReleaseInfo.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,32 @@ package net.nemerosa.versioning

import groovy.transform.Canonical

/**
* Information about the branch coming from its name.
*
* For instance :
*
* release/2.0
* type : 'release'
* base : '2.0'
*
* master
* type : 'master'
* base : ''
*/
@Canonical
class ReleaseInfo {

/**
* Type of branch.
*
* Could be "release", "feature" or what ever has been configured
*/
String type

/**
* Base of release or feature branch. This is what comes after type in branch's name.
*/
String base

}
26 changes: 26 additions & 0 deletions src/main/groovy/net/nemerosa/versioning/SCMInfoService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,37 @@ import org.gradle.api.Project

interface SCMInfoService {

/**
* Get SCM Info
* @param project Gradle's project
* @param extension Plugin data holder
* @return Information got from scm
*/
SCMInfo getInfo(Project project, VersioningExtension extension)

/**
* Get last tags
*
* @param project Gradle's project
* @param extension Plugin data holder
* @param tagPattern Tag pattern
* @return List of tags
*/
List<String> getLastTags(Project project, VersioningExtension extension, String tagPattern)

/**
* Get base tags
*
* @param project Gradle's project
* @param extension Plugin data holder
* @param base Base of branch in case where name of branch is something/base
* @return List of base tags
*/
List<String> getBaseTags(Project project, VersioningExtension extension, String base)

/**
*
* @return Separator used for separating branch type and branch base
*/
String getBranchTypeSeparator()
}
2 changes: 1 addition & 1 deletion src/main/groovy/net/nemerosa/versioning/VersionInfo.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ class VersionInfo {
String base = ''
String build = ''
String tag = null
int versionCode = 0
String lastTag = null
boolean dirty = false
boolean shallow = false
VersionNumber versionNumber = null

}
50 changes: 50 additions & 0 deletions src/main/groovy/net/nemerosa/versioning/VersionNumber.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.nemerosa.versioning

/**
* Representation of a version number.
*
* This is generally a combination of three digits with an optional qualifier.
* These digits are major, minor and path numbers.
*
* This representation is one of many interpretation of version number format. It is let to developer's appreciation.
*/
class VersionNumber {
/**
* Major version
*/
final int major

/**
* Minor version
*/
final int minor

/**
* Patch version
*/
final int patch

/**
* Optional qualifier
*/
final String qualifier

/**
* version code
*/
final int versionCode

/**
* Original full version string
*/
final String versionString

VersionNumber(int major, int minor, int patch, String qualifier, int versionCode, String versionString) {
this.major = major
this.minor = minor
this.patch = patch
this.qualifier = qualifier
this.versionCode = versionCode
this.versionString = versionString
}
}
Loading

0 comments on commit d4964c9

Please sign in to comment.