From 78ba5a8e02fcfcf1e22ed32f2c1ce1b7ab1a4e26 Mon Sep 17 00:00:00 2001 From: patritzenfeld Date: Tue, 28 Jul 2026 16:44:18 +0200 Subject: [PATCH 1/2] differentiate feedback types --- run-codeworld-tasks/app/Main.hs | 59 ++++++++++++++----- run-codeworld-tasks/package.yaml | 1 + run-codeworld-tasks/run-codeworld-tasks.cabal | 1 + 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/run-codeworld-tasks/app/Main.hs b/run-codeworld-tasks/app/Main.hs index 134b4a7..efcedf2 100644 --- a/run-codeworld-tasks/app/Main.hs +++ b/run-codeworld-tasks/app/Main.hs @@ -7,6 +7,15 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as LT import Control.Monad (void) +import Control.Monad.Except ( + ExceptT, + runExceptT, + throwError, + withExceptT, + ) +import Control.Monad.IO.Class +import Data.Char (toUpper) +import Data.String (fromString) import Data.Text (Text) import Data.Text.Lazy.Builder (toLazyText) import Haskell.Template.Task (grade) @@ -25,10 +34,11 @@ import Rainbow ( green, red, yellow, + putChunk, putChunkLn, ) import System.Directory (getTemporaryDirectory) -import System.Exit (die, exitFailure, exitSuccess) +import System.Exit (die, exitSuccess) import System.Environment (getArgs) import System.FilePath ((), (-<.>)) import System.IO (readFile') @@ -59,6 +69,10 @@ suggestionStyle = bold . fore brightYellow . chunk data Mode = Submission | Solution +data Rejection = Syntax | Semantics | Unknown deriving (Show) + +type Output = ExceptT Rejection IO + instance Read Mode where readPrec = lift $ do @@ -88,17 +102,29 @@ main = do runTemplateTask :: String -> String -> IO () runTemplateTask task submission = do tmp <- getTemporaryDirectory - grade - id - id + result <- runExceptT $ grade + syntax + semantics rejection suggestion tmp task submission - putChunkLn $ bold $ fore green "Your submission passed!" - emptyLine - putChunkLn $ statusLabel green "SUCCESS" + case result of + Right () -> do + putChunkLn $ bold $ fore green "Your submission passed!" + emptyLine + putChunkLn $ statusLabel green "SUCCESS" + Left reason -> + putChunkLn $ statusLabel red $ fromString $ map toUpper $ show reason + + +syntax :: Output () -> Output () +syntax = withExceptT $ const Syntax + + +semantics :: Output () -> Output () +semantics = withExceptT $ const Semantics modeToDir :: Mode -> FilePath @@ -140,22 +166,23 @@ styleCommon t | otherwise = bold $ chunk t -suggestion :: Doc -> IO () -suggestion doc = do +suggestion :: Doc -> Output () +suggestion doc = liftIO $ do putChunkLn $ statusLabel yellow "SUGGESTION:" emptyLine unlinesChunks $ map styleSuggestions $ toLines doc emptyLine -rejection :: Doc -> IO a +rejection :: Doc -> Output a rejection doc = do - putChunkLn $ statusLabel red "ERROR:" - emptyLine - unlinesChunks $ map styleRejections $ toLines doc - emptyLine - putChunkLn $ statusLabel red "REJECTED" - exitFailure + liftIO $ do + putChunkLn $ statusLabel red "ERROR:" + emptyLine + unlinesChunks $ map styleRejections $ toLines doc + emptyLine + putChunk $ statusLabel red "REJECTED DUE TO: " + throwError Unknown emptyLine :: IO () diff --git a/run-codeworld-tasks/package.yaml b/run-codeworld-tasks/package.yaml index 5c68f64..200d0c4 100644 --- a/run-codeworld-tasks/package.yaml +++ b/run-codeworld-tasks/package.yaml @@ -16,6 +16,7 @@ dependencies: - haskell-template-task - haskell-template-task-raw - hint + - mtl - rainbow - text - wl-pprint-text diff --git a/run-codeworld-tasks/run-codeworld-tasks.cabal b/run-codeworld-tasks/run-codeworld-tasks.cabal index f7cd16f..2ea9273 100644 --- a/run-codeworld-tasks/run-codeworld-tasks.cabal +++ b/run-codeworld-tasks/run-codeworld-tasks.cabal @@ -38,6 +38,7 @@ executable test-task , haskell-template-task , haskell-template-task-raw , hint + , mtl , rainbow , random , syb From aee5b50ee0514fc8d9acaa5e5d1b9fedecd371f4 Mon Sep 17 00:00:00 2001 From: patritzenfeld Date: Tue, 28 Jul 2026 16:54:21 +0200 Subject: [PATCH 2/2] add exitfailure back for CI tests --- run-codeworld-tasks/app/Main.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/run-codeworld-tasks/app/Main.hs b/run-codeworld-tasks/app/Main.hs index efcedf2..0cb09f1 100644 --- a/run-codeworld-tasks/app/Main.hs +++ b/run-codeworld-tasks/app/Main.hs @@ -38,7 +38,7 @@ import Rainbow ( putChunkLn, ) import System.Directory (getTemporaryDirectory) -import System.Exit (die, exitSuccess) +import System.Exit (die, exitFailure, exitSuccess) import System.Environment (getArgs) import System.FilePath ((), (-<.>)) import System.IO (readFile') @@ -95,7 +95,6 @@ main = do (openFileInDir . modeToDir) $ readMaybe subMode runTemplateTask taskContents submissionContents - exitSuccess _ -> usage @@ -115,8 +114,10 @@ runTemplateTask task submission = do putChunkLn $ bold $ fore green "Your submission passed!" emptyLine putChunkLn $ statusLabel green "SUCCESS" - Left reason -> + exitSuccess + Left reason -> do putChunkLn $ statusLabel red $ fromString $ map toUpper $ show reason + exitFailure syntax :: Output () -> Output ()