1
- {-# LANGUAGE OverloadedStrings #-}
2
-
3
- module Lamdera.CLI.Format
4
- ( Format (.. )
5
- , run
6
- , command
1
+ module Lamdera.CLI.Format
2
+ ( run
7
3
) where
8
4
9
- {- `lamdera format` functionality -}
10
-
11
- import qualified Data.Text as T
12
- import qualified Data.Text.IO as TIO
13
- import qualified Ext.ElmFormat as ElmFormat
14
- import qualified System.Exit as Exit
15
- import qualified System.IO as IO
16
- import Terminal hiding (args )
17
- import Terminal.Helpers
18
- import qualified Text.PrettyPrint.ANSI.Leijen as P
19
- import qualified Data.List as List
20
- import qualified System.Directory as Dir
21
- import qualified System.FilePath as FP
22
-
23
- data Format = Format
24
- { _yes :: Bool
25
- , _validate :: Bool
26
- , _stdin :: Bool
27
- , _output :: Maybe FilePath
28
- , _help :: Bool
29
- }
30
-
31
- yes_ :: Parser Bool
32
- yes_ =
33
- Parser
34
- { _singular = " yes"
35
- , _plural = " yes"
36
- , _parser = \ _ -> Just True
37
- , _suggest = \ _ -> return []
38
- , _examples = \ _ -> return []
39
- }
40
-
41
- validate_ :: Parser Bool
42
- validate_ =
43
- Parser
44
- { _singular = " validate"
45
- , _plural = " validate"
46
- , _parser = \ _ -> Just True
47
- , _suggest = \ _ -> return []
48
- , _examples = \ _ -> return []
49
- }
50
-
51
- stdin_ :: Parser Bool
52
- stdin_ =
53
- Parser
54
- { _singular = " stdin"
55
- , _plural = " stdin"
56
- , _parser = \ _ -> Just True
57
- , _suggest = \ _ -> return []
58
- , _examples = \ _ -> return []
59
- }
60
-
61
- output_ :: Parser FilePath
62
- output_ =
63
- Parser
64
- { _singular = " output"
65
- , _plural = " outputs"
66
- , _parser = Just
67
- , _suggest = \ _ -> return []
68
- , _examples = \ _ -> return [" Main2.elm" ]
69
- }
70
-
71
- elmFileOrDir :: Parser FilePath
72
- elmFileOrDir =
73
- Parser
74
- { _singular = " elm file or directory"
75
- , _plural = " elm files or directories"
76
- , _parser = Just -- Accept any path
77
- , _suggest = \ _ -> return []
78
- , _examples = \ _ -> return [" Main.elm" , " src/Main.elm" ]
79
- }
80
-
81
- command :: Terminal. Command
82
- command =
83
- let
84
- summary =
85
- " Format Elm source files."
86
-
87
- details =
88
- " Usage: lamdera format [INPUT] [--output FILE] [--yes] [--validate] [--stdin]\n\n " ++
89
- " Format Elm source files."
90
-
91
- example =
92
- stack
93
- [ reflow " Examples:"
94
- , P. vcat [ P. indent 2 $ P. green " lamdera format Main.elm # formats Main.elm"
95
- , P. indent 2 $ P. green " lamdera format Main.elm --output Main2.elm # formats Main.elm as Main2.elm"
96
- , P. indent 2 $ P. green " lamdera format src/ # format all *.elm files in the src directory"
97
- ]
98
- , reflow " Full guide to using elm-format at <https://github.com/avh4/elm-format>"
99
- ]
100
-
101
- formatFlags =
102
- flags Format
103
- |-- onOff " yes" " Reply 'yes' to all automated prompts."
104
- |-- onOff " validate" " Check if files are formatted without changing them."
105
- |-- onOff " stdin" " Read from stdin, output to stdout."
106
- |-- flag " output" output_ " Write output to FILE instead of overwriting the given source file."
107
- |-- onOff " help" " Show this help text."
108
- in
109
- Terminal. Command " format" (Common summary) details example (zeroOrMore elmFileOrDir) formatFlags run
110
-
111
- run :: [FilePath ] -> Format -> IO ()
112
- run inputs flags =
113
- if _help flags || null inputs && not (_stdin flags)
114
- then do
115
- TIO. putStrLn " Usage: lamdera format [INPUT] [--output FILE] [--yes] [--validate] [--stdin]\n "
116
- TIO. putStrLn " Format Elm source files.\n "
117
- TIO. putStrLn " Available options:"
118
- TIO. putStrLn " --help Show this help text"
119
- TIO. putStrLn " --output FILE Write output to FILE instead of overwriting the given"
120
- TIO. putStrLn " source file."
121
- TIO. putStrLn " --yes Reply 'yes' to all automated prompts."
122
- TIO. putStrLn " --validate Check if files are formatted without changing them."
123
- TIO. putStrLn " --stdin Read from stdin, output to stdout.\n "
124
- TIO. putStrLn " Examples:"
125
- TIO. putStrLn " lamdera format Main.elm # formats Main.elm"
126
- TIO. putStrLn " lamdera format Main.elm --output Main2.elm # formats Main.elm as Main2.elm"
127
- TIO. putStrLn " lamdera format src/ # format all *.elm files in the src directory\n "
128
- TIO. putStrLn " Full guide to using elm-format at <https://github.com/avh4/elm-format>"
129
- Exit. exitSuccess
130
- else case inputs of
131
- [] | _stdin flags ->
132
- do
133
- input <- TIO. hGetContents IO. stdin
134
- formatText flags input
135
- [] ->
136
- do
137
- TIO. putStrLn " Please specify at least one .elm file to format."
138
- Exit. exitFailure
139
- paths ->
140
- do
141
- elmFilePaths <- concat <$> mapM expandPath paths
142
- if null elmFilePaths
143
- then return ()
144
- else do
145
- TIO. putStrLn " This will overwrite the following files to use Elm's preferred style:\n "
146
- mapM_ (\ f -> TIO. putStrLn $ " " <> T. pack f) elmFilePaths
147
- TIO. putStrLn " \n This cannot be undone! Make sure to back up these files before proceeding.\n "
148
- if _yes flags
149
- then formatFiles flags elmFilePaths
150
- else do
151
- TIO. putStrLn " Are you sure you want to overwrite these files with formatted versions? (y/n) "
152
- answer <- getLine
153
- case answer of
154
- " Y" -> formatFiles flags elmFilePaths
155
- " y" -> formatFiles flags elmFilePaths
156
- " " -> formatFiles flags elmFilePaths
157
- _ -> return ()
158
-
159
- expandPath :: FilePath -> IO [FilePath ]
160
- expandPath path = do
161
- isDir <- Dir. doesDirectoryExist path
162
- if isDir
163
- then findElmFiles path
164
- else return [path | FP. isExtensionOf " elm" path]
165
-
166
- formatText :: Format -> T. Text -> IO ()
167
- formatText flags input =
168
- case ElmFormat. format " stdin:nofilepath" input of
169
- Right formatted ->
170
- TIO. putStr formatted
171
- Left err ->
172
- do
173
- TIO. putStrLn $ " Error: " <> err
174
- Exit. exitFailure
175
-
176
- formatFile :: Format -> FilePath -> IO ()
177
- formatFile flags path = do
178
- isDir <- Dir. doesDirectoryExist path
179
- if isDir
180
- then do
181
- elmFilePaths <- findElmFiles path
182
- if null elmFilePaths
183
- then return ()
184
- else do
185
- TIO. putStrLn " This will overwrite the following files to use Elm's preferred style:\n "
186
- mapM_ (\ f -> TIO. putStrLn $ " " <> T. pack f) elmFilePaths
187
- TIO. putStrLn " \n This cannot be undone! Make sure to back up these files before proceeding.\n "
188
- if _yes flags
189
- then formatFiles flags elmFilePaths
190
- else do
191
- TIO. putStrLn " Are you sure you want to overwrite these files with formatted versions? (y/n) "
192
- answer <- getLine
193
- case answer of
194
- " Y" -> formatFiles flags elmFilePaths
195
- " y" -> formatFiles flags elmFilePaths
196
- " " -> formatFiles flags elmFilePaths
197
- _ -> return ()
198
- else formatSingleFile flags path
199
-
200
- findElmFiles :: FilePath -> IO [FilePath ]
201
- findElmFiles dir = do
202
- contents <- Dir. listDirectory dir
203
- let baseName = FP. takeFileName dir
204
- if baseName `elem` [" elm-stuff" , " node_modules" ]
205
- then return []
206
- else do
207
- paths <- mapM (\ f -> do
208
- let path = dir FP. </> f
209
- isDir <- Dir. doesDirectoryExist path
210
- if isDir
211
- then findElmFiles path
212
- else return [path | FP. isExtensionOf " elm" f]
213
- ) contents
214
- return $ concat paths
215
-
216
- formatFiles :: Format -> [FilePath ] -> IO ()
217
- formatFiles flags = mapM_ (formatSingleFile flags)
218
-
219
- formatSingleFile :: Format -> FilePath -> IO ()
220
- formatSingleFile flags path = do
221
- TIO. putStrLn $ " Processing file " <> T. pack path
222
- input <- TIO. readFile path
223
- case ElmFormat. format path input of
224
- Right formatted ->
225
- if _validate flags && formatted /= input
226
- then do
227
- TIO. putStrLn $ " File " <> T. pack path <> " would be reformatted"
228
- Exit. exitFailure
229
- else case _output flags of
230
- Just outputPath -> TIO. writeFile outputPath formatted
231
- Nothing -> TIO. writeFile path formatted
232
- Left err -> do
233
- TIO. putStrLn err
234
- if _validate flags
235
- then Exit. exitFailure
236
- else return ()
237
-
238
- stack :: [P. Doc ] -> P. Doc
239
- stack docs =
240
- P. vcat $ List. intersperse " " docs
5
+ import qualified ElmFormat.Cli
241
6
242
- reflow :: String -> P. Doc
243
- reflow string =
244
- P. fillSep $ map P. text $ words string
7
+ -- | Delegate to elm-format
8
+ run :: [ String ] -> IO ()
9
+ run args = ElmFormat.Cli. mainIO args
0 commit comments