1- using Cocona ;
1+ using System . ComponentModel . DataAnnotations ;
2+ using System . Globalization ;
3+ using System . IO ;
4+
5+ using Cocona ;
26using Cocona . Application ;
37using Cocona . Builder ;
48
711using Spectre . Console ;
812
913using SquiggleCop . Common ;
14+ using SquiggleCop . Tool . Rendering ;
1015
1116namespace SquiggleCop . Tool ;
1217
1318/// <summary>
1419/// Configure and create the <see cref="CoconaApp"/>.
1520/// </summary>
16- public static class AppBuilder
21+ public static class App
1722{
1823 /// <summary>
1924 /// Create a new instance of <see cref="CoconaApp"/>.
@@ -44,6 +49,7 @@ public static CoconaApp Create(Action<CoconaAppBuilder> configure)
4449 builder . Services . AddSingleton < Serializer > ( ) ;
4550 builder . Services . AddSingleton < BaselineDiffer > ( ) ;
4651 builder . Services . AddSingleton < BaselineWriter > ( ) ;
52+ builder . Services . AddRenderers ( ) ;
4753
4854 configure ( builder ) ;
4955
@@ -60,11 +66,14 @@ public static CoconaApp Create(Action<CoconaAppBuilder> configure)
6066 private static async Task < int > GenerateAsync (
6167 SarifParser parser ,
6268 Serializer serializer ,
69+ BaselineDiffer differ ,
6370 BaselineWriter writer ,
71+ ReportRenderer renderer ,
6472 IAnsiConsole console ,
6573 [ Option ( 'a' , Description = "Automatically update baseline if necessary" ) ] bool autoBaseline ,
6674 [ Argument ( Description = "The SARIF log to generate a baseline for" ) ] string sarif ,
67- [ Option ( 'o' , Description = "The output path for the baseline file" ) ] string ? output )
75+ [ Option ( 'o' , Description = "The output path for the baseline file" ) ] string ? output ,
76+ [ Option ( 'c' , Description = "Number of context lines to use in the diff" ) ] [ Range ( 1 , 100 ) ] int context = 3 )
6877 {
6978 if ( ! File . Exists ( sarif ) )
7079 {
@@ -73,11 +82,6 @@ private static async Task<int> GenerateAsync(
7382
7483 output = ValidateOutputPath ( output ) ;
7584
76- if ( ! autoBaseline )
77- {
78- throw new NotImplementedException ( "Manual baseline creation is not yet implemented. Use `--auto-baseline` and your source control system to review changes for now." ) ;
79- }
80-
8185 try
8286 {
8387 IReadOnlyCollection < DiagnosticConfig > configs ;
@@ -88,16 +92,24 @@ private static async Task<int> GenerateAsync(
8892 }
8993
9094 string newBaseline = serializer . Serialize ( configs ) ;
91- await writer . WriteAsync ( output , newBaseline ) . ConfigureAwait ( false ) ;
95+
96+ BaselineDiff diff = differ . Diff ( await ReadBaselineAsync ( output ) . ConfigureAwait ( false ) , newBaseline ) ;
97+
98+ renderer . Render ( diff , showDiff : ! autoBaseline , context ) ;
99+
100+ if ( autoBaseline )
101+ {
102+ await writer . WriteAsync ( output , newBaseline ) . ConfigureAwait ( false ) ;
103+ console . MarkupLineInterpolated ( CultureInfo . InvariantCulture , $ "[green]Baseline generated[/] @ [link=file://{ Path . GetFullPath ( output ) } ]{ output } [/]") ;
104+ return ExitCodes . Success ;
105+ }
106+
107+ return ! diff . HasDifferences ? ExitCodes . Success : ExitCodes . BaselineMismatch ;
92108 }
93109 catch ( UnsupportedVersionException ex )
94110 {
95111 throw new SarifInvalidException ( $ "SARIF file is invalid. { ex . Message } ", ex ) ;
96112 }
97-
98- console . MarkupLine ( $ "[green]Baseline generated[/] @ { output } ") ;
99-
100- return ExitCodes . Success ;
101113 }
102114
103115 private static string ValidateOutputPath ( string ? path )
@@ -112,4 +124,9 @@ private static string ValidateOutputPath(string? path)
112124
113125 return path ;
114126 }
127+
128+ private static async Task < string > ReadBaselineAsync ( string path )
129+ {
130+ return File . Exists ( path ) ? await File . ReadAllTextAsync ( path ) . ConfigureAwait ( false ) : string . Empty ;
131+ }
115132}
0 commit comments