22using Xunit . Abstractions ;
33using System . Text . Json ;
44using CliWrap ;
5+ using Xunit . Sdk ;
56
67namespace Workleap . DotNet . CodingStandards . Tests . Helpers ;
78
@@ -46,14 +47,27 @@ public void AddFile(string relativePath, string content)
4647 File . WriteAllText ( this . _directory . GetPath ( relativePath ) , content ) ;
4748 }
4849
49- public void AddCsprojFile ( Dictionary < string , string > ? properties = null )
50+ public void AddCsprojFile ( Dictionary < string , string > ? properties = null , Dictionary < string , string > ? packageReferences = null )
5051 {
51- var element = new XElement ( "PropertyGroup" ) ;
52+ var propertyElement = new XElement ( "PropertyGroup" ) ;
5253 if ( properties != null )
5354 {
5455 foreach ( var prop in properties )
5556 {
56- element . Add ( new XElement ( prop . Key ) , prop . Value ) ;
57+ propertyElement . Add ( new XElement ( prop . Key ) , prop . Value ) ;
58+ }
59+ }
60+
61+ var referencesElement = new XElement ( "ItemGroup" ) ;
62+ if ( packageReferences != null )
63+ {
64+ foreach ( var reference in packageReferences )
65+ {
66+ var packageReference = new XElement ( "PackageReference" ) ;
67+ packageReference . SetAttributeValue ( "Include" , reference . Key ) ;
68+ packageReference . SetAttributeValue ( "Version" , reference . Value ) ;
69+
70+ referencesElement . Add ( packageReference ) ;
5771 }
5872 }
5973
@@ -66,11 +80,12 @@ public void AddCsprojFile(Dictionary<string, string>? properties = null)
6680 <Nullable>enable</Nullable>
6781 <ErrorLog>{ SarifFileName } ,version=2.1</ErrorLog>
6882 </PropertyGroup>
69- { element }
83+ { propertyElement }
7084
7185 <ItemGroup>
7286 <PackageReference Include="Workleap.DotNet.CodingStandards" Version="*" />
7387 </ItemGroup>
88+ { referencesElement }
7489 </Project>
7590 """ ;
7691
@@ -92,9 +107,52 @@ public async Task<SarifFile> BuildAndGetOutput(string[]? buildArguments = null)
92107
93108 var bytes = await File . ReadAllBytesAsync ( this . _directory . GetPath ( SarifFileName ) ) ;
94109 var sarif = JsonSerializer . Deserialize < SarifFile > ( bytes ) ?? throw new InvalidOperationException ( "The sarif file is invalid" ) ;
110+
111+ this . AppendAdditionalResult ( sarif ) ;
112+
95113 this . _testOutputHelper . WriteLine ( "Sarif result:\n " + string . Join ( "\n " , sarif . AllResults ( ) . Select ( r => r . ToString ( ) ) ) ) ;
96114 return sarif ;
97115 }
98116
99117 public void Dispose ( ) => this . _directory . Dispose ( ) ;
118+
119+ private void AppendAdditionalResult ( SarifFile sarifFile )
120+ {
121+ if ( this . _testOutputHelper is not TestOutputHelper testOutputHelper || sarifFile . Runs == null )
122+ {
123+ return ;
124+ }
125+
126+ var outputLines = testOutputHelper . Output . Split ( Environment . NewLine ) ;
127+ var customRunResults = new List < SarifFileRunResult > ( ) ;
128+
129+ // These rules (for nuget package vulnerability) are not parsed in the sarif file automatically
130+ // See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1901-nu1904
131+ var scannedRules = new List < string > { "NU1901" , "NU1902" , "NU1903" , "NU1904" }
132+ . ToDictionary ( x => x , x => $ "{ x } :") ;
133+
134+ foreach ( var outputLine in outputLines )
135+ {
136+ foreach ( var scannedRule in scannedRules )
137+ {
138+ var scannedRuleIndex = outputLine . IndexOf ( scannedRule . Value , StringComparison . OrdinalIgnoreCase ) ;
139+ if ( scannedRuleIndex == - 1 )
140+ {
141+ continue ;
142+ }
143+
144+ var previousColonIndex = outputLine . LastIndexOf ( ':' , scannedRuleIndex ) ;
145+ var ruleLevel = outputLine . Substring ( previousColonIndex + 1 , scannedRuleIndex - previousColonIndex - 1 ) . Trim ( ) ;
146+
147+ var message = outputLine [ ( scannedRuleIndex + scannedRule . Value . Length + 1 ) ..] ;
148+ customRunResults . Add ( new SarifFileRunResult { Level = ruleLevel , RuleId = scannedRule . Key , Message = new SarifFileRunResultMessage { Text = message } } ) ;
149+ }
150+ }
151+
152+ var distinctRules = customRunResults
153+ . DistinctBy ( x => new { x . RuleId , x . Level } )
154+ . ToArray ( ) ;
155+
156+ sarifFile . Runs = sarifFile . Runs . Append ( new SarifFileRun { Results = distinctRules } ) . ToArray ( ) ;
157+ }
100158}
0 commit comments