55-}
66module Processor where
77
8- import Control.Monad ( forM_ , void , when )
9- import Data.Maybe (fromJust , isJust )
8+ import Control.Monad.Reader
9+ import Data.Maybe (fromJust , isJust )
1010import System.Exit
11- import System.FilePath ((</>) )
11+ import System.FilePath ((</>) )
1212import System.IO
1313import System.Process
1414
1515import DirectoryUtils
1616import TerminalUtils
1717import Types
1818
19- executeExercise :: ProgramConfig -> ExerciseInfo -> IO ()
20- executeExercise config exInfo@ (ExerciseInfo exerciseName _ _ _) = do
21- let (processSpec, genDirPath, genExecutablePath) = createExerciseProcess config exInfo
22- let exFilename = haskellFileName exerciseName
19+ executeExercise :: ExerciseInfo -> ReaderT ProgramConfig IO ()
20+ executeExercise exInfo@ (ExerciseInfo exerciseName _ _ _) = do
21+ config <- ask
22+ let (processSpec, genDirPath, genExecutablePath, exFilename) = createExerciseProcess config exInfo
2323 withDirectory genDirPath $ do
24- (_, _, procStdErr, procHandle) <- createProcess (processSpec { std_out = CreatePipe , std_err = CreatePipe })
25- exitCode <- waitForProcess procHandle
24+ (_, _, procStdErr, procHandle) <- lift $ createProcess (processSpec { std_out = CreatePipe , std_err = CreatePipe })
25+ exitCode <- lift $ waitForProcess procHandle
2626 case exitCode of
27- ExitFailure code -> void $ onCompileFailure config exFilename procStdErr
27+ ExitFailure code -> void $ onCompileFailure exFilename procStdErr
2828 ExitSuccess -> do
29- progPutStrLnSuccess config $ " Successfully compiled: " ++ exFilename
30- progPutStrLn config $ " ----- Executing file: " ++ exFilename ++ " -----"
29+ progPutStrLnSuccess $ " Successfully compiled: " ++ exFilename
30+ progPutStrLn $ " ----- Executing file: " ++ exFilename ++ " -----"
3131 let execSpec = shell genExecutablePath
32- (_, _, _, execProcHandle) <- createProcess execSpec
33- void $ waitForProcess execProcHandle
32+ (_, _, _, execProcHandle) <- lift $ createProcess execSpec
33+ void $ lift $ waitForProcess execProcHandle
3434
3535-- Produces 3 Elements for running our exercise:
3636-- 1. The 'CreateProcess' that we can run for the compilation.
3737-- 2. The directory path for the generated files
3838-- 3. The path of the executable we would run (assuming the exercise is executable).
39- createExerciseProcess :: ProgramConfig -> ExerciseInfo -> (CreateProcess , FilePath , FilePath )
39+ createExerciseProcess :: ProgramConfig -> ExerciseInfo -> (CreateProcess , FilePath , FilePath , FilePath )
4040createExerciseProcess config (ExerciseInfo exerciseName exDirectory exType _) =
41- (processSpec, genDirPath, genExecutablePath)
41+ (processSpec, genDirPath, genExecutablePath, haskellFileName exerciseName )
4242 where
4343 exIsRunnable = exType /= CompileOnly
4444 exFilename = haskellFileName exerciseName
@@ -51,88 +51,87 @@ createExerciseProcess config (ExerciseInfo exerciseName exDirectory exType _) =
5151 finalArgs = execArgs ++ [" -package-db" , packageDb config]
5252 processSpec = proc (ghcPath config) finalArgs
5353
54- onCompileFailure :: ProgramConfig -> String -> Maybe Handle -> IO RunResult
55- onCompileFailure config exFilename errHandle = withTerminalFailure $ do
56- progPutStrLn config $ " Couldn't compile : " ++ exFilename
54+ onCompileFailure :: String -> Maybe Handle -> ReaderT ProgramConfig IO RunResult
55+ onCompileFailure exFilename errHandle = withTerminalFailure $ do
56+ progPutStrLn $ " Couldn't compile : " ++ exFilename
5757 case errHandle of
5858 Nothing -> return ()
59- Just h -> hGetContents h >>= progPutStrLn config
59+ Just h -> lift ( hGetContents h) >>= progPutStrLn
6060 return CompileError
6161
62- runUnitTestExercise :: ProgramConfig -> FilePath -> String -> IO RunResult
63- runUnitTestExercise config genExecutablePath exFilename = do
62+ runUnitTestExercise :: FilePath -> String -> ReaderT ProgramConfig IO RunResult
63+ runUnitTestExercise genExecutablePath exFilename = do
6464 let execSpec = shell genExecutablePath
65- (_, execStdOut, execStdErr, execProcHandle) <- createProcess (execSpec { std_out = CreatePipe , std_err = CreatePipe })
66- execExit <- waitForProcess execProcHandle
65+ (_, execStdOut, execStdErr, execProcHandle) <- lift $ createProcess (execSpec { std_out = CreatePipe , std_err = CreatePipe })
66+ execExit <- lift $ waitForProcess execProcHandle
6767 case execExit of
6868 ExitFailure code -> withTerminalFailure $ do
69- progPutStrLn config $ " Tests failed on exercise : " ++ exFilename
69+ progPutStrLn $ " Tests failed on exercise : " ++ exFilename
7070 case execStdErr of
7171 Nothing -> return ()
72- Just h -> hGetContents h >>= progPutStrLn config
72+ Just h -> lift ( hGetContents h) >>= progPutStrLn
7373 case execStdOut of
7474 Nothing -> return ()
75- Just h -> hGetContents h >>= progPutStrLn config
75+ Just h -> lift ( hGetContents h) >>= progPutStrLn
7676 return TestFailed
7777 ExitSuccess -> do
78- progPutStrLnSuccess config $ " Successfully ran : " ++ exFilename
78+ progPutStrLnSuccess $ " Successfully ran : " ++ exFilename
7979 return RunSuccess
8080
8181runExecutableExercise
82- :: ProgramConfig
83- -> FilePath
82+ :: FilePath
8483 -> String
8584 -> [String ]
8685 -> ([String ] -> Bool )
87- -> IO RunResult
88- runExecutableExercise config genExecutablePath exFilename inputs outputPred = do
86+ -> ReaderT ProgramConfig IO RunResult
87+ runExecutableExercise genExecutablePath exFilename inputs outputPred = do
8988 let execSpec = shell genExecutablePath
90- (execStdIn, execStdOut, execStdErr, execProcHandle) <- createProcess
89+ (execStdIn, execStdOut, execStdErr, execProcHandle) <- lift $ createProcess
9190 (execSpec { std_out = CreatePipe , std_err = CreatePipe , std_in = CreatePipe })
92- when (isJust execStdIn) $ forM_ inputs $ \ i -> hPutStrLn (fromJust execStdIn) i
93- execExit <- waitForProcess execProcHandle
91+ when (isJust execStdIn) $ forM_ inputs $ \ i -> lift $ hPutStrLn (fromJust execStdIn) i
92+ execExit <- lift $ waitForProcess execProcHandle
9493 case execExit of
9594 ExitFailure code -> withTerminalFailure $ do
96- progPutStrLn config $ " Encountered error running exercise: " ++ exFilename
95+ progPutStrLn $ " Encountered error running exercise: " ++ exFilename
9796 case execStdOut of
9897 Nothing -> return ()
99- Just h -> hGetContents h >>= progPutStrLn config
98+ Just h -> lift ( hGetContents h) >>= progPutStrLn
10099 case execStdErr of
101100 Nothing -> return ()
102- Just h -> hGetContents h >>= progPutStrLn config
103- progPutStrLn config " Check the Sample Input and Sample Output in the file."
104- progPutStrLn config $ " Then try running it for yourself with 'haskellings exec" ++ haskellModuleName exFilename ++ " '."
101+ Just h -> lift ( hGetContents h) >>= progPutStrLn
102+ progPutStrLn " Check the Sample Input and Sample Output in the file."
103+ progPutStrLn $ " Then try running it for yourself with 'haskellings exec" ++ haskellModuleName exFilename ++ " '."
105104 return TestFailed
106105 ExitSuccess -> do
107106 passes <- case execStdOut of
108107 Nothing -> return (outputPred [] )
109- Just h -> (lines <$> hGetContents h) >>= (return . outputPred)
108+ Just h -> (lines <$> lift ( hGetContents h) ) >>= (return . outputPred)
110109 if passes
111110 then withTerminalSuccess $ do
112- progPutStrLn config $ " Successfully ran : " ++ exFilename
113- progPutStrLn config $ " You can run this code for yourself with 'haskellings exec " ++ haskellModuleName exFilename ++ " '."
111+ progPutStrLn $ " Successfully ran : " ++ exFilename
112+ progPutStrLn $ " You can run this code for yourself with 'haskellings exec " ++ haskellModuleName exFilename ++ " '."
114113 return RunSuccess
115114 else withTerminalFailure $ do
116- progPutStrLn config $ " Unexpected output for exercise: " ++ exFilename
117- progPutStrLn config " Check the Sample Input and Sample Output in the file."
118- progPutStrLn config $ " Then try running it for yourself with 'haskellings exec " ++ haskellModuleName exFilename ++ " '."
115+ progPutStrLn $ " Unexpected output for exercise: " ++ exFilename
116+ progPutStrLn " Check the Sample Input and Sample Output in the file."
117+ progPutStrLn $ " Then try running it for yourself with 'haskellings exec " ++ haskellModuleName exFilename ++ " '."
119118 return TestFailed
120119
121- compileAndRunExercise :: ProgramConfig -> ExerciseInfo -> IO RunResult
122- compileAndRunExercise config exInfo@ (ExerciseInfo exerciseName exDirectory exType _) = do
123- let (processSpec, genDirPath, genExecutablePath) = createExerciseProcess config exInfo
124- let exFilename = haskellFileName exerciseName
120+ compileAndRunExercise :: ExerciseInfo -> ReaderT ProgramConfig IO RunResult
121+ compileAndRunExercise exInfo@ (ExerciseInfo exerciseName exDirectory exType _) = do
122+ config <- ask
123+ let (processSpec, genDirPath, genExecutablePath, exFilename) = createExerciseProcess config exInfo
125124 withDirectory genDirPath $ do
126- (_, _, procStdErr, procHandle) <- createProcess (processSpec { std_out = CreatePipe , std_err = CreatePipe })
127- exitCode <- waitForProcess procHandle
125+ (_, _, procStdErr, procHandle) <- lift $ createProcess (processSpec { std_out = CreatePipe , std_err = CreatePipe })
126+ exitCode <- lift $ waitForProcess procHandle
128127 case exitCode of
129- ExitFailure code -> onCompileFailure config exFilename procStdErr
128+ ExitFailure code -> onCompileFailure exFilename procStdErr
130129 ExitSuccess -> do
131- progPutStrLnSuccess config $ " Successfully compiled : " ++ exFilename
130+ progPutStrLnSuccess $ " Successfully compiled : " ++ exFilename
132131 case exType of
133132 CompileOnly -> return RunSuccess
134- UnitTests -> runUnitTestExercise config genExecutablePath exFilename
135- Executable inputs outputPred -> runExecutableExercise config genExecutablePath exFilename inputs outputPred
133+ UnitTests -> runUnitTestExercise genExecutablePath exFilename
134+ Executable inputs outputPred -> runExecutableExercise genExecutablePath exFilename inputs outputPred
136135
137- compileAndRunExercise_ :: ProgramConfig -> ExerciseInfo -> IO ()
138- compileAndRunExercise_ config ex = void $ compileAndRunExercise config ex
136+ compileAndRunExercise_ :: ExerciseInfo -> ReaderT ProgramConfig IO ()
137+ compileAndRunExercise_ ex = void $ compileAndRunExercise ex
0 commit comments