@@ -82,32 +82,32 @@ import System.Info ( arch, os )
82
82
83
83
run' :: HasCallStack => FilePath -> [String ] -> IO ExitCode
84
84
run' cmd args = do
85
- logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
86
- (Nothing , Nothing , Nothing , ph) <- createProcess (proc cmd args)
87
- waitForProcess ph
85
+ logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
86
+ (Nothing , Nothing , Nothing , ph) <- createProcess (proc cmd args)
87
+ waitForProcess ph
88
88
89
89
run :: HasCallStack => FilePath -> [String ] -> IO ()
90
90
run cmd args = do
91
- ec <- run' cmd args
92
- unless (ec == ExitSuccess ) $
93
- error $ " Exited with exit code: " ++ displayException ec
91
+ ec <- run' cmd args
92
+ unless (ec == ExitSuccess ) $
93
+ error $ " Exited with exit code: " ++ displayException ec
94
94
95
95
runShell :: HasCallStack => String -> IO ()
96
96
runShell cmd = do
97
- logInfo $ " Running: " ++ cmd
98
- (Nothing , Nothing , Nothing , ph) <- createProcess (shell cmd)
99
- ec <- waitForProcess ph
100
- unless (ec == ExitSuccess ) $
101
- error $ " Exited with exit code: " ++ displayException ec
97
+ logInfo $ " Running: " ++ cmd
98
+ (Nothing , Nothing , Nothing , ph) <- createProcess (shell cmd)
99
+ ec <- waitForProcess ph
100
+ unless (ec == ExitSuccess ) $
101
+ error $ " Exited with exit code: " ++ displayException ec
102
102
103
103
runWithCwd :: HasCallStack => FilePath -> String -> [String ] -> IO String
104
104
runWithCwd cwdPath cmd args = do
105
- logInfo $ " Running: " ++ cmd
106
- let cp = proc cmd args
107
- (ec, stdoutStr, _) <- readCreateProcessWithExitCode (cp { cwd = Just cwdPath }) " "
108
- unless (ec == ExitSuccess ) $
109
- error $ " Exited with exit code: " ++ displayException ec
110
- pure stdoutStr
105
+ logInfo $ " Running: " ++ cmd
106
+ let cp = proc cmd args
107
+ (ec, stdoutStr, _) <- readCreateProcessWithExitCode (cp { cwd = Just cwdPath }) " "
108
+ unless (ec == ExitSuccess ) $
109
+ error $ " Exited with exit code: " ++ displayException ec
110
+ pure stdoutStr
111
111
112
112
stackExe :: IO String
113
113
stackExe = getEnv " STACK_EXE"
@@ -120,186 +120,198 @@ testDir = getEnv "TEST_DIR"
120
120
121
121
stack' :: HasCallStack => [String ] -> IO ExitCode
122
122
stack' args = do
123
- stackEnv <- stackExe
124
- run' stackEnv args
123
+ stackEnv <- stackExe
124
+ run' stackEnv args
125
125
126
126
stack :: HasCallStack => [String ] -> IO ()
127
127
stack args = do
128
- ec <- stack' args
129
- unless (ec == ExitSuccess ) $
130
- error $ " Exited with exit code: " ++ displayException ec
128
+ ec <- stack' args
129
+ unless (ec == ExitSuccess ) $
130
+ error $ " Exited with exit code: " ++ displayException ec
131
131
132
- -- Temporary workaround for Windows to ignore exceptions arising out
133
- -- of Windows when we do stack clean. More info here: https://github.com/commercialhaskell/stack/issues/4936
132
+ -- Temporary workaround for Windows to ignore exceptions arising out of Windows
133
+ -- when we do stack clean. More info here:
134
+ -- https://github.com/commercialhaskell/stack/issues/4936
134
135
stackCleanFull :: HasCallStack => IO ()
135
136
stackCleanFull = stackIgnoreException [" clean" , " --full" ]
136
137
137
- -- Temporary workaround for Windows to ignore exceptions arising out
138
- -- of Windows when we do stack clean. More info here: https://github.com/commercialhaskell/stack/issues/4936
138
+ -- Temporary workaround for Windows to ignore exceptions arising out of Windows
139
+ -- when we do stack clean. More info here:
140
+ -- https://github.com/commercialhaskell/stack/issues/4936
139
141
stackIgnoreException :: HasCallStack => [String ] -> IO ()
140
- stackIgnoreException args = if isWindows
141
- then void (stack' args) `catch` (\ (_e :: IOException ) -> pure () )
142
- else stack args
142
+ stackIgnoreException args =
143
+ if isWindows
144
+ then void (stack' args) `catch` (\ (_e :: IOException ) -> pure () )
145
+ else stack args
143
146
144
147
stackErr :: HasCallStack => [String ] -> IO ()
145
148
stackErr args = do
146
- ec <- stack' args
147
- when (ec == ExitSuccess ) $ error " stack was supposed to fail, but didn't"
149
+ ec <- stack' args
150
+ when (ec == ExitSuccess ) $ error " stack was supposed to fail, but didn't"
148
151
149
152
type Repl = ReaderT ReplConnection IO
150
153
151
- data ReplConnection
152
- = ReplConnection
153
- { replStdin :: Handle
154
- , replStdout :: Handle
155
- }
154
+ data ReplConnection = ReplConnection
155
+ { replStdin :: Handle
156
+ , replStdout :: Handle
157
+ }
156
158
157
159
nextPrompt :: Repl ()
158
160
nextPrompt = do
159
- (ReplConnection _ inputHandle) <- ask
160
- c <- liftIO $ hGetChar inputHandle
161
- if c == ' >'
162
- then do _ <- liftIO $ hGetChar inputHandle
163
- pure ()
164
- else nextPrompt
161
+ (ReplConnection _ replStdoutHandle) <- ask
162
+ c <- liftIO $ hGetChar replStdoutHandle
163
+ if c == ' >'
164
+ then do
165
+ -- Skip next character
166
+ _ <- liftIO $ hGetChar replStdoutHandle
167
+ pure ()
168
+ else nextPrompt
165
169
166
170
replCommand :: String -> Repl ()
167
171
replCommand cmd = do
168
- (ReplConnection input _) <- ask
169
- liftIO $ hPutStrLn input cmd
172
+ (ReplConnection replStdinHandle _) <- ask
173
+ liftIO $ hPutStrLn replStdinHandle cmd
170
174
171
175
replGetLine :: Repl String
172
176
replGetLine = ask >>= liftIO . hGetLine . replStdout
173
177
174
178
replGetChar :: Repl Char
175
179
replGetChar = ask >>= liftIO . hGetChar . replStdout
176
180
177
- runRepl :: HasCallStack => FilePath -> [String ] -> ReaderT ReplConnection IO () -> IO ExitCode
181
+ runRepl ::
182
+ HasCallStack
183
+ => FilePath
184
+ -> [String ]
185
+ -> ReaderT ReplConnection IO ()
186
+ -> IO ExitCode
178
187
runRepl cmd args actions = do
179
- logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
180
- (Just rStdin, Just rStdout, Just rStderr, ph) <-
181
- createProcess (proc cmd args)
182
- { std_in = CreatePipe
183
- , std_out = CreatePipe
184
- , std_err = CreatePipe
185
- }
186
- hSetBuffering rStdin NoBuffering
187
- hSetBuffering rStdout NoBuffering
188
- hSetBuffering rStderr NoBuffering
189
-
190
- tempDir <- if isWindows
191
- then fromMaybe " " <$> lookupEnv " TEMP"
192
- else pure " /tmp"
193
- let tempFP = tempDir ++ " /stderr"
194
-
195
- _ <- forkIO $ withFile tempFP WriteMode
196
- $ \ err -> do
197
- hSetBuffering err NoBuffering
198
- forever $ catch (hGetChar rStderr >>= hPutChar err)
199
- $ \ e -> unless (isEOFError e) $ throw e
200
-
201
- runReaderT (nextPrompt >> actions) (ReplConnection rStdin rStdout)
202
- waitForProcess ph
188
+ logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
189
+ (Just rStdin, Just rStdout, Just rStderr, ph) <-
190
+ createProcess (proc cmd args)
191
+ { std_in = CreatePipe
192
+ , std_out = CreatePipe
193
+ , std_err = CreatePipe
194
+ }
195
+ hSetBuffering rStdin NoBuffering
196
+ hSetBuffering rStdout NoBuffering
197
+ hSetBuffering rStderr NoBuffering
198
+ -- Log stack repl's standard error output
199
+ tempDir <- if isWindows
200
+ then fromMaybe " " <$> lookupEnv " TEMP"
201
+ else pure " /tmp"
202
+ let tempLogFile = tempDir ++ " /stderr"
203
+ _ <- forkIO $ withFile tempLogFile WriteMode $ \ logFileHandle -> do
204
+ hSetBuffering logFileHandle NoBuffering
205
+ forever $
206
+ catch
207
+ (hGetChar rStderr >>= hPutChar logFileHandle)
208
+ (\ e -> unless (isEOFError e) $ throw e)
209
+ runReaderT (nextPrompt >> actions) (ReplConnection rStdin rStdout)
210
+ waitForProcess ph
203
211
204
212
repl :: HasCallStack => [String ] -> Repl () -> IO ()
205
213
repl args action = do
206
- stackExe' <- stackExe
207
- ec <- runRepl stackExe' (" repl" : args) action
208
- unless (ec == ExitSuccess ) $ pure ()
209
- -- TODO: Understand why the exit code is 1 despite running GHCi tests
210
- -- successfully.
211
- -- else error $ "Exited with exit code: " ++ show ec
214
+ stackExe' <- stackExe
215
+ ec <- runRepl stackExe' (" repl" : args) action
216
+ unless (ec == ExitSuccess ) $ pure ()
217
+ -- TODO: Understand why the exit code is 1 despite running GHCi tests
218
+ -- successfully.
219
+ -- else error $ "Exited with exit code: " ++ show ec
212
220
213
221
stackStderr :: HasCallStack => [String ] -> IO (ExitCode , String )
214
222
stackStderr args = do
215
- stackExe' <- stackExe
216
- logInfo $ " Running: " ++ stackExe' ++ " " ++ unwords (map showProcessArgDebug args)
217
- (ec, _, err) <- readProcessWithExitCode stackExe' args " "
218
- hPutStr stderr err
219
- pure (ec, err)
220
-
221
- -- | Run stack with arguments and apply a check to the resulting
222
- -- stderr output if the process succeeded.
223
+ stackExe' <- stackExe
224
+ logInfo $
225
+ " Running: "
226
+ ++ stackExe'
227
+ ++ " "
228
+ ++ unwords (map showProcessArgDebug args)
229
+ (ec, _, err) <- readProcessWithExitCode stackExe' args " "
230
+ hPutStr stderr err
231
+ pure (ec, err)
232
+
233
+ -- | Run stack with arguments and apply a check to the resulting stderr output
234
+ -- if the process succeeded.
223
235
stackCheckStderr :: HasCallStack => [String ] -> (String -> IO () ) -> IO ()
224
236
stackCheckStderr args check = do
225
- (ec, err) <- stackStderr args
226
- if ec /= ExitSuccess
227
- then error $ " Exited with exit code: " ++ displayException ec
228
- else check err
237
+ (ec, err) <- stackStderr args
238
+ if ec /= ExitSuccess
239
+ then error $ " Exited with exit code: " ++ displayException ec
240
+ else check err
229
241
230
242
-- | Same as 'stackCheckStderr', but ensures that the Stack process
231
243
-- fails.
232
244
stackErrStderr :: HasCallStack => [String ] -> (String -> IO () ) -> IO ()
233
245
stackErrStderr args check = do
234
- (ec, err) <- stackStderr args
235
- if ec == ExitSuccess
236
- then error " Stack process succeeded, but it shouldn't"
237
- else check err
246
+ (ec, err) <- stackStderr args
247
+ if ec == ExitSuccess
248
+ then error " Stack process succeeded, but it shouldn't"
249
+ else check err
238
250
239
251
runEx :: HasCallStack => FilePath -> String -> IO (ExitCode , String , String )
240
252
runEx cmd args = runEx' cmd $ words args
241
253
242
254
runEx' :: HasCallStack => FilePath -> [String ] -> IO (ExitCode , String , String )
243
255
runEx' cmd args = do
244
- logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
245
- (ec, out, err) <- readProcessWithExitCode cmd args " "
246
- putStr out
247
- hPutStr stderr err
248
- pure (ec, out, err)
249
-
250
- -- | Run stack with arguments and apply a check to the resulting
251
- -- stdout output if the process succeeded.
256
+ logInfo $ " Running: " ++ cmd ++ " " ++ unwords (map showProcessArgDebug args)
257
+ (ec, out, err) <- readProcessWithExitCode cmd args " "
258
+ putStr out
259
+ hPutStr stderr err
260
+ pure (ec, out, err)
261
+
262
+ -- | Run stack with arguments and apply a check to the resulting stdout output
263
+ -- if the process succeeded.
252
264
--
253
265
-- Take care with newlines; if the output includes a newline character that
254
266
-- should not be there, use 'Data.List.Extra.trimEnd' to remove it.
255
267
stackCheckStdout :: HasCallStack => [String ] -> (String -> IO () ) -> IO ()
256
268
stackCheckStdout args check = do
257
- stackExe' <- stackExe
258
- (ec, out, _) <- runEx' stackExe' args
259
- if ec /= ExitSuccess
260
- then error $ " Exited with exit code: " ++ displayException ec
261
- else check out
269
+ stackExe' <- stackExe
270
+ (ec, out, _) <- runEx' stackExe' args
271
+ if ec /= ExitSuccess
272
+ then error $ " Exited with exit code: " ++ displayException ec
273
+ else check out
262
274
263
275
doesNotExist :: HasCallStack => FilePath -> IO ()
264
276
doesNotExist fp = do
265
- logInfo $ " doesNotExist " ++ fp
266
- exists <- doesFileOrDirExist fp
267
- case exists of
268
- (Right msg) -> error msg
269
- (Left _) -> pure ()
277
+ logInfo $ " doesNotExist " ++ fp
278
+ exists <- doesFileOrDirExist fp
279
+ case exists of
280
+ (Right msg) -> error msg
281
+ (Left _) -> pure ()
270
282
271
283
doesExist :: HasCallStack => FilePath -> IO ()
272
284
doesExist fp = do
273
- logInfo $ " doesExist " ++ fp
274
- exists <- doesFileOrDirExist fp
275
- case exists of
276
- (Right _) -> pure ()
277
- (Left _) -> error " No file or directory exists"
285
+ logInfo $ " doesExist " ++ fp
286
+ exists <- doesFileOrDirExist fp
287
+ case exists of
288
+ (Right _) -> pure ()
289
+ (Left _) -> error " No file or directory exists"
278
290
279
291
doesFileOrDirExist :: HasCallStack => FilePath -> IO (Either () String )
280
292
doesFileOrDirExist fp = do
281
- isFile <- doesFileExist fp
282
- if isFile
283
- then pure (Right (" File exists: " ++ fp))
284
- else do
285
- isDir <- doesDirectoryExist fp
286
- if isDir
287
- then pure (Right (" Directory exists: " ++ fp))
288
- else pure (Left () )
293
+ isFile <- doesFileExist fp
294
+ if isFile
295
+ then pure (Right (" File exists: " ++ fp))
296
+ else do
297
+ isDir <- doesDirectoryExist fp
298
+ if isDir
299
+ then pure (Right (" Directory exists: " ++ fp))
300
+ else pure (Left () )
289
301
290
302
copy :: HasCallStack => FilePath -> FilePath -> IO ()
291
303
copy src dest = do
292
- logInfo (" Copy " ++ show src ++ " to " ++ show dest)
293
- System.Directory. copyFile src dest
304
+ logInfo (" Copy " ++ show src ++ " to " ++ show dest)
305
+ System.Directory. copyFile src dest
294
306
295
307
fileContentsMatch :: HasCallStack => FilePath -> FilePath -> IO ()
296
308
fileContentsMatch f1 f2 = do
297
- doesExist f1
298
- doesExist f2
299
- f1Contents <- readFile f1
300
- f2Contents <- readFile f2
301
- unless (f1Contents == f2Contents) $
302
- error (" contents do not match for " ++ show f1 ++ " " ++ show f2)
309
+ doesExist f1
310
+ doesExist f2
311
+ f1Contents <- readFile f1
312
+ f2Contents <- readFile f2
313
+ unless (f1Contents == f2Contents) $
314
+ error (" contents do not match for " ++ show f1 ++ " " ++ show f2)
303
315
304
316
logInfo :: String -> IO ()
305
317
logInfo = hPutStrLn stderr
@@ -311,12 +323,12 @@ logInfo = hPutStrLn stderr
311
323
-- debugging purposes, not functionally important.
312
324
showProcessArgDebug :: String -> String
313
325
showProcessArgDebug x
314
- | any special x = show x
315
- | otherwise = x
316
- where
317
- special ' "' = True
318
- special ' ' = True
319
- special _ = False
326
+ | any special x = show x
327
+ | otherwise = x
328
+ where
329
+ special ' "' = True
330
+ special ' ' = True
331
+ special _ = False
320
332
321
333
-- | Extension of executables
322
334
exeExt :: String
@@ -391,6 +403,7 @@ superslow inner = do
391
403
logInfo " Running superslow test, hold on to your butts"
392
404
inner
393
405
Nothing -> do
394
- logInfo " No STACK_TEST_SPEED specified. Executing superslow test, hold on to your butts"
406
+ logInfo " No STACK_TEST_SPEED specified. Executing superslow test, hold \
407
+ \on to your butts"
395
408
inner
396
409
Just x -> error $ " Invalid value for STACK_TEST_SPEED env var: " ++ show x
0 commit comments