Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3341 - fix parsing loose version format #3379

Merged
merged 3 commits into from
Feb 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,19 @@ public void FeatureOnReleaseFeatureBranchNotDeleted()

fixture.AssertFullSemver("4.5.0-beta.2", configuration);
}

[TestCase("release/1.2.0", "1.2.0-beta.1+1", SemanticVersionFormat.Loose)]
[TestCase("release/1.2.0", "1.2.0-beta.1+1", SemanticVersionFormat.Strict)]
[TestCase("release/1.2", "1.2.0-beta.1+1", SemanticVersionFormat.Loose)]
[TestCase("release/1", "1.0.0-beta.1+1", SemanticVersionFormat.Loose)]
public void ShouldDetectVersionInReleaseBranch(string branchName, string expectedVersion, SemanticVersionFormat semanticVersionFormat)
{
var configuration = GitFlowConfigurationBuilder.New
.WithSemanticVersionFormat(semanticVersionFormat)
.Build();

using var fixture = new EmptyRepositoryFixture(branchName);
fixture.MakeACommit();
fixture.AssertFullSemver(expectedVersion, configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,32 @@ public void ReturnsNullWhenNoNextVersionIsInConfig()
baseVersion.ShouldBe(null);
}

[TestCase("1.0.0", "1.0.0")]
[TestCase("2.12.654651698", "2.12.654651698")]
public void ConfigNextVersionTest(string nextVersion, string expectedVersion)
[TestCase("1.0.0", "1.0.0", SemanticVersionFormat.Strict)]
[TestCase("1.0.0", "1.0.0", SemanticVersionFormat.Loose)]
[TestCase("2.12.654651698", "2.12.654651698", SemanticVersionFormat.Strict)]
[TestCase("2.12.654651698", "2.12.654651698", SemanticVersionFormat.Loose)]
[TestCase("0.1", "0.1.0", SemanticVersionFormat.Loose)]
public void ConfigNextVersionTest(string nextVersion, string expectedVersion, SemanticVersionFormat versionFormat)
{
var baseVersion = GetBaseVersion(new GitVersionConfiguration
{
NextVersion = nextVersion
});
var baseVersion = GetBaseVersion(new GitVersionConfiguration { NextVersion = nextVersion, SemanticVersionFormat = versionFormat });

baseVersion.ShouldNotBeNull();
baseVersion.ShouldIncrement.ShouldBe(false);
baseVersion.SemanticVersion.ToString().ShouldBe(expectedVersion);
}

[TestCase("0.1", SemanticVersionFormat.Strict)]
public void ConfigNextVersionTestShouldFail(string nextVersion, SemanticVersionFormat versionFormat)
=>
Should.Throw<WarningException>(()
=> GetBaseVersion(new GitVersionConfiguration
{
NextVersion = nextVersion,
SemanticVersionFormat = versionFormat
}))
.Message.ShouldBe($"Failed to parse {nextVersion} into a Semantic Version");


private static BaseVersion? GetBaseVersion(GitVersionConfiguration? configuration = null)
{
var contextBuilder = new GitVersionContextBuilder();
Expand Down
2 changes: 1 addition & 1 deletion src/GitVersion.Core/Configuration/Init/SetNextVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected override StepResult HandleResult(string? result, Queue<ConfigInitWizar
return StepResult.Ok();
}

if (!SemanticVersion.TryParse(result, string.Empty, out var semVer))
if (!SemanticVersion.TryParse(result, string.Empty, out var semVer, configuration.SemanticVersionFormat))
return StepResult.InvalidResponseSelected();

configuration.NextVersion = semVer.ToString("t");
Expand Down
6 changes: 3 additions & 3 deletions src/GitVersion.Core/Core/Abstractions/IRepositoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public interface IRepositoryStore

IEnumerable<IBranch> GetSourceBranches(IBranch branch, GitVersionConfiguration configuration, IEnumerable<IBranch> excludedBranches);

SemanticVersion? GetCurrentCommitTaggedVersion(ICommit? commit, string? tagPrefix, bool handleDetachedBranch);
SemanticVersion? GetCurrentCommitTaggedVersion(ICommit? commit, string? tagPrefix, SemanticVersionFormat versionFormat, bool handleDetachedBranch);

IEnumerable<SemanticVersion> GetVersionTagsOnBranch(IBranch branch, string? tagPrefixRegex);
IEnumerable<(ITag Tag, SemanticVersion Semver, ICommit Commit)> GetValidVersionTags(string? tagPrefixRegex, DateTimeOffset? olderThan = null);
IEnumerable<SemanticVersion> GetVersionTagsOnBranch(IBranch branch, string? tagPrefixRegex, SemanticVersionFormat versionFormat);
IEnumerable<(ITag Tag, SemanticVersion Semver, ICommit Commit)> GetValidVersionTags(string? tagPrefixRegex, SemanticVersionFormat versionFormat, DateTimeOffset? olderThan = null);

bool IsCommitOnBranch(ICommit? baseVersionSource, IBranch branch, ICommit firstMatchingCommit);

Expand Down
2 changes: 1 addition & 1 deletion src/GitVersion.Core/Core/GitVersionContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public GitVersionContext Create(GitVersionOptions gitVersionOptions)
currentBranch = branchForCommit ?? currentBranch;
}

var currentCommitTaggedVersion = this.repositoryStore.GetCurrentCommitTaggedVersion(currentCommit, configuration.LabelPrefix, handleDetachedBranch: currentBranch.IsDetachedHead);
var currentCommitTaggedVersion = this.repositoryStore.GetCurrentCommitTaggedVersion(currentCommit, configuration.LabelPrefix, configuration.SemanticVersionFormat, handleDetachedBranch: currentBranch.IsDetachedHead);
var numberOfUncommittedChanges = this.repositoryStore.GetNumberOfUncommittedChanges();

return new GitVersionContext(currentBranch, currentCommit, configuration, currentCommitTaggedVersion, numberOfUncommittedChanges);
Expand Down
20 changes: 10 additions & 10 deletions src/GitVersion.Core/Core/RepositoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,24 +219,24 @@ public IEnumerable<BranchCommit> FindCommitBranchesWasBranchedFrom(IBranch branc
}
}

public SemanticVersion? GetCurrentCommitTaggedVersion(ICommit? commit, string? tagPrefix, bool handleDetachedBranch)
public SemanticVersion? GetCurrentCommitTaggedVersion(ICommit? commit, string? tagPrefix, SemanticVersionFormat versionFormat, bool handleDetachedBranch)
=> this.repository.Tags
.SelectMany(t => GetCurrentCommitSemanticVersions(commit, tagPrefix, t, handleDetachedBranch))
.SelectMany(tag => GetCurrentCommitSemanticVersions(commit, tagPrefix, tag, versionFormat, handleDetachedBranch))
.Max();

public IEnumerable<SemanticVersion> GetVersionTagsOnBranch(IBranch branch, string? tagPrefixRegex)
public IEnumerable<SemanticVersion> GetVersionTagsOnBranch(IBranch branch, string? tagPrefixRegex, SemanticVersionFormat versionFormat)
{
branch = branch.NotNull();

if (this.semanticVersionTagsOnBranchCache.ContainsKey(branch))
if (this.semanticVersionTagsOnBranchCache.TryGetValue(branch, out var onBranch))
{
this.log.Debug($"Cache hit for version tags on branch '{branch.Name.Canonical}");
return this.semanticVersionTagsOnBranchCache[branch];
return onBranch;
}

using (this.log.IndentLog($"Getting version tags from branch '{branch.Name.Canonical}'."))
{
var tags = GetValidVersionTags(tagPrefixRegex);
var tags = GetValidVersionTags(tagPrefixRegex, versionFormat);
var tagsBySha = tags.Where(t => t.Tag.TargetSha != null).ToLookup(t => t.Tag.TargetSha, t => t);

var versionTags = (branch.Commits?.SelectMany(c => tagsBySha[c.Sha].Select(t => t.Semver)) ?? Enumerable.Empty<SemanticVersion>()).ToList();
Expand All @@ -246,13 +246,13 @@ public IEnumerable<SemanticVersion> GetVersionTagsOnBranch(IBranch branch, strin
}
}

public IEnumerable<(ITag Tag, SemanticVersion Semver, ICommit Commit)> GetValidVersionTags(string? tagPrefixRegex, DateTimeOffset? olderThan = null)
public IEnumerable<(ITag Tag, SemanticVersion Semver, ICommit Commit)> GetValidVersionTags(string? tagPrefixRegex, SemanticVersionFormat versionFormat, DateTimeOffset? olderThan = null)
{
var tags = new List<(ITag, SemanticVersion, ICommit)>();

foreach (var tag in this.repository.Tags)
{
if (!SemanticVersion.TryParse(tag.Name.Friendly, tagPrefixRegex, out var semver))
if (!SemanticVersion.TryParse(tag.Name.Friendly, tagPrefixRegex, out var semver, versionFormat))
continue;

var commit = tag.PeeledTargetCommit();
Expand Down Expand Up @@ -290,7 +290,7 @@ public bool IsCommitOnBranch(ICommit? baseVersionSource, IBranch branch, ICommit
private static bool IsReleaseBranch(INamedReference branch, IEnumerable<KeyValuePair<string, BranchConfiguration>> releaseBranchConfig)
=> releaseBranchConfig.Any(c => c.Value?.Regex != null && Regex.IsMatch(branch.Name.Friendly, c.Value.Regex));

private IEnumerable<SemanticVersion> GetCurrentCommitSemanticVersions(ICommit? commit, string? tagPrefix, ITag tag, bool handleDetachedBranch)
private IEnumerable<SemanticVersion> GetCurrentCommitSemanticVersions(ICommit? commit, string? tagPrefix, ITag tag, SemanticVersionFormat versionFormat, bool handleDetachedBranch)
{
if (commit == null)
return Array.Empty<SemanticVersion>();
Expand All @@ -303,7 +303,7 @@ private IEnumerable<SemanticVersion> GetCurrentCommitSemanticVersions(ICommit? c

var tagName = tag.Name.Friendly;

return Equals(targetCommit, commitToCompare) && SemanticVersion.TryParse(tagName, tagPrefix, out var version)
return Equals(targetCommit, commitToCompare) && SemanticVersion.TryParse(tagName, tagPrefix, out var version, versionFormat)
? new[] { version }
: Array.Empty<SemanticVersion>();
}
Expand Down
34 changes: 17 additions & 17 deletions src/GitVersion.Core/MergeMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,25 @@ public MergeMessage(string? mergeMessage, GitVersionConfiguration configuration)
foreach (var format in allFormats)
{
var match = format.Pattern.Match(mergeMessage);
if (match.Success)
{
FormatName = format.Name;
MergedBranch = match.Groups["SourceBranch"].Value;

if (match.Groups["TargetBranch"].Success)
{
TargetBranch = match.Groups["TargetBranch"].Value;
}
if (!match.Success)
continue;

if (int.TryParse(match.Groups["PullRequestNumber"].Value, out var pullNumber))
{
PullRequestNumber = pullNumber;
}
FormatName = format.Name;
MergedBranch = match.Groups["SourceBranch"].Value;

Version = ParseVersion(configuration.LabelPrefix);
if (match.Groups["TargetBranch"].Success)
{
TargetBranch = match.Groups["TargetBranch"].Value;
}

break;
if (int.TryParse(match.Groups["PullRequestNumber"].Value, out var pullNumber))
{
PullRequestNumber = pullNumber;
}

Version = ParseVersion(configuration.LabelPrefix, configuration.SemanticVersionFormat);

break;
}
}

Expand All @@ -58,7 +58,7 @@ public MergeMessage(string? mergeMessage, GitVersionConfiguration configuration)
public int? PullRequestNumber { get; }
public SemanticVersion? Version { get; }

private SemanticVersion? ParseVersion(string? tagPrefix)
private SemanticVersion? ParseVersion(string? tagPrefix, SemanticVersionFormat versionFormat)
{
if (tagPrefix is null)
return null;
Expand All @@ -69,7 +69,7 @@ public MergeMessage(string? mergeMessage, GitVersionConfiguration configuration)
var versionMatch = new Regex(@"^(?<!://)\d+\.\d+(\.*\d+)*");
var version = versionMatch.Match(toMatch);

if (version.Success && SemanticVersion.TryParse(version.Value, tagPrefix, out var val))
if (version.Success && SemanticVersion.TryParse(version.Value, tagPrefix, out var val, versionFormat))
{
return val;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ public ConfigNextVersionVersionStrategy(Lazy<GitVersionContext> versionContext)

public override IEnumerable<BaseVersion> GetBaseVersions(EffectiveBranchConfiguration configuration)
{
var nextVersion = Context.Configuration.NextVersion;
var contextConfiguration = Context.Configuration;
var nextVersion = contextConfiguration.NextVersion;
if (!nextVersion.IsNullOrEmpty() && !Context.IsCurrentCommitTagged)
{
var semanticVersion = SemanticVersion.Parse(nextVersion, Context.Configuration.LabelPrefix);
var semanticVersion = SemanticVersion.Parse(nextVersion, contextConfiguration.LabelPrefix, contextConfiguration.SemanticVersionFormat);
yield return new BaseVersion("NextVersion in GitVersion configuration file", false, semanticVersion, null, null);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ internal IEnumerable<BaseVersion> GetTaggedVersions(IBranch currentBranch, DateT
{
if (currentBranch is null)
return Enumerable.Empty<BaseVersion>();
var versionTags = this.repositoryStore.GetValidVersionTags(Context.Configuration.LabelPrefix, olderThan);
var versionTagsByCommit = versionTags.ToLookup(vt => vt.Item3.Id.Sha);
var versionTags = this.repositoryStore.GetValidVersionTags(Context.Configuration.LabelPrefix, Context.Configuration.SemanticVersionFormat, olderThan);
var versionTagsByCommit = versionTags.ToLookup(vt => vt.Commit.Id.Sha);
var commitsOnBranch = currentBranch.Commits;
if (commitsOnBranch == null)
return Enumerable.Empty<BaseVersion>();

var versionTagsOnBranch = commitsOnBranch.SelectMany(commit => versionTagsByCommit[commit.Id.Sha]);
var versionTaggedCommits = versionTagsOnBranch.Select(t => new VersionTaggedCommit(t.Item3, t.Item2, t.Item1.Name.Friendly));
var versionTaggedCommits = versionTagsOnBranch.Select(t => new VersionTaggedCommit(t.Commit, t.Semver, t.Tag.Name.Friendly));
var taggedVersions = versionTaggedCommits.Select(versionTaggedCommit => CreateBaseVersion(Context, versionTaggedCommit)).ToList();
var taggedVersionsOnCurrentCommit = taggedVersions.Where(version => !version.ShouldIncrement).ToList();
return taggedVersionsOnCurrentCommit.Any() ? taggedVersionsOnCurrentCommit : taggedVersions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@ public VersionInBranchNameVersionStrategy(IRepositoryStore repositoryStore, Lazy
public override IEnumerable<BaseVersion> GetBaseVersions(EffectiveBranchConfiguration configuration)
{
string nameWithoutOrigin = NameWithoutOrigin(configuration.Branch);
if (Context.Configuration.IsReleaseBranch(nameWithoutOrigin))
var contextConfiguration = Context.Configuration;
if (contextConfiguration.IsReleaseBranch(nameWithoutOrigin))
{
var versionInBranch = GetVersionInBranch(configuration.Branch.Name.Friendly, Context.Configuration.LabelPrefix);
var versionInBranch = GetVersionInBranch(configuration.Branch.Name.Friendly, contextConfiguration.LabelPrefix, contextConfiguration.SemanticVersionFormat);
if (versionInBranch != null)
{
var commitBranchWasBranchedFrom = this.repositoryStore.FindCommitBranchWasBranchedFrom(configuration.Branch, Context.Configuration);
var commitBranchWasBranchedFrom = this.repositoryStore.FindCommitBranchWasBranchedFrom(configuration.Branch, contextConfiguration);
var branchNameOverride = Context.CurrentBranch.Name.Friendly.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
yield return new BaseVersion("Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom.Commit, branchNameOverride);
}
}
}

private static Tuple<string, SemanticVersion>? GetVersionInBranch(string branchName, string? tagPrefixRegex)
private static Tuple<string, SemanticVersion>? GetVersionInBranch(string branchName, string? tagPrefixRegex, SemanticVersionFormat versionFormat)
{
var branchParts = branchName.Split('/', '-');
foreach (var part in branchParts)
{
if (SemanticVersion.TryParse(part, tagPrefixRegex, out var semanticVersion))
if (SemanticVersion.TryParse(part, tagPrefixRegex, out var semanticVersion, versionFormat))
{
return Tuple.Create(part, semanticVersion);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private void UpdatePreReleaseTag(EffectiveBranchConfiguration configuration, Sem

// TODO: Please update the pre release-tag in the IVersionStrategy implementation.
var lastTag = this.repositoryStore
.GetVersionTagsOnBranch(Context.CurrentBranch, Context.Configuration.LabelPrefix)
.GetVersionTagsOnBranch(Context.CurrentBranch, Context.Configuration.LabelPrefix, Context.Configuration.SemanticVersionFormat)
.FirstOrDefault(v => v.PreReleaseTag?.Name?.IsEquivalentTo(tagToUse) == true);

if (lastTag != null && MajorMinorPatchEqual(lastTag, semanticVersion) && lastTag.HasPreReleaseTagWithLabel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ public override int GetHashCode()
return v1.CompareTo(v2) < 0;
}

public static SemanticVersion Parse(string version, string? tagPrefixRegex, SemanticVersionFormat format = SemanticVersionFormat.Strict)
public static SemanticVersion Parse(string version, string? tagPrefixRegex, SemanticVersionFormat versionFormat = SemanticVersionFormat.Strict)
{
if (!TryParse(version, tagPrefixRegex, out var semanticVersion, format))
if (!TryParse(version, tagPrefixRegex, out var semanticVersion, versionFormat))
throw new WarningException($"Failed to parse {version} into a Semantic Version");

return semanticVersion;
Expand Down