Skip to content

Commit af76a93

Browse files
committed
colored output
1 parent b1ccb4a commit af76a93

File tree

4 files changed

+65
-23
lines changed

4 files changed

+65
-23
lines changed

src/FSharp.Analyzers.Cli/Logging.fs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Console.ExampleFormatters.Custom
1+
module FSharp.Analyzers.Cli.CustomLogging
22

33
open System
44
open System.IO
@@ -11,13 +11,16 @@ open Microsoft.Extensions.Options
1111
type CustomOptions() =
1212
inherit ConsoleFormatterOptions()
1313

14-
member val CustomPrefix = "" with get, set
14+
/// if true: no LogLevel as prefix, colored output according to LogLevel
15+
/// if false: LogLevel as prefix, no colored output
16+
member val UseAnalyzersMsgStyle = false with get, set
1517

1618
type CustomFormatter(options: IOptionsMonitor<CustomOptions>) as this =
1719
inherit ConsoleFormatter("customName")
1820

1921
let mutable optionsReloadToken: IDisposable = null
2022
let mutable formatterOptions = options.CurrentValue
23+
let origColor = Console.ForegroundColor
2124

2225
do optionsReloadToken <- options.OnChange(fun x -> this.ReloadLoggerOptions(x))
2326

@@ -31,11 +34,37 @@ type CustomFormatter(options: IOptionsMonitor<CustomOptions>) as this =
3134
)
3235
=
3336
let message = logEntry.Formatter.Invoke(logEntry.State, logEntry.Exception)
34-
this.CustomLogic(textWriter)
35-
textWriter.WriteLine(message)
3637

37-
member private _.CustomLogic(textWriter: TextWriter) =
38-
textWriter.Write(formatterOptions.CustomPrefix)
38+
if formatterOptions.UseAnalyzersMsgStyle then
39+
this.SetColor(textWriter, logEntry.LogLevel)
40+
textWriter.WriteLine(message)
41+
this.ResetColor()
42+
else
43+
this.WritePrefix(textWriter, logEntry.LogLevel)
44+
textWriter.WriteLine(message)
45+
46+
member private _.WritePrefix(textWriter: TextWriter, logLevel: LogLevel) =
47+
match logLevel with
48+
| LogLevel.Trace -> textWriter.Write("trace: ")
49+
| LogLevel.Debug -> textWriter.Write("debug: ")
50+
| LogLevel.Information -> textWriter.Write("info: ")
51+
| LogLevel.Warning -> textWriter.Write("warn: ")
52+
| LogLevel.Error -> textWriter.Write("error: ")
53+
| LogLevel.Critical -> textWriter.Write("critical: ")
54+
| _ -> ()
55+
56+
member private _.SetColor(textWriter: TextWriter, logLevel: LogLevel) =
57+
let color =
58+
match logLevel with
59+
| LogLevel.Error -> "\x1B[1m\x1B[31m" // ConsoleColor.Red
60+
| LogLevel.Warning -> "\x1B[33m" // ConsoleColor.DarkYellow
61+
| LogLevel.Information -> "\x1B[1m\x1B[34m" // ConsoleColor.Blue
62+
| LogLevel.Trace -> "\x1B[1m\x1B[36m" // ConsoleColor.Cyan
63+
| _ -> "\x1B[37m" // ConsoleColor.Gray
64+
65+
textWriter.Write(color)
66+
67+
member private _.ResetColor() = Console.ForegroundColor <- origColor
3968

4069
interface IDisposable with
4170
member _.Dispose() = optionsReloadToken.Dispose()

src/FSharp.Analyzers.Cli/Program.fs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ open Microsoft.CodeAnalysis.Sarif
1212
open Microsoft.CodeAnalysis.Sarif.Writers
1313
open Microsoft.Extensions.Logging
1414
open Ionide.ProjInfo
15-
open Console.ExampleFormatters.Custom
15+
open FSharp.Analyzers.Cli.CustomLogging
1616

1717
type Arguments =
1818
| Project of string list
@@ -182,7 +182,7 @@ let runProject
182182
let fsharpFiles = set [| ".fs"; ".fsi"; ".fsx" |]
183183

184184
let isFSharpFile (file: string) =
185-
Seq.exists (fun (ext: string) -> file.EndsWith ext) fsharpFiles
185+
Set.exists (fun (ext: string) -> file.EndsWith(ext, StringComparison.Ordinal)) fsharpFiles
186186

187187
let runFscArgs
188188
(client: Client<CliAnalyzerAttribute, CliContext>)
@@ -229,22 +229,35 @@ let runFscArgs
229229
runProjectAux client projectOptions globs mappings
230230

231231
let printMessages (msgs: AnalyzerMessage list) =
232+
233+
let severityToLogLevel =
234+
Map.ofArray
235+
[|
236+
Error, LogLevel.Error
237+
Warning, LogLevel.Warning
238+
Info, LogLevel.Information
239+
Hint, LogLevel.Trace
240+
|]
241+
232242
if List.isEmpty msgs then
233243
logger.LogInformation("No messages found from the analyzer(s)")
234244

245+
use factory =
246+
LoggerFactory.Create(fun builder ->
247+
builder
248+
.AddCustomFormatter(fun options -> options.UseAnalyzersMsgStyle <- true)
249+
.SetMinimumLevel(LogLevel.Trace)
250+
|> ignore
251+
)
252+
253+
let msgLogger = factory.CreateLogger("")
254+
235255
msgs
236256
|> Seq.iter (fun analyzerMessage ->
237257
let m = analyzerMessage.Message
238258

239-
let msgLogLevel =
240-
match m.Severity with
241-
| Error -> LogLevel.Error
242-
| Warning -> LogLevel.Warning
243-
| Info -> LogLevel.Information
244-
| Hint -> LogLevel.Trace
245-
246-
logger.Log(
247-
msgLogLevel,
259+
msgLogger.Log(
260+
severityToLogLevel[m.Severity],
248261
"{0}({1},{2}): {3} {4} - {5}",
249262
m.Range.FileName,
250263
m.Range.StartLine,
@@ -273,7 +286,7 @@ let writeReport (results: AnalyzerMessage list option) (codeRoot: string option)
273286
let driver = ToolComponent()
274287
driver.Name <- "Ionide.Analyzers.Cli"
275288
driver.InformationUri <- Uri("https://ionide.io/FSharp.Analyzers.SDK/")
276-
driver.Version <- string (System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
289+
driver.Version <- string<Version> (System.Reflection.Assembly.GetExecutingAssembly().GetName().Version)
277290
let tool = Tool()
278291
tool.Driver <- driver
279292
let run = Run()
@@ -460,7 +473,7 @@ let main argv =
460473
use factory =
461474
LoggerFactory.Create(fun builder ->
462475
builder
463-
.AddCustomFormatter(fun options -> options.CustomPrefix <- "")
476+
.AddCustomFormatter(fun options -> options.UseAnalyzersMsgStyle <- false)
464477
.SetMinimumLevel(logLevel)
465478
|> ignore
466479
)

src/FSharp.Analyzers.SDK.Testing/FSharp.Analyzers.SDK.Testing.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ exception CompilerDiagnosticErrors of FSharpDiagnostic array
4444
let fsharpFiles = set [| ".fs"; ".fsi"; ".fsx" |]
4545

4646
let isFSharpFile (file: string) =
47-
Seq.exists (fun (ext: string) -> file.EndsWith ext) fsharpFiles
47+
Set.exists (fun (ext: string) -> file.EndsWith(ext, StringComparison.Ordinal)) fsharpFiles
4848

4949
let readCompilerArgsFromBinLog (build: Build) =
5050
if not build.Succeeded then
@@ -82,7 +82,7 @@ let readCompilerArgsFromBinLog (build: Build) =
8282
match args with
8383
| None -> failwith $"Could not parse binlog at {build.LogFilePath}, does it contain CoreCompile?"
8484
| Some args ->
85-
let idx = args.IndexOf "-o:"
85+
let idx = args.IndexOf("-o:", StringComparison.Ordinal)
8686
args.Substring(idx).Split [| '\n' |]
8787

8888
let mkOptions (compilerArgs: string array) =

src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.Client.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module Client =
2828

2929
let isAnalyzer<'TAttribute when 'TAttribute :> AnalyzerAttribute> (mi: MemberInfo) =
3030
mi.GetCustomAttributes true
31-
|> Seq.tryFind (fun n -> n.GetType().Name = typeof<'TAttribute>.Name)
31+
|> Array.tryFind (fun n -> n.GetType().Name = typeof<'TAttribute>.Name)
3232
|> Option.map unbox<'TAttribute>
3333

3434
let analyzerFromMember<'TAnalyzerAttribute, 'TContext
@@ -217,7 +217,7 @@ type Client<'TAttribute, 'TContext when 'TAttribute :> AnalyzerAttribute and 'TC
217217
registeredAnalyzers.AddOrUpdate(path, analyzers, (fun _ _ -> analyzers))
218218
|> ignore
219219

220-
Seq.length analyzers, analyzers |> Seq.collect snd |> Seq.length
220+
Array.length analyzers, analyzers |> Seq.collect snd |> Seq.length
221221
else
222222
0, 0
223223

0 commit comments

Comments
 (0)