1
1
module Main where
2
2
3
3
import Control.Monad (forM , forM_ )
4
- import Data.Char (isSpace , toLower )
4
+ import Data.Char (isLower , isSpace , toLower , toUpper )
5
5
import System.Directory (createDirectory )
6
- import System.FilePath ((</>) )
6
+ import System.FilePath ((<.>) , (</>) )
7
+ import System.IO (BufferMode (.. ), hSetBuffering , stdout )
7
8
import Text.Read (readMaybe )
8
9
10
+ -------------------------------------------------------------------------------
11
+ -- Run this tool with `runghc` on the commandline:
12
+
13
+ -- $ runghc helper-tool.hs
14
+
15
+ -------------------------------------------------------------------------------
16
+
9
17
-------------------------------------------------------------------------------
10
18
-- Querying the user about the diagnostic
11
19
-------------------------------------------------------------------------------
@@ -17,13 +25,13 @@ normalize = fmap toLower . strip
17
25
strip = f . f
18
26
f = reverse . dropWhile isSpace
19
27
20
- -- Querying for the system : GHC / GHCup / Stack
28
+ -- Querying for the tool : GHC / GHCup / Stack
21
29
22
- data System = GHC | GHCup | Stack deriving (Show )
30
+ data Tool = GHC | GHCup | Stack deriving (Show )
23
31
24
- readSystem :: IO System
25
- readSystem = do
26
- putStrLn " For which system do you want to generate a message ?"
32
+ readTool :: IO Tool
33
+ readTool = do
34
+ putStrLn " Which tool's error code do you want to document ?"
27
35
putStrLn " 1) GHC"
28
36
putStrLn " 2) GHCup"
29
37
putStrLn " 3) Stack"
@@ -36,7 +44,10 @@ readSystem = do
36
44
" ghcup" -> pure GHCup
37
45
" 3" -> pure Stack
38
46
" stack" -> pure Stack
39
- _ -> pure GHC
47
+ " " -> pure GHC
48
+ _ -> do
49
+ putStrLn " Didn't understand input. Please type a tool name or a number."
50
+ readTool
40
51
41
52
-- Querying for the error code
42
53
@@ -61,7 +72,8 @@ type Title = String
61
72
62
73
readTitle :: IO Title
63
74
readTitle = do
64
- putStrLn " What is the title of the error message."
75
+ putStrLn " What is the title of the error message?"
76
+ putStrLn " This is used as the title of the documentation page as well as in links to the page."
65
77
putStr " Input: "
66
78
getLine
67
79
@@ -71,6 +83,7 @@ type Summary = String
71
83
readSummary :: IO Summary
72
84
readSummary = do
73
85
putStrLn " Give a short summary of the error message."
86
+ putStrLn " This appears on the overview page that lists all the documented errors and warnings."
74
87
putStr " Input: "
75
88
getLine
76
89
@@ -89,16 +102,20 @@ readSeverity = do
89
102
" error" -> pure Error
90
103
" 2" -> pure Warning
91
104
" warning" -> pure Warning
92
- _ -> pure Error
105
+ " " -> pure Error
106
+ _ -> do
107
+ putStrLn " Please type \" error\" or \" warning\" or a number."
108
+ readSeverity
93
109
94
110
-- Warning flag
95
111
type WarningFlag = String
96
112
97
113
-- | Only ask for a warning flag if Severity = Warning.
98
114
readWarningFlag :: Severity -> IO (Maybe WarningFlag )
99
115
readWarningFlag Warning = do
100
- putStrLn " What is the warning flag which enables this warning. "
116
+ putStrLn " What is the warning flag which enables this warning? "
101
117
putStrLn " For example, enter \" -Wtabs\" if you are documenting GHC's warning about tabs in your source file."
118
+ putStrLn " You can leave this blank if you're not sure."
102
119
putStr " Input: "
103
120
Just <$> getLine
104
121
readWarningFlag _ = pure Nothing
@@ -118,29 +135,30 @@ type Examples = [String]
118
135
119
136
validateExampleName :: String -> Bool
120
137
validateExampleName " " = False
121
- validateExampleName str = not (any isSpace str)
138
+ validateExampleName str@ (s : _) = not (any isSpace str) && isLower s
122
139
123
140
-- | Only ask for examples if the system is GHC.
124
- readExamples :: System -> IO Examples
141
+ readExamples :: Tool -> IO Examples
125
142
readExamples GHC = do
126
143
putStrLn " How many examples should be generated?"
127
144
putStr " Input: "
128
145
ln <- getLine
129
146
case readMaybe ln :: Maybe Int of
130
147
Nothing -> pure []
131
- ( Just n) -> forM [1 .. n] readExample
148
+ Just n -> forM [1 .. n] readExample
132
149
readExamples _ = pure []
133
150
134
151
readExample :: Int -> IO String
135
152
readExample i = do
136
153
putStrLn (" Give a name for example " <> show i)
154
+ putStrLn " The name should not contain spaces and begin with a lowercase letter."
137
155
putStr " Input: "
138
156
ln <- getLine
139
157
if validateExampleName ln then pure ln else readExample i
140
158
141
159
-- Template
142
160
data Template = MkTemplate
143
- { system :: System ,
161
+ { tool :: Tool ,
144
162
code :: ErrorCode ,
145
163
title :: Title ,
146
164
summary :: Summary ,
@@ -156,7 +174,7 @@ readTemplate = do
156
174
putStrLn " This tool helps you create the scaffolding for a new error message on the error-message-index."
157
175
putStrLn " You can leave any of the text fields blank and fill them in by hand later."
158
176
putStrLn " "
159
- sys <- readSystem
177
+ sys <- readTool
160
178
putStrLn " "
161
179
code <- readCode
162
180
putStrLn " "
@@ -184,7 +202,7 @@ createFiles tmpl = do
184
202
putStrLn " "
185
203
186
204
-- Create the new directory "messages/XXX-NNNNNN/" and "messages/XXX-NNNNNN/index.md"
187
- let message_dir = " messages" </> case system tmpl of { GHC -> " GHC-" ; GHCup -> " GHCup-" ; Stack -> " S-" } ++ code tmpl
205
+ let message_dir = " messages" </> case tool tmpl of { GHC -> " GHC-" ; GHCup -> " GHCup-" ; Stack -> " S-" } ++ code tmpl
188
206
createDirectory message_dir
189
207
let toplvl_index =
190
208
unlines
@@ -200,11 +218,14 @@ createFiles tmpl = do
200
218
writeFile (message_dir </> " index.md" ) toplvl_index
201
219
202
220
-- Create the example directories and entries:
203
- -- - "messages/XXX-NNNNNN/" and "messages/XXX-NNNNNN/index.md"
204
- -- - "messages/XXX-NNNNNN/before/" and "messages/XXX-NNNNNN/before/Module.hs"
205
- -- - "messages/XXX-NNNNNN/after/" and "messages/XXX-NNNNNN/after/Module.hs"
221
+ -- - "messages/XXX-NNNNNN/" and "messages/XXX-NNNNNN/example-name/ index.md"
222
+ -- - "messages/XXX-NNNNNN/example-name/ before/" and "messages/XXX-NNNNNN/example-name /before/Module.hs"
223
+ -- - "messages/XXX-NNNNNN/example-name/ after/" and "messages/XXX-NNNNNN/example-name /after/Module.hs"
206
224
forM_ (examples tmpl) $ \ example -> do
207
225
let example_dir = message_dir </> example
226
+ let uppercase " " = " "
227
+ uppercase (s : ss) = toUpper s : ss
228
+ let example_name = uppercase example
208
229
createDirectory example_dir
209
230
createDirectory (example_dir </> " before" )
210
231
createDirectory (example_dir </> " after" )
@@ -217,24 +238,25 @@ createFiles tmpl = do
217
238
writeFile (example_dir </> " index.md" ) example_index
218
239
let before_module =
219
240
unlines
220
- [ " module Example where" ,
241
+ [ " module " <> example_name <> " where" ,
221
242
" " ,
222
243
" -- Insert the example containing a bug here."
223
244
]
224
- writeFile (example_dir </> " before" </> " Example. hs" ) before_module
245
+ writeFile (example_dir </> " before" </> example_name <.> " hs" ) before_module
225
246
let after_module =
226
247
unlines
227
- [ " module Example where" ,
248
+ [ " module " <> example_name <> " where" ,
228
249
" " ,
229
250
" -- Insert the fixed example here."
230
251
]
231
- writeFile (example_dir </> " after" </> " Example. hs" ) after_module
252
+ writeFile (example_dir </> " after" </> example_name <.> " hs" ) after_module
232
253
233
254
-------------------------------------------------------------------------------
234
255
-- Main
235
256
-------------------------------------------------------------------------------
236
257
237
258
main :: IO ()
238
259
main = do
260
+ hSetBuffering stdout NoBuffering
239
261
tmpl <- readTemplate
240
262
createFiles tmpl
0 commit comments