Skip to content

Commit 88092f6

Browse files
committed
Add inital concept of helper tool
1 parent fabe1b3 commit 88092f6

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

message-index/helper-tool.hs

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
module Main where
2+
3+
import Control.Monad (forM)
4+
import Text.Read (readMaybe)
5+
import System.Directory (createDirectory)
6+
import System.FilePath ((</>))
7+
8+
-------------------------------------------------------------------------------
9+
-- Querying the user about the diagnostic
10+
-------------------------------------------------------------------------------
11+
12+
-- Querying for the system: GHC / GHCup / Stack
13+
14+
data System = GHC | GHCup | Stack deriving Show
15+
16+
readSystem :: IO System
17+
readSystem = do
18+
putStrLn "For which system do you want to generate a message?"
19+
putStrLn " 1) GHC"
20+
putStrLn " 2) GHCup"
21+
putStrLn " 3) Stack"
22+
putStr "Input (Default = GHC): "
23+
ln <- getLine
24+
case ln of
25+
"1" -> pure GHC
26+
"GHC" -> pure GHC
27+
"2" -> pure GHCup
28+
"GHCup" -> pure GHCup
29+
"3" -> pure Stack
30+
"Stack" -> pure Stack
31+
_ -> pure GHC
32+
33+
-- Querying for the error code
34+
35+
-- | We need to encode the error code as a string in order
36+
-- to preserve leading 0's.
37+
type ErrorCode = String
38+
39+
readCode :: IO ErrorCode
40+
readCode = do
41+
putStrLn "What is the errorcode that you want to document."
42+
putStr "Input: "
43+
ln <- getLine
44+
case (readMaybe ln) :: Maybe Int of
45+
Nothing -> do
46+
putStrLn "Could not parse the input as an integer. Try again."
47+
readCode
48+
Just _ -> pure ln
49+
50+
-- Title
51+
type Title = String
52+
53+
readTitle :: IO Title
54+
readTitle = do
55+
putStrLn "What is the title of the error message."
56+
putStr "Input: "
57+
getLine
58+
59+
-- Summary
60+
type Summary = String
61+
62+
readSummary :: IO Summary
63+
readSummary = do
64+
putStrLn "Give a short summary of the error message."
65+
putStr "Input: "
66+
getLine
67+
68+
-- Severity
69+
data Severity = Error | Warning | NA deriving Show
70+
71+
readSeverity :: IO Severity
72+
readSeverity = do
73+
putStrLn "What is the severity of the diagnostic."
74+
putStrLn " 1) Error"
75+
putStrLn " 2) Warning"
76+
putStrLn " 3) N/A"
77+
putStr "Input (Default = N/A): "
78+
ln <- getLine
79+
case ln of
80+
"1" -> pure Error
81+
"Error" -> pure Error
82+
"2" -> pure Warning
83+
"Warning" -> pure Warning
84+
_ -> pure NA
85+
86+
-- Warning flag
87+
type WarningFlag = String
88+
89+
-- | Only ask for a warning flag if Severity = Warning.
90+
readWarningFlag :: Severity -> IO (Maybe WarningFlag)
91+
readWarningFlag Warning = do
92+
putStrLn "What is the warning flag which enables this warning."
93+
putStr "Input: "
94+
ln <- getLine
95+
pure (Just ln)
96+
readWarningFlag _ = pure Nothing
97+
98+
-- Version
99+
type Version = String
100+
101+
readVersion :: IO Version
102+
readVersion = do
103+
putStrLn "For which version was this error message emitted for the first time?"
104+
putStrLn "Note: For GHC this is most likely 9.6.1."
105+
putStr "Input: "
106+
getLine
107+
108+
-- Examples
109+
type Examples = Int
110+
111+
-- | Only ask for examples if the system is GHC.
112+
readExamples :: System -> IO Examples
113+
readExamples GHC = do
114+
putStrLn "How many examples should be generated?"
115+
putStr "Input: "
116+
ln <- getLine
117+
case (readMaybe ln) :: Maybe Int of
118+
Nothing -> pure 0
119+
Just n -> pure n
120+
readExamples _ = pure 0
121+
122+
-- Template
123+
data Template =
124+
MkTemplate { system :: System
125+
, code :: ErrorCode
126+
, title :: Title
127+
, summary :: Summary
128+
, severity :: Severity
129+
, warningflag :: Maybe WarningFlag
130+
, introduced :: Version
131+
, examples :: Examples
132+
} deriving Show
133+
134+
135+
readTemplate :: IO Template
136+
readTemplate = do
137+
putStrLn "This tool helps you create the scaffolding for a new error message on the error-message-index."
138+
putStrLn "You can leave any of the text fields blank and fill them in by hand later."
139+
putStrLn ""
140+
sys <- readSystem
141+
putStrLn ""
142+
code <- readCode
143+
putStrLn ""
144+
title <- readTitle
145+
putStrLn ""
146+
summary <- readSummary
147+
putStrLn ""
148+
severity <- readSeverity
149+
putStrLn ""
150+
warningflag <- readWarningFlag severity
151+
putStrLn ""
152+
version <- readVersion
153+
putStrLn ""
154+
examples <- readExamples sys
155+
pure (MkTemplate sys code title summary severity warningflag version examples)
156+
157+
-------------------------------------------------------------------------------
158+
-- Creating the files and directories from the template
159+
-------------------------------------------------------------------------------
160+
161+
createFiles :: Template -> IO ()
162+
createFiles tmpl = do
163+
putStrLn "Creating scaffolding for the following configuration:"
164+
print tmpl
165+
putStrLn ""
166+
167+
-- Create the new directory "messages/XXX-NNNNNN/" and "messages/XXX-NNNNNN/index.md"
168+
let message_dir = "messages" </> case system tmpl of { GHC -> "GHC-"; GHCup -> "GHCup-"; Stack -> "S-" } ++ code tmpl
169+
createDirectory message_dir
170+
let toplvl_index = unlines [ "---"
171+
, "title: " <> title tmpl
172+
, "summary: " <> summary tmpl
173+
, "severity: " <> case severity tmpl of { Warning -> "warning"; Error -> "error"; NA -> "na" }
174+
, "introduced: " <> introduced tmpl
175+
, "---"
176+
, ""
177+
, "Insert your error message here."
178+
]
179+
writeFile (message_dir </> "index.md") toplvl_index
180+
181+
-- Create the example directories and entries:
182+
-- - "messages/XXX-NNNNNN/" and "messages/XXX-NNNNNN/index.md"
183+
-- - "messages/XXX-NNNNNN/before/" and "messages/XXX-NNNNNN/before/Module.hs"
184+
-- - "messages/XXX-NNNNNN/after/" and "messages/XXX-NNNNNN/after/Module.hs"
185+
forM [1 .. (examples tmpl)] $ \n -> do
186+
let example = "example" <> show n
187+
let example_dir = message_dir </> example
188+
createDirectory example_dir
189+
createDirectory (example_dir </> "before")
190+
createDirectory (example_dir </> "after")
191+
let example_index = unlines [ "---"
192+
, "title: <insert a title for this example here>"
193+
, "---"
194+
]
195+
writeFile (example_dir </> "index.md") example_index
196+
let before_module = unlines [ "module Example where"
197+
, ""
198+
, "-- Insert the example containing a bug here."
199+
]
200+
writeFile (example_dir </> "before" </> "Example.hs") before_module
201+
let after_module = unlines [ "module Example where"
202+
, ""
203+
, "-- Insert the fixed example here."
204+
]
205+
writeFile (example_dir </> "after" </> "Example.hs") after_module
206+
pure ()
207+
208+
209+
-------------------------------------------------------------------------------
210+
-- Main
211+
-------------------------------------------------------------------------------
212+
213+
main :: IO ()
214+
main = do
215+
tmpl <- readTemplate
216+
createFiles tmpl

0 commit comments

Comments
 (0)