diff options
Diffstat (limited to 'Omni')
| -rw-r--r-- | Omni/Agent/Worker.hs | 86 |
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 |
