Skip to content

Commit

Permalink
refactor tag retrieval and add tag ordering by version
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdubiel committed Jan 17, 2017
1 parent aa25708 commit 856d7f2
Show file tree
Hide file tree
Showing 46 changed files with 566 additions and 489 deletions.
4 changes: 1 addition & 3 deletions docs/configuration/version.rst
Expand Up @@ -92,9 +92,7 @@ You can implement own deserializer by setting closure that would accept deserial

``position`` object contains:

* ``latestTag`` - the name of the latest tag
* ``branch`` - the name of the current branch
* ``onTag`` - true, if current commit is tagged with release version tag

Last but not least, ``tagName`` contains prepared tag name that should be used to extract version. ``position.latestTag``
might point to next version tag with additional suffix.
Expand Down Expand Up @@ -265,7 +263,7 @@ Custom version creators can be implemented by creating closure::
{version, position -> ...}
* version - string version resolved by previous steps
* position - object described above in *Serialization* section
* position - object described above :doc:`scm-position` section

.. _version-sanitization:

Expand Down
Expand Up @@ -9,6 +9,10 @@ class BaseIntegrationTest extends RepositoryBasedTest {
return temporaryFolder.newFile('build.gradle')
}

File newFile(String name) {
return temporaryFolder.newFile(name)
}

void buildFile(String contents) {
buildFile() << """
plugins {
Expand Down
Expand Up @@ -25,6 +25,7 @@ class SimpleIntegrationTest extends BaseIntegrationTest {

then:
releaseResult.task(':release').outcome == TaskOutcome.SUCCESS
releaseResult.output.contains('Creating tag: release-1.0.0')

when:
def result = runGradle('cV')
Expand All @@ -33,4 +34,55 @@ class SimpleIntegrationTest extends BaseIntegrationTest {
result.output.contains('1.0.0')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should return tag with highest version when there are multiple releases on single commit"() {
given:
buildFile('')

runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')
runGradle('release', '-Prelease.version=1.1.0', '-Prelease.localOnly', '-Prelease.disableChecks', '-Prelease.forceSnapshot')

when:
def result = runGradle('currentVersion')

then:
result.output.contains('1.1.0')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should return tag with highest version when there are normal and alpha releases on single commit"() {
given:
buildFile('')

runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')
runGradle('markNextVersion', '-Prelease.version=2.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')

when:
def result = runGradle('currentVersion')

then:
result.output.contains('2.0.0')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should update file in pre release hook"() {
given:
File versionFile = newFile('version-file')
versionFile << "Version: 0.1.0"

buildFile("""
scmVersion {
hooks {
pre 'fileUpdate', [files: ['version-file'], pattern: { v, p -> v }, replacement: { v, p -> v }]
pre 'commit'
}
}
""")

when:
runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')

then:
versionFile.text == "Version: 1.0.0"
}
}
Expand Up @@ -9,11 +9,11 @@ enum NextVersionSerializer {
{ NextVersionProperties rules, String version ->
return rules.suffix ? version + rules.separator + rules.suffix : version
},
{ NextVersionProperties rules, ScmPosition position ->
{ NextVersionProperties rules, ScmPosition position, String tag ->
if (rules.suffix.isEmpty()) {
return position.latestTag
return tag
}
return position.latestTag.replaceFirst(rules.separator + rules.suffix, '')
return tag.replaceFirst(rules.separator + rules.suffix, '')
}
)

Expand Down
Expand Up @@ -23,18 +23,18 @@ class Releaser {
}

void release(Properties rules) {
VersionWithPosition positionedVersion = versionService.currentVersion(rules.version, rules.tag, rules.nextVersion)
Version version = positionedVersion.version
VersionContext versionContext = versionService.currentVersion(rules.version, rules.tag, rules.nextVersion)
Version version = versionContext.version

if (notOnTagAlready(positionedVersion) || rules.version.forceVersion()) {
if (versionContext.snapshot) {
String tagName = rules.tag.serialize(rules.tag, version.toString())

hooksRunner.runPreReleaseHooks(rules.hooks, rules, positionedVersion, version)
hooksRunner.runPreReleaseHooks(rules.hooks, rules, versionContext, version)

logger.quiet("Creating tag: $tagName")
repository.tag(tagName)

hooksRunner.runPostReleaseHooks(rules.hooks, rules, positionedVersion, version)
hooksRunner.runPostReleaseHooks(rules.hooks, rules, versionContext, version)
} else {
logger.quiet("Working on released version ${version}, nothing to release.")
}
Expand All @@ -43,8 +43,4 @@ class Releaser {
void pushRelease() {
repository.push()
}

private boolean notOnTagAlready(VersionWithPosition positionedVersion) {
return positionedVersion.snapshotVersion
}
}

This file was deleted.

@@ -0,0 +1,19 @@
package pl.allegro.tech.build.axion.release.domain

class ScmState {

final boolean onReleaseTag

final boolean onNextVersionTag

final boolean noReleaseTagsFound

final boolean hasUncommittedChanges

ScmState(boolean onReleaseTag, boolean onNextVersionTag, boolean noReleaseTagsFound, boolean hasUncommittedChanges) {
this.onReleaseTag = onReleaseTag
this.onNextVersionTag = onNextVersionTag
this.noReleaseTagsFound = noReleaseTagsFound
this.hasUncommittedChanges = hasUncommittedChanges
}
}
Expand Up @@ -22,15 +22,9 @@ class TagNameSerializationConfig {

Closure initialVersion = defaultInitialVersion()

Closure tagSelector = defaultTagSelector()

private static Closure defaultInitialVersion() {
return { TagProperties rules, ScmPosition position ->
return '0.1.0'
}
}

private static Closure defaultTagSelector() {
return ScmRepository.LAST_TAG_SELECTOR
}
}
Expand Up @@ -8,6 +8,7 @@ import pl.allegro.tech.build.axion.release.domain.properties.Properties
import pl.allegro.tech.build.axion.release.infrastructure.di.Context
import pl.allegro.tech.build.axion.release.infrastructure.di.GradleAwareContext
import pl.allegro.tech.build.axion.release.infrastructure.output.GradleReleaseLoggerFactory
import pl.allegro.tech.build.axion.release.util.FileLoader

import javax.inject.Inject
import java.util.regex.Pattern
Expand Down Expand Up @@ -52,13 +53,12 @@ class VersionConfig {

private String resolvedVersion = null

private VersionWithPosition rawVersion = null
private VersionContext rawVersion = null

@Inject
VersionConfig(Project project) {
ReleaseLogger.Factory.initialize(new GradleReleaseLoggerFactory())

this.project = project
FileLoader.setRoot(project.rootDir)

this.repository = RepositoryConfigFactory.create(project)
this.dryRun = project.hasProperty(ReleasePlugin.DRY_RUN_FLAG)
Expand Down
@@ -0,0 +1,22 @@
package pl.allegro.tech.build.axion.release.domain

import com.github.zafarkhaja.semver.Version
import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition

class VersionContext {

final Version version

final boolean snapshot

final Version previousVersion

final ScmPosition position

VersionContext(Version version, boolean snapshot, Version previousVersion, ScmPosition position) {
this.version = version
this.snapshot = snapshot
this.previousVersion = previousVersion
this.position = position
}
}
Expand Up @@ -8,40 +8,54 @@ import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition

class VersionFactory {

Version create(ScmPositionContext context,
VersionProperties versionRules,
TagProperties tagRules,
NextVersionProperties nextVersionRules) {
Version version

if (versionRules.forcedVersion) {
version = Version.valueOf(versionRules.forcedVersion)
} else {
if (context.position.tagless()) {
version = Version.valueOf(initialVersion(tagRules.initialVersion, tagRules, context.position))
} else {
version = Version.valueOf(readVersionFromPosition(context, tagRules, nextVersionRules))

boolean hasUncommittedChanges = !versionRules.ignoreUncommittedChanges && context.position.hasUncommittedChanges
boolean hasChanges = !context.position.onTag || hasUncommittedChanges || versionRules.forceSnapshot

if (hasChanges && !context.nextVersionTag) {
version = versionRules.versionIncrementer(new VersionIncrementerContext(version, context.position))
}
}
private final VersionProperties versionProperties

private final TagProperties tagProperties

private final NextVersionProperties nextVersionProperties

private final ScmPosition scmPosition

VersionFactory(VersionProperties versionProperties,
TagProperties tagProperties,
NextVersionProperties nextVersionProperties,
ScmPosition scmPosition) {
this.tagProperties = tagProperties
this.nextVersionProperties = nextVersionProperties
this.scmPosition = scmPosition
this.versionProperties = versionProperties
}

Version versionFromTag(String tag) {
String tagWithoutNextVersion = tag
if (tag ==~ /.*${nextVersionProperties.suffix}$/) {
tagWithoutNextVersion = nextVersionProperties.deserializer(nextVersionProperties, scmPosition, tag)
}
return version
return Version.valueOf(tagProperties.deserialize(tagProperties, scmPosition, tagWithoutNextVersion))
}

private String initialVersion(Closure toCall, TagProperties tagRules, ScmPosition currentPosition) {
return toCall(tagRules, currentPosition)
Version initialVersion() {
return Version.valueOf(tagProperties.initialVersion(tagProperties, scmPosition))
}

private String readVersionFromPosition(ScmPositionContext context, TagProperties tagRules, NextVersionProperties nextVersionRules) {
String tagWithoutNextVersion = context.position.latestTag
if(context.nextVersionTag) {
tagWithoutNextVersion = nextVersionRules.deserializer(nextVersionRules, context.position)
Map createFinalVersion(ScmState scmState, Version version) {
boolean hasUncommittedChanges = !versionProperties.ignoreUncommittedChanges && scmState.hasUncommittedChanges
boolean hasCommittedChanges = !scmState.onReleaseTag
boolean hasChanges = hasCommittedChanges || hasUncommittedChanges

boolean isSnapshot = versionProperties.forcedVersion || versionProperties.forceSnapshot || hasChanges || scmState.onNextVersionTag || scmState.noReleaseTagsFound
boolean incrementVersion = versionProperties.forceSnapshot || (!scmState.onNextVersionTag && !scmState.noReleaseTagsFound && hasChanges)

Version finalVersion = version
if (versionProperties.forcedVersion) {
finalVersion = Version.valueOf(versionProperties.forcedVersion)
} else if (incrementVersion) {
finalVersion = versionProperties.versionIncrementer(new VersionIncrementerContext(version, scmPosition))
}
return tagRules.deserialize(tagRules, context.position, tagWithoutNextVersion)

return [
version : finalVersion,
snapshot: isSnapshot
]
}
}

0 comments on commit 856d7f2

Please sign in to comment.