Skip to content

Commit 27e3b52

Browse files
committed
Migrate Cli.Report from the compiler
1 parent c168982 commit 27e3b52

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

gren.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"exposed-modules": [
99
"Cli.Parser",
1010
"Cli.PrettyPrinter",
11+
"Cli.Report",
1112
"Compiler.Backend",
1213
"Compiler.Outline",
1314
"Compiler.Package",

src/Cli/Report.gren

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
module Cli.Report exposing
2+
( Report
3+
--
4+
, empty
5+
, create
6+
--
7+
, OutputType (..)
8+
, toString
9+
, prettyPrint
10+
)
11+
12+
13+
{-| This module is an abstraction on top of Cli.PrettyPrinter with
14+
a default layout and some standard options that we like to use in
15+
the Gren compiler.
16+
17+
If you want your command line application to output messages in the
18+
same style as the Gren compiler, then this is the package to use.
19+
-}
20+
21+
22+
import FileSystem.Path as Path exposing (Path)
23+
import Cli.PrettyPrinter as PP
24+
import Json.Encode as Encode
25+
26+
27+
{- A message to the user. We tend to use `Report`s for
28+
error messages and warnings.
29+
-}
30+
type Report
31+
= Empty
32+
| Report
33+
{ title : String
34+
, maybePath : Maybe Path
35+
, message : PP.Document
36+
}
37+
38+
39+
{-| The empty report. Equivalent to no output at all.
40+
-}
41+
empty : Report
42+
empty =
43+
Empty
44+
45+
46+
{-| A report has a title, a message and (optionally) a file path
47+
to the file that is relevant to the report.
48+
-}
49+
create : String -> Maybe Path -> PP.Document -> Report
50+
create title maybePath message =
51+
Report
52+
{ title = title
53+
, maybePath = maybePath
54+
, message = message
55+
}
56+
57+
58+
{-| How do you want to format the report? Use `Json` when you
59+
expect your CLI to be read by a script.
60+
-}
61+
type OutputType
62+
= Terminal { useColor : Bool }
63+
| Json
64+
65+
66+
{-| Turn the report into a string that can be written to the
67+
stdout stream. If you target something other than stdout, make
68+
sure you've disabled colors or use the `Json` output type.
69+
-}
70+
toString : OutputType -> (Path -> String) -> Report -> String
71+
toString outputType pathToString report =
72+
when outputType is
73+
Json ->
74+
when report is
75+
Empty ->
76+
Encode.encode 0 (Encode.object [])
77+
78+
Report { title, maybePath, message } ->
79+
Encode.encode 4 <|
80+
Encode.object
81+
[ { key = "type", value = Encode.string "error" }
82+
, { key = "title", value = Encode.string title }
83+
, { key = "path"
84+
, value =
85+
maybePath
86+
|> Maybe.map pathToString
87+
|> Maybe.withDefault ""
88+
|> Encode.string
89+
}
90+
, { key = "message"
91+
, value =
92+
message
93+
|> prettyPrint { useColor = False }
94+
|> Encode.string
95+
}
96+
]
97+
98+
Terminal printOpts ->
99+
prettyPrint printOpts <|
100+
when report is
101+
Empty ->
102+
PP.empty
103+
104+
Report { title, maybePath, message } ->
105+
let
106+
makeDashes n =
107+
String.repeat (max 1 (80 - n)) "-"
108+
109+
errorBarEnd =
110+
when maybePath is
111+
Nothing ->
112+
makeDashes (4 + String.unitLength title)
113+
114+
Just path ->
115+
let
116+
pathStr =
117+
pathToString path
118+
in
119+
" "
120+
++ makeDashes (5 + String.unitLength title + String.unitLength pathStr)
121+
++ " "
122+
++ pathStr
123+
124+
errorBar =
125+
PP.block
126+
[ PP.text "-- "
127+
, PP.text title
128+
, PP.text errorBarEnd
129+
]
130+
|> PP.color PP.Cyan
131+
in
132+
PP.verticalBlock
133+
[ errorBar
134+
, PP.empty
135+
, message
136+
, PP.empty
137+
, PP.empty
138+
]
139+
140+
141+
{-| An oppinionated `PrettyPrint.toString`.
142+
-}
143+
prettyPrint : { useColor : Bool } -> PP.Document -> String
144+
prettyPrint { useColor } doc =
145+
PP.toStringWithOptions
146+
{ maxColumns = 80
147+
, indentationSize = 4
148+
, newlineSeparator = "\n"
149+
}
150+
(if useColor then
151+
doc
152+
153+
else
154+
PP.stripColor doc
155+
)

0 commit comments

Comments
 (0)