Skip to content

Commit 7ed1c09

Browse files
authored
Merge pull request #3845 from HHobeck/feature/Replace-the-version-mode-Mainline-Part-I.B
Replace the version mode Mainline in 6.x (Part I.B)
2 parents 4157e11 + 37c67fe commit 7ed1c09

40 files changed

+1278
-56
lines changed

src/GitVersion.Core/Core/ITaggedSemanticVersionRepository.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ namespace GitVersion.Core;
44

55
internal interface ITaggedSemanticVersionRepository
66
{
7-
ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersions(IBranch branch, EffectiveConfiguration configuration);
8-
9-
ILookup<ICommit, SemanticVersionWithTag> GetAllTaggedSemanticVersions(string? tagPrefix, SemanticVersionFormat format);
7+
ILookup<ICommit, SemanticVersionWithTag> GetAllTaggedSemanticVersions(IBranch branch, EffectiveConfiguration configuration);
108

119
ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfBranch(
1210
IBranch branch,

src/GitVersion.Core/Core/TaggedSemanticVersionService.cs renamed to src/GitVersion.Core/Core/TaggedSemanticVersionRepository.cs

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ namespace GitVersion.Core;
77

88
internal sealed class TaggedSemanticVersionRepository : ITaggedSemanticVersionRepository
99
{
10+
private readonly ConcurrentDictionary<(IBranch, string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
11+
taggedSemanticVersionsOfBranchCache = new();
12+
private readonly ConcurrentDictionary<(IBranch, string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
13+
taggedSemanticVersionsOfMergeTargetCache = new();
14+
private readonly ConcurrentDictionary<(string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
15+
taggedSemanticVersionsCache = new();
1016
private readonly ILog log;
1117

1218
private GitVersionContext VersionContext => this.versionContextLazy.Value;
@@ -24,7 +30,7 @@ public TaggedSemanticVersionRepository(ILog log, Lazy<GitVersionContext> version
2430
this.branchRepository = branchRepository.NotNull();
2531
}
2632

27-
public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersions(IBranch branch, EffectiveConfiguration configuration)
33+
public ILookup<ICommit, SemanticVersionWithTag> GetAllTaggedSemanticVersions(IBranch branch, EffectiveConfiguration configuration)
2834
{
2935
configuration.NotNull();
3036

@@ -102,47 +108,9 @@ public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersions(IBranc
102108
}
103109
}
104110

105-
return GetElements().ToLookup(element => element.Key, element => element.Value);
106-
}
107-
108-
private readonly ConcurrentDictionary<(string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
109-
allTaggedSemanticVersionsCache = new();
110-
111-
public ILookup<ICommit, SemanticVersionWithTag> GetAllTaggedSemanticVersions(string? tagPrefix, SemanticVersionFormat format)
112-
{
113-
tagPrefix ??= string.Empty;
114-
115-
IEnumerable<SemanticVersionWithTag> GetElements()
116-
{
117-
this.log.Info($"Getting tagged semantic versions. TagPrefix: {tagPrefix} and Format: {format}");
118-
119-
foreach (var tag in this.gitRepository.Tags)
120-
{
121-
if (SemanticVersion.TryParse(tag.Name.Friendly, tagPrefix, out var semanticVersion, format))
122-
{
123-
yield return new SemanticVersionWithTag(semanticVersion, tag);
124-
}
125-
}
126-
}
127-
128-
bool isCached = true;
129-
var result = allTaggedSemanticVersionsCache.GetOrAdd(new(tagPrefix, format), _ =>
130-
{
131-
isCached = false;
132-
return GetElements().ToLookup(element => element.Tag.Commit, element => element);
133-
});
134-
135-
if (isCached)
136-
{
137-
this.log.Debug($"Returning cached tagged semantic versions. TagPrefix: {tagPrefix} and Format: {format}");
138-
}
139-
140-
return result;
111+
return GetElements().Distinct().ToLookup(element => element.Key, element => element.Value);
141112
}
142113

143-
private readonly ConcurrentDictionary<(IBranch, string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
144-
taggedSemanticVersionsOfBranchCache = new();
145-
146114
public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfBranch(
147115
IBranch branch, string? tagPrefix, SemanticVersionFormat format)
148116
{
@@ -154,8 +122,7 @@ IEnumerable<SemanticVersionWithTag> GetElements()
154122
using (this.log.IndentLog($"Getting tagged semantic versions on branch '{branch.Name.Canonical}'. " +
155123
$"TagPrefix: {tagPrefix} and Format: {format}"))
156124
{
157-
var semanticVersions = GetAllTaggedSemanticVersions(tagPrefix, format);
158-
125+
var semanticVersions = GetTaggedSemanticVersions(tagPrefix, format);
159126
foreach (var commit in branch.Commits)
160127
{
161128
foreach (var semanticVersion in semanticVersions[commit])
@@ -170,8 +137,7 @@ IEnumerable<SemanticVersionWithTag> GetElements()
170137
var result = taggedSemanticVersionsOfBranchCache.GetOrAdd(new(branch, tagPrefix, format), _ =>
171138
{
172139
isCached = false;
173-
var semanticVersions = GetElements();
174-
return semanticVersions.ToLookup(element => element.Tag.Commit, element => element);
140+
return GetElements().Distinct().ToLookup(element => element.Tag.Commit, element => element);
175141
});
176142

177143
if (isCached)
@@ -185,9 +151,6 @@ IEnumerable<SemanticVersionWithTag> GetElements()
185151
return result;
186152
}
187153

188-
private readonly ConcurrentDictionary<(IBranch, string, SemanticVersionFormat), ILookup<ICommit, SemanticVersionWithTag>>
189-
taggedSemanticVersionsOfMergeTargetCache = new();
190-
191154
public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfMergeTarget(
192155
IBranch branch, string? tagPrefix, SemanticVersionFormat format)
193156
{
@@ -201,7 +164,7 @@ public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfMerge
201164
{
202165
var shaHashSet = new HashSet<string>(branch.Commits.Select(element => element.Id.Sha));
203166

204-
foreach (var semanticVersion in GetAllTaggedSemanticVersions(tagPrefix, format).SelectMany(_ => _))
167+
foreach (var semanticVersion in GetTaggedSemanticVersions(tagPrefix, format).SelectMany(_ => _))
205168
{
206169
foreach (var commit in semanticVersion.Tag.Commit.Parents.Where(element => shaHashSet.Contains(element.Id.Sha)))
207170
{
@@ -215,7 +178,7 @@ public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfMerge
215178
var result = taggedSemanticVersionsOfMergeTargetCache.GetOrAdd(new(branch, tagPrefix, format), _ =>
216179
{
217180
isCached = false;
218-
return GetElements().ToLookup(element => element.Item1, element => element.Item2);
181+
return GetElements().Distinct().ToLookup(element => element.Item1, element => element.Item2);
219182
});
220183

221184
if (isCached)
@@ -250,7 +213,7 @@ IEnumerable<SemanticVersionWithTag> GetElements()
250213
}
251214
}
252215

253-
return GetElements().ToLookup(element => element.Tag.Commit, element => element);
216+
return GetElements().Distinct().ToLookup(element => element.Tag.Commit, element => element);
254217
}
255218

256219
public ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersionsOfReleaseBranches(
@@ -274,6 +237,38 @@ IEnumerable<SemanticVersionWithTag> GetElements()
274237
}
275238
}
276239

277-
return GetElements().ToLookup(element => element.Tag.Commit, element => element);
240+
return GetElements().Distinct().ToLookup(element => element.Tag.Commit, element => element);
241+
}
242+
243+
private ILookup<ICommit, SemanticVersionWithTag> GetTaggedSemanticVersions(string? tagPrefix, SemanticVersionFormat format)
244+
{
245+
tagPrefix ??= string.Empty;
246+
247+
IEnumerable<SemanticVersionWithTag> GetElements()
248+
{
249+
this.log.Info($"Getting tagged semantic versions. TagPrefix: {tagPrefix} and Format: {format}");
250+
251+
foreach (var tag in this.gitRepository.Tags)
252+
{
253+
if (SemanticVersion.TryParse(tag.Name.Friendly, tagPrefix, out var semanticVersion, format))
254+
{
255+
yield return new SemanticVersionWithTag(semanticVersion, tag);
256+
}
257+
}
258+
}
259+
260+
bool isCached = true;
261+
var result = taggedSemanticVersionsCache.GetOrAdd(new(tagPrefix, format), _ =>
262+
{
263+
isCached = false;
264+
return GetElements().ToLookup(element => element.Tag.Commit, element => element);
265+
});
266+
267+
if (isCached)
268+
{
269+
this.log.Debug($"Returning cached tagged semantic versions. TagPrefix: {tagPrefix} and Format: {format}");
270+
}
271+
272+
return result;
278273
}
279274
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using GitVersion.Configuration;
2+
using GitVersion.Extensions;
3+
4+
namespace GitVersion.VersionCalculation.TrunkBased;
5+
6+
internal sealed class EnrichIncrement : ITrunkBasedContextPreEnricher
7+
{
8+
public void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
9+
{
10+
var incrementForcedByBranch = commit.GetIncrementForcedByBranch();
11+
var incrementForcedByCommit = commit.Increment;
12+
context.Increment = context.Increment.Consolidate(incrementForcedByBranch, incrementForcedByCommit);
13+
14+
if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName)
15+
context.Label = null;
16+
context.Label ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null);
17+
18+
if (commit.Configuration.IsMainline)
19+
context.BaseVersionSource = commit.Predecessor?.Value;
20+
context.ForceIncrement |= commit.Configuration.IsMainline || commit.IsPredecessorTheLastCommitOnTrunk;
21+
}
22+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using GitVersion.Configuration;
2+
using GitVersion.Extensions;
3+
4+
namespace GitVersion.VersionCalculation.TrunkBased;
5+
6+
internal sealed class EnrichSemanticVersion : ITrunkBasedContextPreEnricher
7+
{
8+
public void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
9+
{
10+
var branchSpecificLabel = context.TargetLabel;
11+
branchSpecificLabel ??= iteration.Configuration.GetBranchSpecificLabel(commit.BranchName, null);
12+
branchSpecificLabel ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null);
13+
14+
var semanticVersions = commit.SemanticVersions.Where(
15+
element => element.IsMatchForBranchSpecificLabel(branchSpecificLabel)
16+
).ToList();
17+
context.AlternativeSemanticVersions.AddRange(commit.SemanticVersions.Except(semanticVersions));
18+
context.SemanticVersion = semanticVersions.Max();
19+
}
20+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace GitVersion.VersionCalculation.TrunkBased;
2+
3+
internal interface ITrunkBasedContextPostEnricher
4+
{
5+
void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context);
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace GitVersion.VersionCalculation.TrunkBased;
2+
3+
internal interface ITrunkBasedContextPreEnricher
4+
{
5+
void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context);
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace GitVersion.VersionCalculation.TrunkBased;
2+
3+
internal interface ITrunkBasedIncrementer
4+
{
5+
bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context);
6+
7+
IEnumerable<BaseVersionV2> GetIncrements(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context);
8+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using GitVersion.Configuration;
2+
3+
namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk;
4+
5+
internal sealed class CommitOnNonTrunk : ITrunkBasedIncrementer
6+
{
7+
// B 57 minutes ago (HEAD -> feature/foo)
8+
// A 58 minutes ago <<--
9+
10+
// B 57 minutes ago (HEAD -> feature/foo) <<--
11+
// A 58 minutes ago
12+
13+
public bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
14+
=> commit.ChildIteration is null && !commit.Configuration.IsMainline && context.SemanticVersion is null;
15+
16+
public IEnumerable<BaseVersionV2> GetIncrements(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
17+
{
18+
if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName)
19+
context.Label = null;
20+
context.Label ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null);
21+
22+
if (commit.Successor is null)
23+
{
24+
yield return BaseVersionV2.ShouldIncrementTrue(
25+
source: GetType().Name,
26+
baseVersionSource: context.BaseVersionSource,
27+
increment: context.Increment,
28+
label: context.Label,
29+
forceIncrement: context.ForceIncrement,
30+
alternativeSemanticVersion: context.AlternativeSemanticVersions.Max()
31+
);
32+
33+
context.BaseVersionSource = commit.Value;
34+
}
35+
}
36+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using GitVersion.Configuration;
2+
using GitVersion.Extensions;
3+
4+
namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk;
5+
6+
internal abstract class CommitOnNonTrunkBranchedBase : ITrunkBasedIncrementer
7+
{
8+
public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
9+
=> !commit.Configuration.IsMainline && commit.BranchName != iteration.BranchName && commit.Successor is null;
10+
11+
public virtual IEnumerable<BaseVersionV2> GetIncrements(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
12+
{
13+
context.BaseVersionSource = commit.Value;
14+
15+
var incrementForcedByBranch = iteration.Configuration.Increment == IncrementStrategy.Inherit
16+
? commit.GetIncrementForcedByBranch() : iteration.Configuration.Increment.ToVersionField();
17+
context.Increment = context.Increment.Consolidate(incrementForcedByBranch);
18+
19+
context.Label = iteration.Configuration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label;
20+
context.ForceIncrement = true;
21+
22+
yield return BaseVersionV2.ShouldIncrementFalse(
23+
source: GetType().Name,
24+
baseVersionSource: null,
25+
label: context.Label,
26+
alternativeSemanticVersion: context.AlternativeSemanticVersions.Max()
27+
);
28+
}
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk;
2+
3+
internal sealed class CommitOnNonTrunkBranchedToNonTrunk : CommitOnNonTrunkBranchedBase
4+
{
5+
// B 51 minutes ago (HEAD -> feature/foo, main) <<--
6+
// A 59 minutes ago
7+
8+
// B 58 minutes ago (main)
9+
// A 59 minutes ago (HEAD -> feature/foo) <<--
10+
11+
// * 54 minutes ago (main)
12+
// | B 56 minutes ago (HEAD -> feature/foo)
13+
// |/
14+
// A 58 minutes ago <<--
15+
16+
public override bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context)
17+
=> base.MatchPrecondition(iteration, commit, context) && !iteration.Configuration.IsMainline;
18+
}

0 commit comments

Comments
 (0)