Skip to content

Commit ff639d4

Browse files
committed
Add ANSI color code support to trace, use for AppVeyor
1 parent b866925 commit ff639d4

File tree

2 files changed

+66
-32
lines changed

2 files changed

+66
-32
lines changed

src/app/FakeLib/TraceHelper.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ let traceStartTaskUsing task description =
167167
traceStartTask task description
168168
{ new IDisposable with member x.Dispose() = traceEndTask task description }
169169

170-
let console = new ConsoleTraceListener(false, colorMap) :> ITraceListener
170+
let console = new ConsoleTraceListener(false, colorMap, false) :> ITraceListener
171171

172172
open System.Diagnostics
173173

src/app/FakeLib/TraceListener.fs

+65-31
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Fake.TraceListener
55
open System
66

77
/// Defines Tracing information for TraceListeners
8-
type TraceData =
8+
type TraceData =
99
| StartMessage
1010
| ImportantMessage of string
1111
| ErrorMessage of string
@@ -36,11 +36,11 @@ type TraceData =
3636
| CloseTag _ -> None
3737

3838
/// Defines a TraceListener interface
39-
type ITraceListener =
39+
type ITraceListener =
4040
abstract Write : TraceData -> unit
4141

4242
/// A default color map which maps TracePriorities to ConsoleColors
43-
let colorMap traceData =
43+
let colorMap traceData =
4444
match traceData with
4545
| ImportantMessage _ -> ConsoleColor.Yellow
4646
| ErrorMessage _ -> ConsoleColor.Red
@@ -53,86 +53,120 @@ let colorMap traceData =
5353
/// ## Parameters
5454
/// - `importantMessagesToStdErr` - Defines whether to trace important messages to StdErr.
5555
/// - `colorMap` - A function which maps TracePriorities to ConsoleColors.
56-
type ConsoleTraceListener(importantMessagesToStdErr, colorMap) =
57-
58-
let writeText toStdErr color newLine text =
56+
type ConsoleTraceListener(importantMessagesToStdErr, colorMap, useAnsiColorCodes) =
57+
let writeTextConsoleColor print color text =
5958
let curColor = Console.ForegroundColor
6059
try
6160
try
6261
if curColor <> color then Console.ForegroundColor <- color
63-
let printer =
64-
match toStdErr, newLine with
65-
| true, true -> eprintfn
66-
| true, false -> eprintf
67-
| false, true -> printfn
68-
| false, false -> printf
69-
printer "%s" text
62+
print text
7063
with
71-
| :? ArgumentException when EnvironmentHelper.isMono ->
64+
| :? ArgumentException when EnvironmentHelper.isMono ->
7265
printfn "* Color output has been disabled because of a bug in GNOME Terminal."
7366
printfn "* Hint: To workaround this bug, please set environment property TERM=xterm-256color"
7467
reraise()
7568
finally
7669
if curColor <> color then Console.ForegroundColor <- curColor
77-
70+
71+
let writeTextAnsiColor print color text =
72+
let colorCode = function
73+
| ConsoleColor.Black -> [30]
74+
| ConsoleColor.Blue -> [34]
75+
| ConsoleColor.Cyan -> [36]
76+
| ConsoleColor.Gray -> [37;2]
77+
| ConsoleColor.Green -> [32]
78+
| ConsoleColor.Magenta -> [35]
79+
| ConsoleColor.Red -> [31]
80+
| ConsoleColor.White -> [37]
81+
| ConsoleColor.Yellow -> [33]
82+
| ConsoleColor.DarkBlue -> [34;2]
83+
| ConsoleColor.DarkCyan -> [36;2]
84+
| ConsoleColor.DarkGray -> [37;2]
85+
| ConsoleColor.DarkGreen -> [32;2]
86+
| ConsoleColor.DarkMagenta -> [35;2]
87+
| ConsoleColor.DarkRed -> [31;2]
88+
| ConsoleColor.DarkYellow -> [33;2]
89+
| _ -> [39]
90+
91+
let codeStr =
92+
colorCode color
93+
|> List.map (sprintf "%i")
94+
|> String.concat ";"
95+
96+
print <| sprintf "\x1b[%sm%s\x1b[0m" codeStr text
97+
98+
let printer toStdErr newLine =
99+
match toStdErr, newLine with
100+
| true, true -> eprintfn "%s"
101+
| true, false -> eprintf "%s"
102+
| false, true -> printfn "%s"
103+
| false, false -> printf "%s"
104+
78105
interface ITraceListener with
79106
/// Writes the given message to the Console.
80-
member this.Write msg =
107+
member this.Write msg =
81108
let color = colorMap msg
109+
let writeText text printer =
110+
if useAnsiColorCodes
111+
then writeTextAnsiColor printer color text
112+
else writeTextConsoleColor printer color text
82113
match msg with
83114
| StartMessage -> ()
84115
| OpenTag _ -> ()
85116
| CloseTag _ -> ()
86117
| ImportantMessage text | ErrorMessage text ->
87-
writeText importantMessagesToStdErr color true text
118+
printer importantMessagesToStdErr true |> writeText text
88119
| LogMessage(text, newLine) | TraceMessage(text, newLine) ->
89-
writeText false color newLine text
120+
printer false newLine |> writeText text
90121
| FinishedMessage -> ()
91122

92123
// If we write the stderr on those build servers the build will fail.
93124
let importantMessagesToStdErr = buildServer <> CCNet && buildServer <> AppVeyor && buildServer <> TeamCity
94125

126+
// stdout is piped to the logger, so colours are lost. AppVeyor supports ANSI color codes.
127+
let useAnsiColors = buildServer = AppVeyor
128+
95129
/// The default TraceListener for Console.
96130
let defaultConsoleTraceListener =
97-
ConsoleTraceListener(importantMessagesToStdErr, colorMap)
131+
ConsoleTraceListener(importantMessagesToStdErr, colorMap, useAnsiColors)
98132

99133
/// Specifies if the XmlWriter should close tags automatically
100134
let mutable AutoCloseXmlWriter = false
101135

102136
/// Implements a TraceListener which writes NAnt like XML files.
103137
/// ## Parameters
104138
/// - `xmlOutputFile` - Defines the xml output file.
105-
type NAntXmlTraceListener(xmlOutputFile) =
139+
type NAntXmlTraceListener(xmlOutputFile) =
106140
let xmlOutputPath = FullName xmlOutputFile
107141
let getXmlWriter() = new IO.StreamWriter(xmlOutputPath, true, encoding)
108142
let mutable xmlWriter : IO.StreamWriter = null
109-
110-
let deleteOldFile() =
143+
144+
let deleteOldFile() =
111145
let fi = fileInfo xmlOutputPath
112-
if fi.Exists then
146+
if fi.Exists then
113147
fi.IsReadOnly <- false
114148
fi.Delete()
115149
if not fi.Directory.Exists then fi.Directory.Create()
116-
117-
let closeWriter() =
118-
if xmlWriter <> null then
150+
151+
let closeWriter() =
152+
if xmlWriter <> null then
119153
xmlWriter.Close()
120154
xmlWriter <- null
121-
122-
let getXml msg =
155+
156+
let getXml msg =
123157
match msg with
124158
| StartMessage -> "<?xml version=\"1.0\"?>\r\n<buildresults>"
125159
| ImportantMessage text -> sprintf "<message level=\"Info\"><![CDATA[%s]]></message>" text // TODO: Set Level
126160
| LogMessage(text, _) | TraceMessage(text, _) -> sprintf "<message level=\"Info\"><![CDATA[%s]]></message>" text
127161
| FinishedMessage -> "</buildresults>"
128162
| OpenTag(tag, name) -> sprintf "<%s name=\"%s\">" tag name
129163
| CloseTag tag -> sprintf "</%s>" tag
130-
| ErrorMessage text ->
164+
| ErrorMessage text ->
131165
sprintf "<failure><builderror><message level=\"Error\"><![CDATA[%s]]></message></builderror></failure>" text
132-
166+
133167
interface ITraceListener with
134168
/// Writes the given message to the xml file.
135-
member this.Write msg =
169+
member this.Write msg =
136170
if msg = StartMessage then deleteOldFile()
137171
if xmlWriter = null then xmlWriter <- getXmlWriter()
138172
msg

0 commit comments

Comments
 (0)