Skip to content
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
28 changes: 21 additions & 7 deletions src/GitVersion.Core/Configuration/BranchConfigurationCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
using GitVersion.Extensions;
using GitVersion.Logging;
using GitVersion.Model.Configuration;
using GitVersion.Model.Exceptions;

namespace GitVersion.Configuration;

public class BranchConfigurationCalculator : IBranchConfigurationCalculator
{
private const string FallbackConfigName = "Fallback";
private const int MaxRecursions = 50;

private readonly ILog log;
private readonly IRepositoryStore repositoryStore;
Expand All @@ -22,8 +24,16 @@ public BranchConfigurationCalculator(ILog log, IRepositoryStore repositoryStore)
/// <summary>
/// Gets the <see cref="BranchConfig"/> for the current commit.
/// </summary>
public BranchConfig GetBranchConfiguration(IBranch targetBranch, ICommit? currentCommit, Config configuration, IList<IBranch>? excludedInheritBranches = null)
public BranchConfig GetBranchConfiguration(IBranch targetBranch, ICommit? currentCommit, Config configuration, IList<IBranch>? excludedInheritBranches = null) =>
GetBranchConfigurationInternal(0, targetBranch, currentCommit, configuration, excludedInheritBranches);

private BranchConfig GetBranchConfigurationInternal(int recursions, IBranch targetBranch, ICommit? currentCommit, Config configuration, IList<IBranch>? excludedInheritBranches = null)
{
if (recursions >= MaxRecursions)
{
throw new InfiniteLoopProtectionException($"Inherited branch configuration caused {recursions} recursions. Aborting!");
}

var matchingBranches = configuration.GetConfigForBranch(targetBranch.Name.WithoutRemote);

if (matchingBranches == null)
Expand All @@ -41,7 +51,7 @@ public BranchConfig GetBranchConfiguration(IBranch targetBranch, ICommit? curren

if (matchingBranches.Increment == IncrementStrategy.Inherit)
{
matchingBranches = InheritBranchConfiguration(targetBranch, matchingBranches, currentCommit, configuration, excludedInheritBranches);
matchingBranches = InheritBranchConfiguration(recursions, targetBranch, matchingBranches, currentCommit, configuration, excludedInheritBranches);
if (matchingBranches.Name!.IsEquivalentTo(FallbackConfigName) && matchingBranches.Increment == IncrementStrategy.Inherit)
{
// We tried, and failed to inherit, just fall back to patch
Expand All @@ -50,13 +60,16 @@ public BranchConfig GetBranchConfiguration(IBranch targetBranch, ICommit? curren
}

return matchingBranches;

}

// TODO I think we need to take a fresh approach to this.. it's getting really complex with heaps of edge cases
private BranchConfig InheritBranchConfiguration(IBranch targetBranch, BranchConfig branchConfiguration, ICommit? currentCommit, Config configuration, IList<IBranch>? excludedInheritBranches)
private BranchConfig InheritBranchConfiguration(int recursions, IBranch targetBranch, BranchConfig branchConfiguration, ICommit? currentCommit, Config configuration, IList<IBranch>? excludedInheritBranches)
{
using (this.log.IndentLog("Attempting to inherit branch configuration from parent branch"))
{
recursions += 1;

var excludedBranches = new[] { targetBranch };
// Check if we are a merge commit. If so likely we are a pull request
var parentCount = currentCommit?.Parents.Count();
Expand Down Expand Up @@ -106,7 +119,7 @@ private BranchConfig InheritBranchConfiguration(IBranch targetBranch, BranchConf

if (possibleParents.Count == 1)
{
var branchConfig = GetBranchConfiguration(possibleParents[0], currentCommit, configuration, excludedInheritBranches);
var branchConfig = GetBranchConfigurationInternal(recursions, possibleParents[0], currentCommit, configuration, excludedInheritBranches);
// If we have resolved a fallback config we should not return that we have got config
if (branchConfig.Name != FallbackConfigName)
{
Expand Down Expand Up @@ -154,13 +167,14 @@ private BranchConfig InheritBranchConfiguration(IBranch targetBranch, BranchConf
};
}

var inheritingBranchConfig = GetBranchConfiguration(chosenBranch, currentCommit, configuration, excludedInheritBranches)!;
var inheritingBranchConfig = GetBranchConfigurationInternal(recursions, chosenBranch, currentCommit, configuration, excludedInheritBranches)!;
var configIncrement = inheritingBranchConfig.Increment;
if (inheritingBranchConfig.Name!.IsEquivalentTo(FallbackConfigName) && configIncrement == IncrementStrategy.Inherit)
{
this.log.Warning("Fallback config inherits by default, dropping to patch increment");
configIncrement = IncrementStrategy.Patch;
}

return new BranchConfig(branchConfiguration)
{
Increment = configIncrement,
Expand Down Expand Up @@ -212,8 +226,8 @@ private IBranch[] CalculateWhenMultipleParents(ICommit currentCommit, ref IBranc
private static BranchConfig? ChooseMainOrDevelopIncrementStrategyIfTheChosenBranchIsOneOfThem(IBranch chosenBranch, BranchConfig branchConfiguration, Config config)
{
BranchConfig? mainOrDevelopConfig = null;
var developBranchRegex = config.Branches[Config.DevelopBranchKey]?.Regex;
var mainBranchRegex = config.Branches[Config.MainBranchKey]?.Regex;
var developBranchRegex = config.Branches[Config.DevelopBranchKey]?.Regex ?? Config.DevelopBranchRegex;
var mainBranchRegex = config.Branches[Config.MainBranchKey]?.Regex ?? Config.MainBranchRegex;
if (Regex.IsMatch(chosenBranch.Name.Friendly, developBranchRegex, RegexOptions.IgnoreCase))
{
// Normally we would not expect this to happen but for safety we add a check
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace GitVersion.Model.Exceptions
{
public class InfiniteLoopProtectionException : Exception
{
public InfiniteLoopProtectionException(string messageFormat)
: base(messageFormat)
{
}
}
}