1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
--------------------------------------------------------------------------------
{-# LANGUAGE DeriveDataTypeable #-}
module Main
( main
) where
--------------------------------------------------------------------------------
import Control.Monad (forM_)
import Data.List (intercalate)
import Data.Version (Version(..))
import System.Console.CmdArgs
import System.IO (hPutStrLn, stderr, withFile, hSetEncoding, IOMode(ReadMode), utf8)
import System.IO.Strict (hGetContents)
--------------------------------------------------------------------------------
import Language.Haskell.Stylish
--------------------------------------------------------------------------------
data StylishArgs = StylishArgs
{ config :: Maybe FilePath
, verbose :: Bool
, defaults :: Bool
, inPlace :: Bool
, files :: [FilePath]
} deriving (Data, Show, Typeable)
--------------------------------------------------------------------------------
stylishArgs :: StylishArgs
stylishArgs = StylishArgs
{ config = Nothing &= typFile &= help "Configuration file"
, verbose = False &= help "Run in verbose mode"
, defaults = False &= help "Dump default config and exit"
, inPlace = False &= help "Overwrite the given files in place"
, files = [] &= typFile &= args
} &= summary ("stylish-haskell-" ++ versionString version)
where
versionString = intercalate "." . map show . versionBranch
--------------------------------------------------------------------------------
main :: IO ()
main = cmdArgs stylishArgs >>= stylishHaskell
--------------------------------------------------------------------------------
stylishHaskell :: StylishArgs -> IO ()
stylishHaskell sa
| defaults sa = do
fileName <- defaultConfigFilePath
verbose' $ "Dumping config from " ++ fileName
readUTF8File fileName >>= putStr
| otherwise = do
conf <- loadConfig verbose' (config sa)
let steps = configSteps conf
forM_ steps $ \s -> verbose' $ "Enabled " ++ stepName s ++ " step"
verbose' $ "Extra language extensions: " ++
show (configLanguageExtensions conf)
mapM_ (file sa conf) files'
where
verbose' = makeVerbose (verbose sa)
files' = if null (files sa) then [Nothing] else map Just (files sa)
--------------------------------------------------------------------------------
-- | Processes a single file, or stdin if no filepath is given
file :: StylishArgs -> Config -> Maybe FilePath -> IO ()
file sa conf mfp = do
contents <- maybe getContents readUTF8File mfp
let result = runSteps (configLanguageExtensions conf)
mfp (configSteps conf) $ lines contents
case result of
Left err -> hPutStrLn stderr err >> write contents contents
Right ok -> write contents $ unlines ok
where
write old new = case mfp of
Nothing -> putStr new
Just _ | not (inPlace sa) -> putStr new
Just path | length new /= 0 && old /= new -> writeFile path new
_ -> return ()
readUTF8File :: FilePath -> IO String
readUTF8File fp =
withFile fp ReadMode $ \h -> do
hSetEncoding h utf8
content <- hGetContents h
return content
|