1
+ using System . Collections . Concurrent ;
1
2
using System . Collections . Generic ;
2
3
using System . Linq ;
3
4
using System . Text . RegularExpressions ;
@@ -23,6 +24,11 @@ public static class IncrementStrategyFinder
23
24
public const string DefaultPatchPattern = @"\+semver:\s?(fix|patch)" ;
24
25
public const string DefaultNoBumpPattern = @"\+semver:\s?(none|skip)" ;
25
26
27
+ private static readonly Regex DefaultMajorPatternRegex = new Regex ( DefaultMajorPattern , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
28
+ private static readonly Regex DefaultMinorPatternRegex = new Regex ( DefaultMinorPattern , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
29
+ private static readonly Regex DefaultPatchPatternRegex = new Regex ( DefaultPatchPattern , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
30
+ private static readonly Regex DefaultNoBumpPatternRegex = new Regex ( DefaultNoBumpPattern , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
31
+
26
32
public static VersionField ? DetermineIncrementedField ( GitVersionContext context , BaseVersion baseVersion )
27
33
{
28
34
var commitMessageIncrement = FindCommitMessageIncrement ( context , baseVersion ) ;
@@ -69,13 +75,10 @@ public static class IncrementStrategyFinder
69
75
70
76
public static VersionField ? GetIncrementForCommits ( GitVersionContext context , IEnumerable < Commit > commits )
71
77
{
72
- // More efficient use of Regexes. The static version of Regex.IsMatch caches the compiled regexes.
73
- // see: https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices#static-regular-expressions
74
-
75
- var majorRegex = context . Configuration . MajorVersionBumpMessage ?? DefaultMajorPattern ;
76
- var minorRegex = context . Configuration . MinorVersionBumpMessage ?? DefaultMinorPattern ;
77
- var patchRegex = context . Configuration . PatchVersionBumpMessage ?? DefaultPatchPattern ;
78
- var none = context . Configuration . NoBumpMessage ?? DefaultNoBumpPattern ;
78
+ var majorRegex = TryGetRegexOrDefault ( context . Configuration . MajorVersionBumpMessage , DefaultMajorPatternRegex ) ;
79
+ var minorRegex = TryGetRegexOrDefault ( context . Configuration . MinorVersionBumpMessage , DefaultMinorPatternRegex ) ;
80
+ var patchRegex = TryGetRegexOrDefault ( context . Configuration . PatchVersionBumpMessage , DefaultPatchPatternRegex ) ;
81
+ var none = TryGetRegexOrDefault ( context . Configuration . NoBumpMessage , DefaultNoBumpPatternRegex ) ;
79
82
80
83
var increments = commits
81
84
. Select ( c => GetIncrementFromMessage ( c . Message , majorRegex , minorRegex , patchRegex , none ) )
@@ -91,23 +94,36 @@ public static class IncrementStrategyFinder
91
94
return null ;
92
95
}
93
96
97
+ private static Regex TryGetRegexOrDefault ( string messageRegex , Regex defaultRegex )
98
+ {
99
+ if ( messageRegex == null )
100
+ {
101
+ return defaultRegex ;
102
+ }
103
+
104
+ return CompiledRegexCache . GetOrAdd ( messageRegex , pattern => new Regex ( pattern , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ) ;
105
+ }
106
+
94
107
private static IEnumerable < Commit > GetIntermediateCommits ( IRepository repo , Commit baseCommit , Commit headCommit )
95
108
{
96
109
if ( baseCommit == null ) yield break ;
97
110
98
- if ( intermediateCommitCache == null || intermediateCommitCache . LastOrDefault ( ) != headCommit )
111
+ var commitCache = intermediateCommitCache ;
112
+
113
+ if ( commitCache == null || commitCache . LastOrDefault ( ) != headCommit )
99
114
{
100
115
var filter = new CommitFilter
101
116
{
102
117
IncludeReachableFrom = headCommit ,
103
118
SortBy = CommitSortStrategies . Topological | CommitSortStrategies . Reverse
104
119
} ;
105
120
106
- intermediateCommitCache = repo . Commits . QueryBy ( filter ) . ToList ( ) ;
121
+ commitCache = repo . Commits . QueryBy ( filter ) . ToList ( ) ;
122
+ intermediateCommitCache = commitCache ;
107
123
}
108
124
109
125
var found = false ;
110
- foreach ( var commit in intermediateCommitCache )
126
+ foreach ( var commit in commitCache )
111
127
{
112
128
if ( found )
113
129
yield return commit ;
@@ -117,41 +133,16 @@ private static IEnumerable<Commit> GetIntermediateCommits(IRepository repo, Comm
117
133
}
118
134
}
119
135
120
- private static VersionField ? GetIncrementFromMessage ( string message , string majorRegex , string minorRegex , string patchRegex , string none )
136
+ private static VersionField ? GetIncrementFromMessage ( string message , Regex majorRegex , Regex minorRegex , Regex patchRegex , Regex none )
121
137
{
122
- var key = message . GetHashCode ( ) ;
123
-
124
- if ( ! VersionFieldCache . TryGetValue ( key , out var version ) )
125
- {
126
- version = FindIncrementFromMessage ( message , majorRegex , minorRegex , patchRegex , none ) ;
127
- VersionFieldCache [ key ] = version ;
128
- }
129
- return version ;
130
- }
131
-
132
- private static VersionField ? FindIncrementFromMessage ( string message , string majorRegex , string minorRegex , string patchRegex , string noneRegex )
133
- {
134
- if ( IsMatch ( message , majorRegex ) ) return VersionField . Major ;
135
- if ( IsMatch ( message , minorRegex ) ) return VersionField . Minor ;
136
- if ( IsMatch ( message , patchRegex ) ) return VersionField . Patch ;
137
- if ( IsMatch ( message , noneRegex ) ) return VersionField . None ;
138
+ if ( majorRegex . IsMatch ( message ) ) return VersionField . Major ;
139
+ if ( minorRegex . IsMatch ( message ) ) return VersionField . Minor ;
140
+ if ( patchRegex . IsMatch ( message ) ) return VersionField . Patch ;
141
+ if ( none . IsMatch ( message ) ) return VersionField . None ;
138
142
return null ;
139
143
}
140
144
141
- private static bool IsMatch ( string message , string regex )
142
- {
143
- var key = message . GetHashCode ( ) ^ regex . GetHashCode ( ) ;
144
-
145
- if ( ! MatchCache . TryGetValue ( key , out var match ) )
146
- {
147
- match = Regex . IsMatch ( message , regex , RegexOptions . IgnoreCase ) ;
148
- MatchCache [ key ] = match ;
149
- }
150
- return match ;
151
- }
152
-
153
- private static readonly IDictionary < int , bool > MatchCache = new Dictionary < int , bool > ( ) ;
154
- private static readonly IDictionary < int , VersionField ? > VersionFieldCache = new Dictionary < int , VersionField ? > ( ) ;
145
+ private static readonly ConcurrentDictionary < string , Regex > CompiledRegexCache = new ConcurrentDictionary < string , Regex > ( ) ;
155
146
156
147
public static VersionField FindDefaultIncrementForBranch ( GitVersionContext context , string branch = null )
157
148
{
0 commit comments