Skip to content

Commit 35af003

Browse files
authored
Support absolute paths in TAP stylelint format (#974)
1 parent 92bd914 commit 35af003

File tree

6 files changed

+139
-2
lines changed

6 files changed

+139
-2
lines changed

src/Cake.Issues.Tap.Tests/LogFileFormat/StylelintLogFileFormatTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,67 @@ public void Should_Read_Issue_Correct_When_Message_Contains_Double_Quotes()
154154
.OfRule("csstools/use-logical")
155155
.Create());
156156
}
157+
158+
[Theory]
159+
[InlineData(@"c:\Source\Cake.Issues", "test.scss")]
160+
[InlineData(@"c:\Source\Cake.Issues\", "test.scss")]
161+
[InlineData(@"c:/Source/Cake.Issues", "test.scss")]
162+
[InlineData(@"c:/Source/Cake.Issues/", "test.scss")]
163+
[InlineData(@"c:\Source", @"Cake.Issues\test.scss")]
164+
[InlineData(@"c:\Source\", @"Cake.Issues\test.scss")]
165+
[InlineData(@"c:/Source", @"Cake.Issues\test.scss")]
166+
[InlineData(@"c:/Source/", @"Cake.Issues\test.scss")]
167+
public void Should_Read_Issue_Correct_When_Absolute_Windows_Path(string repositoryRoot, string relativeFilePath)
168+
{
169+
// Given
170+
var fixture = new TapIssuesProviderFixture<StylelintLogFileFormat>("absolute-windows-path.tap", repositoryRoot);
171+
172+
// When
173+
var issues = fixture.ReadIssues().ToList();
174+
175+
// Then
176+
issues.Count.ShouldBe(1);
177+
178+
var issue = issues[0];
179+
IssueChecker.Check(
180+
issue,
181+
IssueBuilder.NewIssue(
182+
"Unexpected empty block (block-no-empty)",
183+
"Cake.Issues.Tap.TapIssuesProvider",
184+
"TAP")
185+
.InFile(relativeFilePath, 16, 16, 6, 8)
186+
.WithPriority(IssuePriority.Error)
187+
.OfRule("block-no-empty")
188+
.Create());
189+
}
190+
191+
[Theory]
192+
[InlineData("/src/Cake.Issues", "test.scss")]
193+
[InlineData("/src/Cake.Issues/", "test.scss")]
194+
[InlineData("/src", "Cake.Issues/test.scss")]
195+
[InlineData("/src/", "Cake.Issues/test.scss")]
196+
public void Should_Read_Issue_Correct_When_Absolute_Linux_Path(string repositoryRoot, string relativeFilePath)
197+
{
198+
// Given
199+
var fixture = new TapIssuesProviderFixture<StylelintLogFileFormat>("absolute-linux-path.tap", repositoryRoot);
200+
201+
// When
202+
var issues = fixture.ReadIssues().ToList();
203+
204+
// Then
205+
issues.Count.ShouldBe(1);
206+
207+
var issue = issues[0];
208+
IssueChecker.Check(
209+
issue,
210+
IssueBuilder.NewIssue(
211+
"Unexpected empty block (block-no-empty)",
212+
"Cake.Issues.Tap.TapIssuesProvider",
213+
"TAP")
214+
.InFile(relativeFilePath, 16, 16, 6, 8)
215+
.WithPriority(IssuePriority.Error)
216+
.OfRule("block-no-empty")
217+
.Create());
218+
}
157219
}
158220
}

src/Cake.Issues.Tap.Tests/TapIssuesProviderFixture.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ internal class TapIssuesProviderFixture<T>
55
where T : BaseTapLogFileFormat
66
{
77
public TapIssuesProviderFixture(string fileResourceName)
8+
: this(fileResourceName, @"c:\Source\Cake.Issues")
9+
{
10+
}
11+
12+
public TapIssuesProviderFixture(string fileResourceName, string repositoryRoot)
813
: base(fileResourceName)
914
{
1015
this.ReadIssuesSettings =
11-
new ReadIssuesSettings(@"c:\Source\Cake.Issues");
16+
new ReadIssuesSettings(repositoryRoot);
1217
}
1318

1419
protected override string FileResourceNamespace => "Cake.Issues.Tap.Tests.Testfiles." + typeof(T).Name + ".";
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
TAP version 14
2+
1..153
3+
not ok 123 - /src/Cake.Issues/test.scss
4+
---
5+
block-no-empty:
6+
- message: "Unexpected empty block (block-no-empty)"
7+
severity: error
8+
line: 16
9+
column: 6
10+
endLine: 16
11+
endColumn: 8
12+
...
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
TAP version 14
2+
1..153
3+
not ok 123 - c:\Source\Cake.Issues\test.scss
4+
---
5+
block-no-empty:
6+
- message: "Unexpected empty block (block-no-empty)"
7+
severity: error
8+
line: 16
9+
column: 6
10+
endLine: 16
11+
endColumn: 8
12+
...

src/Cake.Issues.Tap/BaseTapLogFileFormat.cs

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

33
using Cake.Core.Diagnostics;
4+
using Cake.Core.IO;
45

56
/// <summary>
67
/// Base class for all log file formats supported by the TAP issue provider.
@@ -9,4 +10,23 @@
910
public abstract class BaseTapLogFileFormat(ICakeLog log)
1011
: BaseLogFileFormat<TapIssuesProvider, TapIssuesSettings>(log)
1112
{
13+
/// <summary>
14+
/// Validates a file path.
15+
/// </summary>
16+
/// <param name="filePath">Full file path.</param>
17+
/// <param name="repositorySettings">Repository settings.</param>
18+
/// <returns>Tuple containing a value if validation was successful, and file path relative to repository root.</returns>
19+
protected static (bool Valid, string FilePath) ValidateFilePath(string filePath, IRepositorySettings repositorySettings)
20+
{
21+
filePath.NotNullOrWhiteSpace();
22+
repositorySettings.NotNull();
23+
24+
// Make path relative to repository root.
25+
if (!new FilePath(filePath).IsRelative)
26+
{
27+
filePath = filePath.NormalizePath().MakeFilePathRelativeToRepositoryRoot(repositorySettings);
28+
}
29+
30+
return (true, filePath);
31+
}
1232
}

src/Cake.Issues.Tap/LogFileFormat/StylelintLogFileFormat.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,19 @@ public override IEnumerable<IIssue> ReadIssues(
3737
{
3838
if (diagnostic is Dictionary<object, object> diagnosticDict)
3939
{
40+
// Read affected file from the result.
41+
if (!TryGetFile(tapResult, repositorySettings, out var fileName))
42+
{
43+
this.Log.Information("Skip element since file path could not be parsed");
44+
continue;
45+
}
46+
4047
// Build issue.
4148
var issueBuilder =
4249
IssueBuilder
4350
.NewIssue(diagnosticDict["message"].ToString(), issueProvider)
4451
.InFile(
45-
tapResult.Description.ToString(),
52+
fileName,
4653
diagnosticDict.ContainsKey("line") ? int.Parse(diagnosticDict["line"].ToString()) : null,
4754
diagnosticDict.ContainsKey("endLine") ? int.Parse(diagnosticDict["endLine"].ToString()) : null,
4855
diagnosticDict.ContainsKey("column") ? int.Parse(diagnosticDict["column"].ToString()) : null,
@@ -65,4 +72,23 @@ public override IEnumerable<IIssue> ReadIssues(
6572
"warning" => IssuePriority.Warning,
6673
_ => IssuePriority.Undefined,
6774
};
75+
76+
/// <summary>
77+
/// Reads the affected file path from a result.
78+
/// </summary>
79+
/// <param name="tapResult">Result entry.</param>
80+
/// <param name="repositorySettings">Repository settings to use.</param>
81+
/// <param name="fileName">Returns the full path to the affected file.</param>
82+
/// <returns>True if the file path could be parsed.</returns>
83+
private static bool TryGetFile(
84+
TapTestPoint tapResult,
85+
IRepositorySettings repositorySettings,
86+
out string fileName)
87+
{
88+
fileName = tapResult.Description.ToString();
89+
90+
// Validate file path and make relative to repository root.
91+
(var result, fileName) = ValidateFilePath(fileName, repositorySettings);
92+
return result;
93+
}
6894
}

0 commit comments

Comments
 (0)