summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-26 05:56:59 -0500
committerBen Sima <ben@bensima.com>2025-11-26 05:56:59 -0500
commita1b335d73202a2dc4e9ecf3f70b0efc74008e402 (patch)
treed3ab549faec1bd9fe0549276f1a9829516623106
parentb5c6cfd04e5c1034e8d78830b55616f5540775e4 (diff)
Fix worker to run formatters before commit
- Run ormolu --mode inplace on changed .hs files - Run hlint --refactor to auto-fix lint issues - Use tryCommit that returns Either instead of panicking - Prevents commit hook failures from hlint violations Task-Id: t-1o2g8gugkr1
-rw-r--r--Omni/Agent/Worker.hs86
1 files changed, 76 insertions, 10 deletions
diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs
index 1cdeb6d..0c15a57 100644
--- a/Omni/Agent/Worker.hs
+++ b/Omni/Agent/Worker.hs
@@ -7,7 +7,6 @@ import Alpha
import qualified Data.Text as Text
import qualified Data.Text.IO as TIO
import qualified Omni.Agent.Core as Core
-import qualified Omni.Agent.Git as Git
import qualified Omni.Agent.Log as AgentLog
import qualified Omni.Task.Core as TaskCore
import qualified System.Directory as Directory
@@ -65,23 +64,90 @@ processTask worker task = do
Exit.ExitSuccess -> do
AgentLog.log "Agent finished successfully"
- -- Update status to Review
- TaskCore.updateTaskStatus tid TaskCore.Review []
+ -- Run formatting and linting before commit
+ AgentLog.updateActivity "Running formatters..."
+ formatResult <- runFormatters repo
- -- Commit changes using Amp output (Gerrit-style trailer)
- let commitMsg = formatCommitMessage output tid
- Git.commit repo commitMsg
+ case formatResult of
+ Left err -> do
+ AgentLog.log ("Formatting failed: " <> err)
+ AgentLog.updateActivity "Format failed, task incomplete"
+ -- Don't update status, leave as InProgress for retry
+ Right () -> do
+ -- Update status to Review
+ TaskCore.updateTaskStatus tid TaskCore.Review []
- -- Submit for review
- AgentLog.updateActivity "Task completed"
+ -- Commit changes using Amp output (Gerrit-style trailer)
+ let commitMsg = formatCommitMessage output tid
+ commitResult <- tryCommit repo commitMsg
- AgentLog.log ("[✓] Task " <> tid <> " completed")
- AgentLog.update (\s -> s {AgentLog.statusTask = Nothing})
+ case commitResult of
+ Left commitErr -> do
+ AgentLog.log ("Commit failed: " <> commitErr)
+ AgentLog.updateActivity "Commit failed"
+ Right () -> do
+ AgentLog.updateActivity "Task completed"
+ AgentLog.log ("[✓] Task " <> tid <> " completed")
+ AgentLog.update (\s -> s {AgentLog.statusTask = Nothing})
Exit.ExitFailure code -> do
AgentLog.log ("Agent failed with code " <> tshow code)
AgentLog.updateActivity "Agent failed, retrying..."
threadDelay (10 * 1000000) -- Sleep 10s
+-- | Run ormolu and hlint --refactor on changed files
+runFormatters :: FilePath -> IO (Either Text ())
+runFormatters repo = do
+ -- Get list of changed .hs files
+ let diffCmd = (Process.proc "git" ["diff", "--name-only", "--cached", "HEAD"]) {Process.cwd = Just repo}
+ (_, diffOut, _) <- Process.readCreateProcessWithExitCode diffCmd ""
+
+ -- Also get untracked files
+ let untrackedCmd = (Process.proc "git" ["ls-files", "--others", "--exclude-standard"]) {Process.cwd = Just repo}
+ (_, untrackedOut, _) <- Process.readCreateProcessWithExitCode untrackedCmd ""
+
+ let changedFiles = Text.lines (Text.pack diffOut) ++ Text.lines (Text.pack untrackedOut)
+ allFiles = filter (Text.isSuffixOf ".hs") changedFiles
+
+ if null allFiles
+ then pure (Right ())
+ else do
+ -- Run ormolu on each file
+ forM_ allFiles <| \f -> do
+ let ormoluCmd = (Process.proc "ormolu" ["--mode", "inplace", Text.unpack f]) {Process.cwd = Just repo}
+ _ <- Process.readCreateProcessWithExitCode ormoluCmd ""
+ pure ()
+
+ -- Run hlint --refactor on each file
+ forM_ allFiles <| \f -> do
+ let hlintCmd = (Process.proc "hlint" ["--refactor", "--refactor-options=-i", Text.unpack f]) {Process.cwd = Just repo}
+ _ <- Process.readCreateProcessWithExitCode hlintCmd ""
+ pure ()
+
+ pure (Right ())
+
+-- | Try to commit, returning error message on failure
+tryCommit :: FilePath -> Text -> IO (Either Text ())
+tryCommit repo msg = do
+ -- Stage all changes
+ let addCmd = (Process.proc "git" ["add", "."]) {Process.cwd = Just repo}
+ (addCode, _, addErr) <- Process.readCreateProcessWithExitCode addCmd ""
+ case addCode of
+ Exit.ExitFailure _ -> pure <| Left (Text.pack addErr)
+ Exit.ExitSuccess -> do
+ -- Check for changes
+ let checkCmd = (Process.proc "git" ["diff", "--cached", "--quiet"]) {Process.cwd = Just repo}
+ (checkCode, _, _) <- Process.readCreateProcessWithExitCode checkCmd ""
+ case checkCode of
+ Exit.ExitSuccess -> pure (Right ()) -- Nothing to commit
+ Exit.ExitFailure 1 -> do
+ -- There are changes, commit them
+ let commitCmd = (Process.proc "git" ["commit", "-m", Text.unpack msg]) {Process.cwd = Just repo}
+ (commitCode, _, commitErr) <- Process.readCreateProcessWithExitCode commitCmd ""
+ case commitCode of
+ Exit.ExitSuccess -> pure (Right ())
+ Exit.ExitFailure _ -> pure <| Left (Text.pack commitErr)
+ Exit.ExitFailure c -> pure <| Left ("git diff failed with code " <> tshow c)
+
runAmp :: FilePath -> TaskCore.Task -> IO (Exit.ExitCode, Text)
runAmp repo task = do
-- Check for retry context