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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
#!/usr/bin/env runhaskell
{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
import Control.Monad
import Data.Maybe
import Distribution.Simple.Utils
import Distribution.Verbosity
import System.Console.GetOpt
import System.Directory
import System.Environment
import System.Exit
import System.FilePath
import System.IO
import System.Process
baseDir, rootDir :: FilePath
baseDir = takeDirectory __FILE__
rootDir = baseDir </> ".."
srcDir, refDir, outDir :: FilePath
srcDir = baseDir </> "src"
refDir = baseDir </> "ref"
outDir = baseDir </> "out"
resDir :: FilePath
resDir = rootDir </> "resources"
data Config = Config
{ cfgHaddockPath :: FilePath
, cfgGhcPath :: FilePath
, cfgFiles :: [FilePath]
}
main :: IO ()
main = do
Config { .. } <- loadConfig =<< getArgs
return ()
loadConfig :: [String] -> IO Config
loadConfig args = do
let (flags, files, errors) = getOpt Permute options args
when (not $ null errors) $ do
hPutStr stderr $ concat errors
exitFailure
when (FlagHelp `elem` flags) $ do
hPutStrLn stderr $ usageInfo "" options
exitSuccess
env <- Just . (:) ("haddock_datadir", resDir) <$> getEnvironment
let cfgHaddockPath = flagsHaddockPath flags
printVersions env cfgHaddockPath
cfgFiles <- processFileArgs files
cfgGhcPath <- init <$> rawSystemStdout normal cfgHaddockPath
["--print-ghc-path"]
putStrLn $ "Files to test: " ++ show cfgFiles
return $ Config { .. }
printVersions :: Maybe [(String, String)] -> FilePath -> IO ()
printVersions env haddockPath = do
handle <- runProcess' haddockPath $ processConfig
{ pcEnv = env
, pcArgs = ["--version"]
}
waitForSuccess "Failed to run `haddock --version`" handle
handle <- runProcess' haddockPath $ processConfig
{ pcEnv = env
, pcArgs = ["--ghc-version"]
}
waitForSuccess "Failed to run `haddock --ghc-version`" handle
processFileArgs :: [String] -> IO [FilePath]
processFileArgs [] = filter isSourceFile <$> getDirectoryContents srcDir
processFileArgs args = pure $ map processFileArg args
processFileArg :: String -> FilePath
processFileArg arg
| isSourceFile arg = arg
| otherwise = srcDir </> arg <.> "hs"
isSourceFile :: FilePath -> Bool
isSourceFile path = takeExtension path `elem` [".hs", ".lhs"]
data Flag
= FlagHaddockPath FilePath
| FlagHelp
deriving Eq
options :: [OptDescr Flag]
options =
[ Option [] ["haddock-path"] (ReqArg FlagHaddockPath "FILE")
"path to Haddock executable to exectue tests with"
, Option ['h'] ["help"] (NoArg FlagHelp)
"display this help end exit"
]
flagsHaddockPath :: [Flag] -> FilePath
flagsHaddockPath flags =
case mlast [ path | FlagHaddockPath path <- flags ] of
Just path -> path
Nothing -> rootDir </> "dist" </> "build" </> "haddock" </> "haddock"
where
mlast = listToMaybe . reverse
data ProcessConfig = ProcessConfig
{ pcArgs :: [String]
, pcWorkDir :: Maybe FilePath
, pcEnv :: Maybe [(String, String)]
, pcStdIn :: Maybe Handle
, pcStdOut :: Maybe Handle
, pcStdErr :: Maybe Handle
}
processConfig :: ProcessConfig
processConfig = ProcessConfig
{ pcArgs = []
, pcWorkDir = Nothing
, pcEnv = Nothing
, pcStdIn = Nothing
, pcStdOut = Nothing
, pcStdErr = Nothing
}
runProcess' :: FilePath -> ProcessConfig -> IO ProcessHandle
runProcess' path (ProcessConfig { .. }) = runProcess
path pcArgs pcWorkDir pcEnv pcStdIn pcStdOut pcStdErr
waitForSuccess :: String -> ProcessHandle -> IO ()
waitForSuccess msg handle = do
result <- waitForProcess handle
unless (result == ExitSuccess) $ do
hPutStrLn stderr $ msg
exitFailure
|