Skip to content

Commit

Permalink
simplify solution
Browse files Browse the repository at this point in the history
  • Loading branch information
dicko2 committed Nov 17, 2024
1 parent ad1a750 commit cac74f8
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 217 deletions.
49 changes: 29 additions & 20 deletions src/Agoda.CodeCompass.MSBuild.Tests/SarifConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
using Agoda.CodeCompass.MSBuild.Sarif;
using Microsoft.Build.Framework;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using NSubstitute;
using NUnit.Framework;
using NUnit.Framework.Internal;
using Shouldly;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;

namespace Agoda.CodeCompass.MSBuild.Tests;

Expand All @@ -15,6 +18,12 @@ public class SarifConversionTests
private readonly string _writeSarifPath = "TestData/write.sarif";
private readonly string _sampleSarifPath = "TestData/sample.sarif";
private readonly IBuildEngine _buildEngine = Substitute.For<IBuildEngine>();
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Error = HandleDeserializationError

Check warning on line 24 in src/Agoda.CodeCompass.MSBuild.Tests/SarifConversionTests.cs

View workflow job for this annotation

GitHub Actions / Build Package

Nullability of reference types in type of parameter 'sender' of 'void SarifConversionTests.HandleDeserializationError(object sender, ErrorEventArgs errorArgs)' doesn't match the target delegate 'EventHandler<ErrorEventArgs>' (possibly because of nullability attributes).

};

[Test]
public async Task ConvertSarif_WithValidInput_ShouldAddTechDebtProperties()
Expand All @@ -34,8 +43,14 @@ public async Task ConvertSarif_WithValidInput_ShouldAddTechDebtProperties()
// Assert
result.ShouldBeTrue();

var jsonSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Error = HandleDeserializationError

Check warning on line 49 in src/Agoda.CodeCompass.MSBuild.Tests/SarifConversionTests.cs

View workflow job for this annotation

GitHub Actions / Build Package

Nullability of reference types in type of parameter 'sender' of 'void SarifConversionTests.HandleDeserializationError(object sender, ErrorEventArgs errorArgs)' doesn't match the target delegate 'EventHandler<ErrorEventArgs>' (possibly because of nullability attributes).

};
var outputJson = await File.ReadAllTextAsync(outfile);
var output = JsonSerializer.Deserialize<SarifReport>(outputJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
var output = JsonConvert.DeserializeObject<SarifReport>(outputJson, jsonSettings);

output.ShouldNotBeNull();
output.Runs.ShouldNotBeEmpty();
Expand All @@ -49,21 +64,6 @@ public async Task ConvertSarif_WithValidInput_ShouldAddTechDebtProperties()
firstResult.Properties.TechDebt.Priority.ShouldNotBeNullOrWhiteSpace();
}

[Test]
public void ConvertSarif_WithInvalidPath_ShouldReturnFalse()
{
var task = new TechDebtSarifTask
{
InputPath = "TestData/invalid.sarif",
OutputPath = Guid.NewGuid().ToString(),
BuildEngine = _buildEngine
};

var result = task.Execute();

result.ShouldBeFalse();
}

[Test]
public async Task ConvertSarif_WithV1FromTestData_ShouldHave1Violation()
{
Expand All @@ -80,14 +80,23 @@ public async Task ConvertSarif_WithV1FromTestData_ShouldHave1Violation()
result.ShouldBeTrue();

var outputJson = await File.ReadAllTextAsync(outfile);
var output = JsonSerializer.Deserialize<SarifReport>(outputJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
var output = JsonConvert.DeserializeObject<SarifV1Report>(outputJson, _jsonSettings);

output.Runs[0].Results.Count.ShouldBe(1);
output.Runs[0].Results.Length.ShouldBe(1);

Check warning on line 85 in src/Agoda.CodeCompass.MSBuild.Tests/SarifConversionTests.cs

View workflow job for this annotation

GitHub Actions / Build Package

Dereference of a possibly null reference.

var results = output.Runs[0].Results;
results[0].RuleId.ShouldBe("CA1707");

}

private static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
// Log the error but don't throw it
var currentError = errorArgs.ErrorContext.Error.Message;
Console.WriteLine($"Warning during SARIF processing: {currentError}");
errorArgs.ErrorContext.Handled = true;
}

[Test]
public async Task ConvertSarif_WithMultipleRules_ShouldPreserveRuleMetadata()
{
Expand All @@ -108,7 +117,7 @@ public async Task ConvertSarif_WithMultipleRules_ShouldPreserveRuleMetadata()
};

await File.WriteAllTextAsync(_writeSarifPath,
JsonSerializer.Serialize(sarif, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }));
JsonConvert.SerializeObject(sarif, _jsonSettings));
var outfile = "TestData/" + Guid.NewGuid();
var task = new TechDebtSarifTask
{
Expand All @@ -122,7 +131,7 @@ await File.WriteAllTextAsync(_writeSarifPath,

// Assert
var outputJson = await File.ReadAllTextAsync(outfile);
var output = JsonSerializer.Deserialize<SarifReport>(outputJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
var output = JsonConvert.DeserializeObject<SarifReport>(outputJson, _jsonSettings);

output.ShouldNotBeNull();
output.Runs[0].Results.Count.ShouldBe(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.Build.Framework" Version="17.8.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.8.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/Agoda.CodeCompass.MSBuild/Sarif/V1Result.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using Newtonsoft.Json;

namespace Agoda.CodeCompass.MSBuild.Sarif;

public class V1Result
{
public string RuleId { get; set; } = string.Empty;
public string Level { get; set; } = string.Empty;

[JsonProperty("message")]
public string Message { get; set; } = string.Empty;
public V1Location[] Locations { get; set; } = Array.Empty<V1Location>();
public TechDebtProperties Properties { get; set; } = new();
Expand Down
129 changes: 68 additions & 61 deletions src/Agoda.CodeCompass.MSBuild/SarifReporter.cs
Original file line number Diff line number Diff line change
@@ -1,75 +1,82 @@
using System.Text.Json;
using Agoda.CodeCompass.Data;
using Agoda.CodeCompass.MSBuild.Sarif;
using Microsoft.CodeAnalysis;
using Location = Agoda.CodeCompass.MSBuild.Sarif.Location;

namespace Agoda.CodeCompass.MSBuild;
using Agoda.CodeCompass.MSBuild;
using Microsoft.Build.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
using Formatting = System.Xml.Formatting;

public class SarifReporter
{
public static string GenerateSarifReport(IEnumerable<Diagnostic> diagnostics)
private static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
// Log the error but don't throw it
var currentError = errorArgs.ErrorContext.Error.Message;
Console.WriteLine($"Warning during SARIF processing: {currentError}");
errorArgs.ErrorContext.Handled = true;
}
public static string AddTechDebtToSarif(string sarifContent)
{
var jsonSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Error = HandleDeserializationError

Check warning on line 25 in src/Agoda.CodeCompass.MSBuild/SarifReporter.cs

View workflow job for this annotation

GitHub Actions / Build Package

Nullability of reference types in type of parameter 'sender' of 'void SarifReporter.HandleDeserializationError(object sender, ErrorEventArgs errorArgs)' doesn't match the target delegate 'EventHandler<ErrorEventArgs>' (possibly because of nullability attributes).

};

// Detect version
var jObject = JObject.Parse(sarifContent);
var version = jObject["version"]?.ToString();

return version switch
{
"1.0.0" => AddTechDebtToSarifV1(sarifContent, jsonSettings),
"2.1.0" => AddTechDebtToSarifV2(sarifContent, jsonSettings),
_ => throw new NotSupportedException($"Unsupported SARIF version: {version}")
};
}

private static string AddTechDebtToSarifV1(string sarifContent, JsonSerializerSettings jsonSettings)
{
var report = new SarifReport
var report = JsonConvert.DeserializeObject<SarifV1Report>(sarifContent, jsonSettings);

// Add tech debt properties to results for V1
foreach (var run in report.Runs)

Check warning on line 46 in src/Agoda.CodeCompass.MSBuild/SarifReporter.cs

View workflow job for this annotation

GitHub Actions / Build Package

Dereference of a possibly null reference.
{
Runs = new[]
foreach (var result in run.Results)
{
new Run
{
Tool = new Tool
{
Driver = new ToolDriver
{
Rules = diagnostics
.Select(d => d.Descriptor)
.Distinct()
.Select(d => new Rule
{
Id = d.Id,
Name = d.Title.ToString(),
ShortDescription = new Message { Text = d.Title.ToString() },
FullDescription = new Message { Text = d.Description.ToString() },
Help = new Message { Text = d.Description.ToString() },
Properties = GetTechDebtProperties(d.Id)
})
.ToArray()
}
},
Results = diagnostics.Select(d => new Result
{
RuleId = d.Id,
Message = new Message { Text = d.GetMessage() },
Locations = new[]
{
new Location
{
PhysicalLocation = new PhysicalLocation
{
ArtifactLocation = new ArtifactLocation
{
Uri = d.Location.GetLineSpan().Path
},
Region = new Region
{
StartLine = d.Location.GetLineSpan().StartLinePosition.Line + 1,
StartColumn = d.Location.GetLineSpan().StartLinePosition.Character + 1,
EndLine = d.Location.GetLineSpan().EndLinePosition.Line + 1,
EndColumn = d.Location.GetLineSpan().EndLinePosition.Character + 1
}
}
}
},
Properties = GetTechDebtProperties(d.Id)
}).ToList()
}
result.Properties = GetTechDebtProperties(result.RuleId);
}
};
}

return JsonConvert.SerializeObject(report, jsonSettings);
}

return JsonSerializer.Serialize(report, new JsonSerializerOptions
private static string AddTechDebtToSarifV2(string sarifContent, JsonSerializerSettings jsonSettings)
{
var report = JsonConvert.DeserializeObject<SarifReport>(sarifContent, jsonSettings);

// Add tech debt properties to rules
if (report.Runs?.FirstOrDefault()?.Tool?.Driver?.Rules != null)

Check warning on line 62 in src/Agoda.CodeCompass.MSBuild/SarifReporter.cs

View workflow job for this annotation

GitHub Actions / Build Package

Dereference of a possibly null reference.
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
foreach (var rule in report.Runs[0].Tool.Driver.Rules)
{
rule.Properties = GetTechDebtProperties(rule.Id);
}
}

// Add tech debt properties to results
foreach (var run in report.Runs)

Check warning on line 71 in src/Agoda.CodeCompass.MSBuild/SarifReporter.cs

View workflow job for this annotation

GitHub Actions / Build Package

Dereference of a possibly null reference.
{
foreach (var result in run.Results)
{
result.Properties = GetTechDebtProperties(result.RuleId);
}
}

return JsonConvert.SerializeObject(report, jsonSettings);
}

private static TechDebtProperties GetTechDebtProperties(string ruleId)
Expand Down
Loading

0 comments on commit cac74f8

Please sign in to comment.