Skip to content

Commit b2c6b32

Browse files
CopilotMalcolmnixon
andcommitted
Rename TagInfo to Version, add SemanticVersion/PreRelease/Metadata properties, update API parameters
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
1 parent cfd89e2 commit b2c6b32

File tree

10 files changed

+146
-137
lines changed

10 files changed

+146
-137
lines changed

src/DemaConsulting.BuildMark/BuildInformation.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public record IssueInfo(string Id, string Title, string Url);
3939
/// <param name="BugIssues">Bugs fixed between versions.</param>
4040
/// <param name="KnownIssues">Known issues (unfixed or fixed but not in this build).</param>
4141
public record BuildInformation(
42-
string? FromVersion,
43-
string ToVersion,
42+
Version? FromVersion,
43+
Version ToVersion,
4444
string? FromHash,
4545
string ToHash,
4646
List<IssueInfo> ChangeIssues,
@@ -54,14 +54,14 @@ public record BuildInformation(
5454
/// <param name="version">Optional target version. If not provided, uses the most recent tag if it matches current commit.</param>
5555
/// <returns>BuildInformation record with all collected data.</returns>
5656
/// <exception cref="InvalidOperationException">Thrown if version cannot be determined.</exception>
57-
public static async Task<BuildInformation> CreateAsync(IRepoConnector connector, TagInfo? version = null)
57+
public static async Task<BuildInformation> CreateAsync(IRepoConnector connector, Version? version = null)
5858
{
5959
// Get tag history and current hash
6060
var tags = await connector.GetTagHistoryAsync();
6161
var currentHash = await connector.GetHashForTagAsync(null);
6262

6363
// Determine the "To" version
64-
TagInfo toTagInfo;
64+
Version toTagInfo;
6565
string toHash;
6666

6767
if (version != null)
@@ -74,7 +74,7 @@ public static async Task<BuildInformation> CreateAsync(IRepoConnector connector,
7474
{
7575
// Check if current commit matches the most recent tag
7676
var latestTag = tags[^1];
77-
var latestTagHash = await connector.GetHashForTagAsync(latestTag);
77+
var latestTagHash = await connector.GetHashForTagAsync(latestTag.Tag);
7878

7979
if (latestTagHash.Trim() == currentHash.Trim())
8080
{
@@ -96,7 +96,7 @@ public static async Task<BuildInformation> CreateAsync(IRepoConnector connector,
9696
}
9797

9898
// Determine the "From" version
99-
TagInfo? fromTagInfo = null;
99+
Version? fromTagInfo = null;
100100
string? fromHash = null;
101101

102102
if (tags.Count > 0)
@@ -150,7 +150,7 @@ public static async Task<BuildInformation> CreateAsync(IRepoConnector connector,
150150

151151
if (fromTagInfo != null)
152152
{
153-
fromHash = await connector.GetHashForTagAsync(fromTagInfo);
153+
fromHash = await connector.GetHashForTagAsync(fromTagInfo.Tag);
154154
}
155155
}
156156

@@ -212,8 +212,8 @@ public static async Task<BuildInformation> CreateAsync(IRepoConnector connector,
212212
}
213213

214214
return new BuildInformation(
215-
fromTagInfo?.Tag,
216-
toTagInfo.Tag,
215+
fromTagInfo,
216+
toTagInfo,
217217
fromHash?.Trim(),
218218
toHash.Trim(),
219219
changeIssues,
@@ -227,7 +227,7 @@ public static async Task<BuildInformation> CreateAsync(IRepoConnector connector,
227227
/// <param name="tags">List of tags.</param>
228228
/// <param name="normalizedVersion">Normalized version to find.</param>
229229
/// <returns>Index of the tag, or -1 if not found.</returns>
230-
private static int FindTagIndex(List<TagInfo> tags, string normalizedVersion)
230+
private static int FindTagIndex(List<Version> tags, string normalizedVersion)
231231
{
232232
for (var i = 0; i < tags.Count; i++)
233233
{

src/DemaConsulting.BuildMark/RepoConnectors/GitHubRepoConnector.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private static string ValidateId(string id, string paramName)
7575
/// Gets the history of tags leading to the current branch.
7676
/// </summary>
7777
/// <returns>List of tags in chronological order.</returns>
78-
public override async Task<List<TagInfo>> GetTagHistoryAsync()
78+
public override async Task<List<Version>> GetTagHistoryAsync()
7979
{
8080
var output = await RunCommandAsync("git", "tag --sort=creatordate --merged HEAD");
8181
var tagNames = output
@@ -84,36 +84,36 @@ public override async Task<List<TagInfo>> GetTagHistoryAsync()
8484
.ToList();
8585
// Filter out non-version tags
8686
return tagNames
87-
.Select(TagInfo.Create)
87+
.Select(Version.Create)
8888
.Where(t => t != null)
89-
.Cast<TagInfo>()
89+
.Cast<Version>()
9090
.ToList();
9191
}
9292

9393
/// <summary>
94-
/// Gets the list of pull request IDs between two tags.
94+
/// Gets the list of pull request IDs between two versions.
9595
/// </summary>
96-
/// <param name="fromTag">Starting tag (null for start of history).</param>
97-
/// <param name="toTag">Ending tag (null for current state).</param>
96+
/// <param name="from">Starting version (null for start of history).</param>
97+
/// <param name="to">Ending version (null for current state).</param>
9898
/// <returns>List of pull request IDs.</returns>
99-
public override async Task<List<string>> GetPullRequestsBetweenTagsAsync(TagInfo? fromTag, TagInfo? toTag)
99+
public override async Task<List<string>> GetPullRequestsBetweenTagsAsync(Version? from, Version? to)
100100
{
101101
string range;
102-
if (fromTag == null && toTag == null)
102+
if (from == null && to == null)
103103
{
104104
range = "HEAD";
105105
}
106-
else if (fromTag == null)
106+
else if (from == null)
107107
{
108-
range = ValidateTag(toTag!.Tag);
108+
range = ValidateTag(to!.Tag);
109109
}
110-
else if (toTag == null)
110+
else if (to == null)
111111
{
112-
range = $"{ValidateTag(fromTag.Tag)}..HEAD";
112+
range = $"{ValidateTag(from.Tag)}..HEAD";
113113
}
114114
else
115115
{
116-
range = $"{ValidateTag(fromTag.Tag)}..{ValidateTag(toTag.Tag)}";
116+
range = $"{ValidateTag(from.Tag)}..{ValidateTag(to.Tag)}";
117117
}
118118

119119
var output = await RunCommandAsync("git", $"log --oneline --merges {range}");
@@ -193,11 +193,11 @@ public override async Task<string> GetIssueTypeAsync(string issueId)
193193
/// <summary>
194194
/// Gets the git hash for a tag.
195195
/// </summary>
196-
/// <param name="tag">Tag information (null for current state).</param>
196+
/// <param name="tag">Tag name (null for current state).</param>
197197
/// <returns>Git hash.</returns>
198-
public override async Task<string> GetHashForTagAsync(TagInfo? tag)
198+
public override async Task<string> GetHashForTagAsync(string? tag)
199199
{
200-
var refName = tag == null ? "HEAD" : ValidateTag(tag.Tag);
200+
var refName = tag == null ? "HEAD" : ValidateTag(tag);
201201
return await RunCommandAsync("git", $"rev-parse {refName}");
202202
}
203203

src/DemaConsulting.BuildMark/RepoConnectors/IRepoConnector.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ public interface IRepoConnector
2929
/// Gets the history of tags leading to the current branch.
3030
/// </summary>
3131
/// <returns>List of tags in chronological order.</returns>
32-
Task<List<TagInfo>> GetTagHistoryAsync();
32+
Task<List<Version>> GetTagHistoryAsync();
3333

3434
/// <summary>
35-
/// Gets the list of pull request IDs between two tags.
35+
/// Gets the list of pull request IDs between two versions.
3636
/// </summary>
37-
/// <param name="fromTag">Starting tag (null for start of history).</param>
38-
/// <param name="toTag">Ending tag (null for current state).</param>
37+
/// <param name="from">Starting version (null for start of history).</param>
38+
/// <param name="to">Ending version (null for current state).</param>
3939
/// <returns>List of pull request IDs.</returns>
40-
Task<List<string>> GetPullRequestsBetweenTagsAsync(TagInfo? fromTag, TagInfo? toTag);
40+
Task<List<string>> GetPullRequestsBetweenTagsAsync(Version? from, Version? to);
4141

4242
/// <summary>
4343
/// Gets the issue IDs associated with a pull request.
@@ -63,9 +63,9 @@ public interface IRepoConnector
6363
/// <summary>
6464
/// Gets the git hash for a tag.
6565
/// </summary>
66-
/// <param name="tag">Tag information (null for current state).</param>
66+
/// <param name="tag">Tag name (null for current state).</param>
6767
/// <returns>Git hash.</returns>
68-
Task<string> GetHashForTagAsync(TagInfo? tag);
68+
Task<string> GetHashForTagAsync(string? tag);
6969

7070
/// <summary>
7171
/// Gets the URL for an issue.

src/DemaConsulting.BuildMark/RepoConnectors/MockRepoConnector.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,27 +65,27 @@ public class MockRepoConnector : IRepoConnector
6565
/// Gets the history of tags leading to the current branch.
6666
/// </summary>
6767
/// <returns>List of tags in chronological order.</returns>
68-
public Task<List<TagInfo>> GetTagHistoryAsync()
68+
public Task<List<Version>> GetTagHistoryAsync()
6969
{
7070
// Use dictionary keys to avoid duplication, filter out non-version tags
7171
var tagInfoList = _tagHashes.Keys
72-
.Select(TagInfo.Create)
72+
.Select(Version.Create)
7373
.Where(t => t != null)
74-
.Cast<TagInfo>()
74+
.Cast<Version>()
7575
.ToList();
7676
return Task.FromResult(tagInfoList);
7777
}
7878

7979
/// <summary>
80-
/// Gets the list of pull request IDs between two tags.
80+
/// Gets the list of pull request IDs between two versions.
8181
/// </summary>
82-
/// <param name="fromTag">Starting tag (null for start of history).</param>
83-
/// <param name="toTag">Ending tag (null for current state).</param>
82+
/// <param name="from">Starting version (null for start of history).</param>
83+
/// <param name="to">Ending version (null for current state).</param>
8484
/// <returns>List of pull request IDs.</returns>
85-
public Task<List<string>> GetPullRequestsBetweenTagsAsync(TagInfo? fromTag, TagInfo? toTag)
85+
public Task<List<string>> GetPullRequestsBetweenTagsAsync(Version? from, Version? to)
8686
{
87-
var fromTagName = fromTag?.Tag;
88-
var toTagName = toTag?.Tag;
87+
var fromTagName = from?.Tag;
88+
var toTagName = to?.Tag;
8989

9090
// Deterministic mock data based on tag range
9191
if (fromTagName == "v1.0.0" && toTagName == "ver-1.1.0")
@@ -148,17 +148,17 @@ public Task<string> GetIssueTypeAsync(string issueId)
148148
/// <summary>
149149
/// Gets the git hash for a tag.
150150
/// </summary>
151-
/// <param name="tag">Tag information (null for current state).</param>
151+
/// <param name="tag">Tag name (null for current state).</param>
152152
/// <returns>Git hash.</returns>
153-
public Task<string> GetHashForTagAsync(TagInfo? tag)
153+
public Task<string> GetHashForTagAsync(string? tag)
154154
{
155155
if (tag == null)
156156
{
157157
return Task.FromResult("current123hash456");
158158
}
159159

160160
return Task.FromResult(
161-
_tagHashes.TryGetValue(tag.Tag, out var hash)
161+
_tagHashes.TryGetValue(tag, out var hash)
162162
? hash
163163
: "unknown000hash000");
164164
}

src/DemaConsulting.BuildMark/RepoConnectors/RepoConnectorBase.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ protected virtual Task<string> RunCommandAsync(string command, string arguments)
4040
/// Gets the history of tags leading to the current branch.
4141
/// </summary>
4242
/// <returns>List of tags in chronological order.</returns>
43-
public abstract Task<List<TagInfo>> GetTagHistoryAsync();
43+
public abstract Task<List<Version>> GetTagHistoryAsync();
4444

4545
/// <summary>
46-
/// Gets the list of pull request IDs between two tags.
46+
/// Gets the list of pull request IDs between two versions.
4747
/// </summary>
48-
/// <param name="fromTag">Starting tag (null for start of history).</param>
49-
/// <param name="toTag">Ending tag (null for current state).</param>
48+
/// <param name="from">Starting version (null for start of history).</param>
49+
/// <param name="to">Ending version (null for current state).</param>
5050
/// <returns>List of pull request IDs.</returns>
51-
public abstract Task<List<string>> GetPullRequestsBetweenTagsAsync(TagInfo? fromTag, TagInfo? toTag);
51+
public abstract Task<List<string>> GetPullRequestsBetweenTagsAsync(Version? from, Version? to);
5252

5353
/// <summary>
5454
/// Gets the issue IDs associated with a pull request.
@@ -74,9 +74,9 @@ protected virtual Task<string> RunCommandAsync(string command, string arguments)
7474
/// <summary>
7575
/// Gets the git hash for a tag.
7676
/// </summary>
77-
/// <param name="tag">Tag information (null for current state).</param>
77+
/// <param name="tag">Tag name (null for current state).</param>
7878
/// <returns>Git hash.</returns>
79-
public abstract Task<string> GetHashForTagAsync(TagInfo? tag);
79+
public abstract Task<string> GetHashForTagAsync(string? tag);
8080

8181
/// <summary>
8282
/// Gets the URL for an issue.
Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323
namespace DemaConsulting.BuildMark;
2424

2525
/// <summary>
26-
/// Represents a version tag with parsed semantic version information.
26+
/// Represents a version with parsed semantic version information.
2727
/// </summary>
2828
/// <param name="Tag">The tag name.</param>
29-
/// <param name="FullVersion">The full semantic version (major.minor.patch-prerelease) with leading non-version characters removed.</param>
29+
/// <param name="FullVersion">The full semantic version (major.minor.patch-prerelease+metadata) with leading non-version characters removed.</param>
30+
/// <param name="SemanticVersion">The core semantic version (major.minor.patch).</param>
31+
/// <param name="PreRelease">The pre-release identifier (e.g., rc.4, alpha.1), or empty string if not a pre-release.</param>
32+
/// <param name="Metadata">The build metadata (e.g., build.5, linux.x64), or empty string if no metadata.</param>
3033
/// <param name="IsPreRelease">Whether this is a pre-release version.</param>
31-
public partial record TagInfo(string Tag, string FullVersion, bool IsPreRelease)
34+
public partial record Version(string Tag, string FullVersion, string SemanticVersion, string PreRelease, string Metadata, bool IsPreRelease)
3235
{
3336
/// <summary>
3437
/// Regex pattern for parsing version tags with optional prefix, pre-release, and build metadata.
@@ -43,11 +46,11 @@ public partial record TagInfo(string Tag, string FullVersion, bool IsPreRelease)
4346
private static partial Regex TagPattern();
4447

4548
/// <summary>
46-
/// Creates a TagInfo from a tag string, or returns null if the tag doesn't match version format.
49+
/// Creates a Version from a tag string, or returns null if the tag doesn't match version format.
4750
/// </summary>
4851
/// <param name="tag">Tag name to parse.</param>
49-
/// <returns>TagInfo instance if tag matches version format, null otherwise.</returns>
50-
public static TagInfo? Create(string tag)
52+
/// <returns>Version instance if tag matches version format, null otherwise.</returns>
53+
public static Version? Create(string tag)
5154
{
5255
var match = TagPattern().Match(tag);
5356
if (!match.Success)
@@ -57,23 +60,27 @@ public partial record TagInfo(string Tag, string FullVersion, bool IsPreRelease)
5760

5861
var version = match.Groups["version"].Value;
5962
var separator = match.Groups["separator"];
60-
var preRelease = match.Groups["pre_release"];
61-
var metadata = match.Groups["metadata"];
63+
var preReleaseGroup = match.Groups["pre_release"];
64+
var metadataGroup = match.Groups["metadata"];
6265

6366
// Pre-release exists if separator is present and pre-release group has content
64-
var hasPreRelease = separator.Success && preRelease.Success && !string.IsNullOrEmpty(preRelease.Value);
67+
var hasPreRelease = separator.Success && preReleaseGroup.Success && !string.IsNullOrEmpty(preReleaseGroup.Value);
68+
69+
// Extract pre-release and metadata strings
70+
var preRelease = hasPreRelease ? preReleaseGroup.Value : string.Empty;
71+
var metadata = metadataGroup.Success ? metadataGroup.Value : string.Empty;
6572

6673
// Build full version: version + optional pre-release + optional build metadata
6774
var fullVersion = version;
6875
if (hasPreRelease)
6976
{
70-
fullVersion += $"{separator.Value}{preRelease.Value}";
77+
fullVersion += $"{separator.Value}{preRelease}";
7178
}
72-
if (metadata.Success)
79+
if (metadataGroup.Success)
7380
{
74-
fullVersion += $"+{metadata.Value}";
81+
fullVersion += $"+{metadata}";
7582
}
7683

77-
return new TagInfo(tag, fullVersion, hasPreRelease);
84+
return new Version(tag, fullVersion, version, preRelease, metadata, hasPreRelease);
7885
}
7986
}

0 commit comments

Comments
 (0)