buildNext :: Options -> Job -> MVar () -> IO ()
buildNext opts job mvar = handle errorHandler $ do
    hPutStrLn stderr $ "Building " ++ show job ++ " ..."
    (buildPath, outputPath, processHandle) <- spawnBuild job
    exitCode <- waitForProcess processHandle
    output <- readFile outputPath
    let result = Result
          { resultExitCode = exitCode
          , resultOutput   = output
          , resultPath     = buildPath
          }
    modifyGlobalResults opts $ changeResults result
    modifyLocalResults  job  $ changeResults result
    cleanBuilds 20 $ jobProjectPath job
    putMVar mvar ()
  where
    changeResults :: Result -> Results -> Results
    changeResults result (Results results) = Results $ take 20 $ result : results

    errorHandler :: SomeException -> IO ()
    errorHandler e = do
      hPutStrLn stderr $ "ERROR: " ++ show e
      putMVar mvar ()
buildNext :: Options -> Job -> MVar () -> IO ()
buildNext opts job mvar = handle errorHandler $ do
    hPutStrLn stderr $ "Building " ++ show job ++ " ..."
    (buildPath, outputPath, processHandle) <- spawnBuild job
    exitCode <- waitForProcess processHandle
    output <- readFile outputPath
    let result = Result
          { resultExitCode = exitCode
          , resultOutput   = output
          , resultPath     = buildPath
          }
    modifyGlobalResults opts $ changeResults result
    modifyLocalResults  job  $ changeResults result
    cleanBuilds 20 $ jobProjectPath job
    putMVar mvar ()
  where
    changeResults :: Result -> Results -> Results
    changeResults result (Results results) = Results $ take 20 $ result : results

    errorHandler :: SomeException -> IO ()
    errorHandler e = do
      hPutStrLn stderr $ "ERROR: " ++ show e
      putMVar mvar ()
buildNext opts job mvar = handle errorHandler $ do
    hPutStrLn stderr $ "Building " ++ show job ++ " ..."
    (buildPath, outputPath, processHandle) <- spawnBuild job
    exitCode <- waitForProcess processHandle
    output <- readFile outputPath
    let result = Result
          { resultExitCode = exitCode
          , resultOutput   = output
          , resultPath     = buildPath
          }
    modifyGlobalResults opts $ changeResults result
    modifyLocalResults  job  $ changeResults result
    cleanBuilds 20 $ jobProjectPath job
    putMVar mvar ()
  where
    changeResults :: Result -> Results -> Results
    changeResults result (Results results) = Results $ take 20 $ result : results

    errorHandler :: SomeException -> IO ()
    errorHandler e = do
      hPutStrLn stderr $ "ERROR: " ++ show e
      putMVar mvar ()