Skip to content

Commit cfd89e2

Browse files
CopilotMalcolmnixon
andcommitted
Update TagInfo regex to accept both dot and hyphen as pre-release separators with build metadata support
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
1 parent ce13ed4 commit cfd89e2

File tree

2 files changed

+83
-12
lines changed

2 files changed

+83
-12
lines changed

src/DemaConsulting.BuildMark/TagInfo.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,15 @@ namespace DemaConsulting.BuildMark;
3131
public partial record TagInfo(string Tag, string FullVersion, bool IsPreRelease)
3232
{
3333
/// <summary>
34-
/// Regex pattern for parsing version tags with optional prefix and pre-release suffix.
34+
/// Regex pattern for parsing version tags with optional prefix, pre-release, and build metadata.
35+
/// Format: [prefix]major.minor.patch[.|-)prerelease][+buildmetadata]
36+
/// Accepts both dot and hyphen as pre-release separators.
37+
/// Examples:
38+
/// - Rel_1.2.3.rc.4+build.5 -> version: 1.2.3, prerelease: rc.4, metadata: build.5
39+
/// - v2.0.0-alpha.1 -> version: 2.0.0, prerelease: alpha.1
3540
/// </summary>
3641
/// <returns>Compiled regex for parsing tags.</returns>
37-
[GeneratedRegex(@"^(?:[a-zA-Z_-]+)?(?<version>\d+\.\d+\.\d+)(?:-(?<pre_release>[a-zA-Z0-9.-]+))?(?:\.(?<metadata>[a-zA-Z0-9.-]+))?$")]
42+
[GeneratedRegex(@"^(?:[a-zA-Z_-]+)?(?<version>\d+\.\d+\.\d+)(?<separator>[-.])?(?<pre_release>[a-zA-Z0-9.-]+?)?(?:\+(?<metadata>[a-zA-Z0-9.-]+))?$")]
3843
private static partial Regex TagPattern();
3944

4045
/// <summary>
@@ -51,22 +56,24 @@ public partial record TagInfo(string Tag, string FullVersion, bool IsPreRelease)
5156
}
5257

5358
var version = match.Groups["version"].Value;
59+
var separator = match.Groups["separator"];
5460
var preRelease = match.Groups["pre_release"];
5561
var metadata = match.Groups["metadata"];
5662

57-
// Build full version: version + optional pre-release + optional metadata
63+
// Pre-release exists if separator is present and pre-release group has content
64+
var hasPreRelease = separator.Success && preRelease.Success && !string.IsNullOrEmpty(preRelease.Value);
65+
66+
// Build full version: version + optional pre-release + optional build metadata
5867
var fullVersion = version;
59-
if (preRelease.Success)
68+
if (hasPreRelease)
6069
{
61-
fullVersion += $"-{preRelease.Value}";
70+
fullVersion += $"{separator.Value}{preRelease.Value}";
6271
}
6372
if (metadata.Success)
6473
{
65-
fullVersion += $".{metadata.Value}";
74+
fullVersion += $"+{metadata.Value}";
6675
}
67-
68-
var isPreRelease = preRelease.Success;
6976

70-
return new TagInfo(tag, fullVersion, isPreRelease);
77+
return new TagInfo(tag, fullVersion, hasPreRelease);
7178
}
7279
}

test/DemaConsulting.BuildMark.Tests/TagInfoTests.cs

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,26 @@ public void TagInfo_Constructor_HandlesComplexPrefix()
171171
}
172172

173173
/// <summary>
174-
/// Test that TagInfo does not falsely detect rc in words like 'arch'.
174+
/// Test that TagInfo correctly parses build metadata with plus separator.
175175
/// </summary>
176176
[TestMethod]
177-
public void TagInfo_Constructor_DoesNotFalselyDetectRcInArch()
177+
public void TagInfo_Constructor_ParsesBuildMetadata()
178+
{
179+
// Arrange & Act
180+
var tagVersion = TagInfo.Create("v1.0.0+arch");
181+
Assert.IsNotNull(tagVersion);
182+
183+
// Assert
184+
Assert.AreEqual("v1.0.0+arch", tagVersion.Tag);
185+
Assert.AreEqual("1.0.0+arch", tagVersion.FullVersion);
186+
Assert.IsFalse(tagVersion.IsPreRelease);
187+
}
188+
189+
/// <summary>
190+
/// Test that TagInfo accepts dot-separated pre-release and treats it as pre-release.
191+
/// </summary>
192+
[TestMethod]
193+
public void TagInfo_Constructor_AcceptsDotSeparatedAsPreRelease()
178194
{
179195
// Arrange & Act
180196
var tagVersion = TagInfo.Create("v1.0.0.arch");
@@ -183,7 +199,39 @@ public void TagInfo_Constructor_DoesNotFalselyDetectRcInArch()
183199
// Assert
184200
Assert.AreEqual("v1.0.0.arch", tagVersion.Tag);
185201
Assert.AreEqual("1.0.0.arch", tagVersion.FullVersion);
186-
Assert.IsFalse(tagVersion.IsPreRelease);
202+
Assert.IsTrue(tagVersion.IsPreRelease);
203+
}
204+
205+
/// <summary>
206+
/// Test that TagInfo correctly parses complex version with prefix, pre-release, and metadata.
207+
/// </summary>
208+
[TestMethod]
209+
public void TagInfo_Constructor_ParsesComplexVersionWithMetadata()
210+
{
211+
// Arrange & Act
212+
var tagVersion = TagInfo.Create("Rel_1.2.3.rc.4+build.5");
213+
Assert.IsNotNull(tagVersion);
214+
215+
// Assert
216+
Assert.AreEqual("Rel_1.2.3.rc.4+build.5", tagVersion.Tag);
217+
Assert.AreEqual("1.2.3.rc.4+build.5", tagVersion.FullVersion);
218+
Assert.IsTrue(tagVersion.IsPreRelease);
219+
}
220+
221+
/// <summary>
222+
/// Test that TagInfo correctly parses complex version with hyphen separator for pre-release.
223+
/// </summary>
224+
[TestMethod]
225+
public void TagInfo_Constructor_ParsesComplexVersionWithHyphenPreRelease()
226+
{
227+
// Arrange & Act
228+
var tagVersion = TagInfo.Create("Rel_1.2.3-rc.4+build.5");
229+
Assert.IsNotNull(tagVersion);
230+
231+
// Assert
232+
Assert.AreEqual("Rel_1.2.3-rc.4+build.5", tagVersion.Tag);
233+
Assert.AreEqual("1.2.3-rc.4+build.5", tagVersion.FullVersion);
234+
Assert.IsTrue(tagVersion.IsPreRelease);
187235
}
188236

189237
/// <summary>
@@ -201,4 +249,20 @@ public void TagInfo_Constructor_CorrectlyDetectsRcWithNumber()
201249
Assert.AreEqual("1.0.0-rc1", tagVersion.FullVersion);
202250
Assert.IsTrue(tagVersion.IsPreRelease);
203251
}
252+
253+
/// <summary>
254+
/// Test that TagInfo correctly parses pre-release with build metadata.
255+
/// </summary>
256+
[TestMethod]
257+
public void TagInfo_Constructor_ParsesPreReleaseWithBuildMetadata()
258+
{
259+
// Arrange & Act
260+
var tagVersion = TagInfo.Create("v2.0.0-beta.1+linux.x64");
261+
Assert.IsNotNull(tagVersion);
262+
263+
// Assert
264+
Assert.AreEqual("v2.0.0-beta.1+linux.x64", tagVersion.Tag);
265+
Assert.AreEqual("2.0.0-beta.1+linux.x64", tagVersion.FullVersion);
266+
Assert.IsTrue(tagVersion.IsPreRelease);
267+
}
204268
}

0 commit comments

Comments
 (0)