9
9
module Main where
10
10
11
11
import Control.Concurrent (Chan , forkIO , newChan , readChan , writeChan )
12
- import Data.Bifunctor (first )
13
12
import Data.Either (lefts )
14
13
import Data.Text (Text )
15
14
import Data.Version (showVersion )
@@ -24,7 +23,7 @@ import System.Posix.Signals (Handler(..), installHandler, keyboardSignal)
24
23
25
24
import qualified Data.Text.IO as TextIO (getContents , hPutStr , putStr )
26
25
27
- import Nixfmt
26
+ import qualified Nixfmt
28
27
import System.IO.Atomic (withOutputFile )
29
28
import System.IO.Utf8 (readFileUtf8 , withUtf8StdHandles )
30
29
@@ -36,6 +35,7 @@ data Nixfmt = Nixfmt
36
35
, width :: Width
37
36
, check :: Bool
38
37
, quiet :: Bool
38
+ , verify :: Bool
39
39
} deriving (Show , Data , Typeable )
40
40
41
41
options :: Nixfmt
@@ -44,30 +44,28 @@ options = Nixfmt
44
44
, width = 80 &= help " Maximum width in characters"
45
45
, check = False &= help " Check whether files are formatted"
46
46
, quiet = False &= help " Do not report errors"
47
+ , verify = False &= help " Check that the output parses and formats the same as the input"
47
48
} &= summary (" nixfmt v" ++ showVersion version)
48
49
&= help " Format Nix source code"
49
50
50
- format' :: Width -> FilePath -> Text -> Either String Text
51
- format' w path = first errorBundlePretty . format w path
52
-
53
51
data Target = Target
54
52
{ tDoRead :: IO Text
55
53
, tPath :: FilePath
56
54
, tDoWrite :: Text -> IO ()
57
55
}
58
56
59
- formatTarget :: Width -> Target -> IO Result
60
- formatTarget w Target {tDoRead, tPath, tDoWrite} = do
57
+ formatTarget :: Formatter -> Target -> IO Result
58
+ formatTarget format Target {tDoRead, tPath, tDoWrite} = do
61
59
contents <- tDoRead
62
- let formatted = format' w tPath contents
60
+ let formatted = format tPath contents
63
61
mapM tDoWrite formatted
64
62
65
63
-- | Return an error if target could not be parsed or was not formatted
66
64
-- correctly.
67
- checkTarget :: Width -> Target -> IO Result
68
- checkTarget w Target {tDoRead, tPath} = do
65
+ checkTarget :: Formatter -> Target -> IO Result
66
+ checkTarget format Target {tDoRead, tPath} = do
69
67
contents <- tDoRead
70
- return $ case format' w tPath contents of
68
+ return $ case format tPath contents of
71
69
Left err -> Left err
72
70
Right formatted
73
71
| formatted == contents -> Right ()
@@ -87,16 +85,24 @@ toTargets :: Nixfmt -> [Target]
87
85
toTargets Nixfmt { files = [] } = [stdioTarget]
88
86
toTargets Nixfmt { files = paths } = map fileTarget paths
89
87
90
- toOperation :: Nixfmt -> Target -> IO Result
91
- toOperation Nixfmt { width = w, check = True } = checkTarget w
92
- toOperation Nixfmt { width = w } = formatTarget w
88
+ type Formatter = FilePath -> Text -> Either String Text
89
+
90
+ toFormatter :: Nixfmt -> Formatter
91
+ toFormatter Nixfmt { width, verify = True } = Nixfmt. formatVerify width
92
+ toFormatter Nixfmt { width, verify = False } = Nixfmt. format width
93
+
94
+ type Operation = Formatter -> Target -> IO Result
95
+
96
+ toOperation :: Nixfmt -> Operation
97
+ toOperation Nixfmt { check = True } = checkTarget
98
+ toOperation Nixfmt { } = formatTarget
93
99
94
100
toWriteError :: Nixfmt -> String -> IO ()
95
101
toWriteError Nixfmt { quiet = False } = hPutStrLn stderr
96
102
toWriteError Nixfmt { quiet = True } = const $ return ()
97
103
98
104
toJobs :: Nixfmt -> [IO Result ]
99
- toJobs opts = map (toOperation opts) $ toTargets opts
105
+ toJobs opts = map (toOperation opts $ toFormatter opts ) $ toTargets opts
100
106
101
107
-- TODO: Efficient parallel implementation. This is just a sequential stub.
102
108
-- This was originally implemented using parallel-io, but it gave a factor two
0 commit comments