Skip to content

Commit 1b03cdf

Browse files
Copilotpascalberger
andcommitted
Make IIssue immutable with Run and FileLink properties
Co-authored-by: pascalberger <[email protected]>
1 parent c294d73 commit 1b03cdf

File tree

4 files changed

+94
-28
lines changed

4 files changed

+94
-28
lines changed

src/Cake.Issues.Tests/IssueReaderTests.cs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,11 @@ public void Should_Read_Correct_Number_Of_Issues()
175175

176176
// Then
177177
issues.Count.ShouldBe(2);
178-
issues.ShouldContain(issue1);
179-
issues.ShouldContain(issue2);
178+
179+
// Since IIssue is now immutable, we verify the returned issues
180+
// have the same identifiers as the original issues
181+
issues.Select(x => x.Identifier).ShouldContain(issue1.Identifier);
182+
issues.Select(x => x.Identifier).ShouldContain(issue2.Identifier);
180183
}
181184

182185
[Fact]
@@ -207,8 +210,11 @@ public void Should_Read_Correct_Number_Of_Issues_Not_Related_To_A_File()
207210

208211
// Then
209212
issues.Count.ShouldBe(2);
210-
issues.ShouldContain(issue1);
211-
issues.ShouldContain(issue2);
213+
214+
// Since IIssue is now immutable, we verify the returned issues
215+
// have the same identifiers as the original issues
216+
issues.Select(x => x.Identifier).ShouldContain(issue1.Identifier);
217+
issues.Select(x => x.Identifier).ShouldContain(issue2.Identifier);
212218
}
213219

214220
[Fact]
@@ -259,10 +265,13 @@ public void Should_Read_Correct_Number_Of_Issues_From_Multiple_Providers()
259265

260266
// Then
261267
issues.Count.ShouldBe(4);
262-
issues.ShouldContain(issue1);
263-
issues.ShouldContain(issue2);
264-
issues.ShouldContain(issue3);
265-
issues.ShouldContain(issue4);
268+
269+
// Since IIssue is now immutable, we verify the returned issues
270+
// have the same identifiers as the original issues
271+
issues.Select(x => x.Identifier).ShouldContain(issue1.Identifier);
272+
issues.Select(x => x.Identifier).ShouldContain(issue2.Identifier);
273+
issues.Select(x => x.Identifier).ShouldContain(issue3.Identifier);
274+
issues.Select(x => x.Identifier).ShouldContain(issue4.Identifier);
266275
}
267276

268277
[Fact]
@@ -297,10 +306,15 @@ public void Should_Set_Run_Property()
297306

298307
// Then
299308
issues.Count.ShouldBe(2);
300-
issues.ShouldContain(issue1);
301-
issue1.Run.ShouldBe(run);
302-
issues.ShouldContain(issue2);
303-
issue2.Run.ShouldBe(run);
309+
310+
// Since IIssue is now immutable, the returned issues are new objects
311+
// We check that the returned issues have the same content as originals
312+
var returnedIssue1 = issues.First(x => x.Identifier == issue1.Identifier);
313+
var returnedIssue2 = issues.First(x => x.Identifier == issue2.Identifier);
314+
315+
// Verify the Run property is set on the returned issues
316+
returnedIssue1.Run.ShouldBe(run);
317+
returnedIssue2.Run.ShouldBe(run);
304318
}
305319

306320
[Fact]
@@ -342,11 +356,16 @@ public void Should_Set_FileLink_Property()
342356

343357
// Then
344358
issues.Count.ShouldBe(2);
345-
issues.ShouldContain(issue1);
346-
issue1.FileLink.ToString()
359+
360+
// Since IIssue is now immutable, the returned issues are new objects
361+
// We check that the returned issues have the same content as originals
362+
var returnedIssue1 = issues.First(x => x.Identifier == issue1.Identifier);
363+
var returnedIssue2 = issues.First(x => x.Identifier == issue2.Identifier);
364+
365+
// Verify the FileLink property is set on the returned issues
366+
returnedIssue1.FileLink.ToString()
347367
.ShouldBe($"{repoUrl}/blob/{branch}/{filePath1.Replace(@"\", "/")}#L{line1}-L{endLine1}");
348-
issues.ShouldContain(issue2);
349-
issue2.FileLink.ToString()
368+
returnedIssue2.FileLink.ToString()
350369
.ShouldBe($"{repoUrl}/blob/{branch}/{filePath2.Replace(@"\", "/")}#L{line2}");
351370
}
352371
}

src/Cake.Issues/IIssue.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ public interface IIssue
6060
int? EndColumn { get; }
6161

6262
/// <summary>
63-
/// Gets or sets a link to the position in the file where the issue occurred.
63+
/// Gets a link to the position in the file where the issue occurred.
6464
/// <c>null</c> if <see cref="IReadIssuesSettings.FileLinkSettings"/> was not set while reading issue.
6565
/// </summary>
66-
Uri FileLink { get; set; }
66+
Uri FileLink { get; }
6767

6868
/// <summary>
6969
/// Gets the message of the issue in text format.
@@ -111,10 +111,10 @@ public interface IIssue
111111
Uri RuleUrl { get; }
112112

113113
/// <summary>
114-
/// Gets or sets the description of the run.
114+
/// Gets the description of the run.
115115
/// Can be <c>null</c> or <see cref="string.Empty"/> if no run information is provided.
116116
/// </summary>
117-
string Run { get; set; }
117+
string Run { get; }
118118

119119
/// <summary>
120120
/// Gets the type of the issue provider.

src/Cake.Issues/Issue.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public Issue(
202202
public int? EndColumn { get; }
203203

204204
/// <inheritdoc/>
205-
public Uri FileLink { get; set; }
205+
public Uri FileLink { get; }
206206

207207
/// <inheritdoc/>
208208
public string MessageText { get; }
@@ -229,7 +229,7 @@ public Issue(
229229
public Uri RuleUrl { get; }
230230

231231
/// <inheritdoc/>
232-
public string Run { get; set; }
232+
public string Run { get; }
233233

234234
/// <inheritdoc/>
235235
public string ProviderType { get; }
@@ -245,4 +245,36 @@ public Issue(
245245

246246
/// <inheritdoc/>
247247
public string SourceLanguage { get; }
248+
249+
/// <summary>
250+
/// Creates a new instance of this issue with updated Run and FileLink values.
251+
/// This method enables immutability by creating a copy of the issue with new values
252+
/// instead of modifying the existing instance.
253+
/// </summary>
254+
/// <param name="run">The new run value.</param>
255+
/// <param name="fileLink">The new file link value.</param>
256+
/// <returns>A new Issue instance with the updated values.</returns>
257+
public Issue WithRunAndFileLink(string run, Uri fileLink) =>
258+
new(
259+
this.Identifier,
260+
this.ProjectFileRelativePath?.ToString(),
261+
this.ProjectName,
262+
this.AffectedFileRelativePath?.ToString(),
263+
this.Line,
264+
this.EndLine,
265+
this.Column,
266+
this.EndColumn,
267+
fileLink,
268+
this.MessageText,
269+
this.MessageHtml,
270+
this.MessageMarkdown,
271+
this.Priority,
272+
this.PriorityName,
273+
this.RuleId,
274+
this.RuleName,
275+
this.RuleUrl,
276+
run,
277+
this.ProviderType,
278+
this.ProviderName,
279+
this.AdditionalInformation);
248280
}

src/Cake.Issues/IssuesReader.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace Cake.Issues;
22

3+
using System;
34
using System.Collections.Generic;
45
using System.Linq;
56
using Cake.Core.Diagnostics;
@@ -57,17 +58,31 @@ public IEnumerable<IIssue> ReadIssues()
5758
currentIssues.Count,
5859
providerName);
5960

60-
currentIssues.ForEach(x =>
61+
// Create enhanced issues with the Run and FileLink properties set
62+
// This maintains immutability by creating copies instead of mutating originals
63+
var enhancedIssues = new List<IIssue>();
64+
foreach (var issue in currentIssues)
6165
{
62-
x.Run = this.settings.Run;
66+
var run = this.settings.Run;
67+
var fileLink = this.settings.FileLinkSettings?.GetFileLink(issue);
6368

64-
if (this.settings.FileLinkSettings != null)
69+
// Always create a new issue instance to ensure immutability
70+
if (issue is Issue originalIssue)
6571
{
66-
x.FileLink = this.settings.FileLinkSettings.GetFileLink(x);
72+
var enhancedIssue = originalIssue.WithRunAndFileLink(run, fileLink);
73+
enhancedIssues.Add(enhancedIssue);
6774
}
68-
});
75+
else
76+
{
77+
// If it's a custom IIssue implementation, we can't enhance it while maintaining immutability
78+
// This is a limitation - custom implementations would need to handle this themselves
79+
throw new NotSupportedException(
80+
$"Issue type {issue.GetType().Name} does not support immutable enhancement. " +
81+
"Custom IIssue implementations should handle Run and FileLink setting during construction.");
82+
}
83+
}
6984

70-
issues.AddRange(currentIssues);
85+
issues.AddRange(enhancedIssues);
7186
}
7287
else
7388
{

0 commit comments

Comments
 (0)