1 -- | Utilities for printing terminal output.
7 import Control
.Exception
(catch)
8 import qualified System
.Console
.Terminal
.Size
as Terminal
9 import System
.Process
.Typed
(ExitCodeException
)
11 import ANSI
(SGR
(Bold
, BrightCyan
, BrightGreen
, BrightRed
, Reset
), setSGR
)
12 import ClockUtil
(AbsoluteTime
, diffAbsoluteTime
, formatDiffTime
, getAbsoluteTime
)
13 import System
.Exit
(exitFailure)
15 -- | Get the width of the current terminal, or 80 if no width can be determined.
16 getTerminalWidth
:: IO Int
17 getTerminalWidth
= maybe 80 Terminal
.width
<$> Terminal
.size
@Int
19 -- | Print a header for a given step.
21 -- This is colorful and hard to miss in the output.
26 printHeader title
= do
27 columns
<- getTerminalWidth
29 right
= columns
- length title
- left
- 2
31 setSGR
[Bold
, BrightCyan
]
36 <> replicate right
'═
'
40 -- | Run an `IO` action and print duration information after it finishes.
43 -- ^ Start time for the whole @cabal-validate@ run.
45 -- ^ Name for describing the action.
47 -- Used in a sentence like "@title@ finished after 16.34s".
51 withTiming startTime title action
= do
52 startTime
' <- getAbsoluteTime
56 `
catch`
(\exception
-> pure
(Left
(exception
:: ExitCodeException
)))
58 endTime
<- getAbsoluteTime
60 let duration
= diffAbsoluteTime endTime startTime
'
61 totalDuration
= diffAbsoluteTime endTime startTime
66 setSGR
[Bold
, BrightGreen
]
69 <> formatDiffTime duration
70 <> "\nTotal time so far: "
71 <> formatDiffTime totalDuration
75 Left _procFailed
-> do
77 setSGR
[Bold
, BrightRed
]
80 <> formatDiffTime duration
81 <> "\nTotal time so far: "
82 <> formatDiffTime totalDuration
85 -- TODO: `--keep-going` mode.