{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE NoImplicitPrelude #-} -- : out agent -- : dep sqlite-simple -- : dep temporary module Omni.Agent where import Alpha import qualified Data.Text as Text import qualified Omni.Agent.Core as Core import qualified Omni.Agent.Log as Log import qualified Omni.Agent.Worker as Worker import qualified Omni.Cli as Cli import qualified Omni.Task.Core as TaskCore import qualified Omni.Test as Test import qualified System.Console.Docopt as Docopt import qualified System.Directory as Directory import qualified System.Environment as Env import qualified System.Exit as Exit import System.FilePath (takeFileName) main :: IO () main = Cli.main plan plan :: Cli.Plan () plan = Cli.Plan { Cli.help = help, Cli.move = move, Cli.test = test, Cli.tidy = \_ -> pure () } help :: Cli.Docopt help = [Cli.docopt| agent Usage: agent start [] agent merge-driver agent test agent --help Options: --path= Path to the worker directory [default: .] --help Show this help |] move :: Cli.Arguments -> IO () move args | args `Cli.has` Cli.command "start" = do -- Always run in current directory let path = "." -- Infer name from current directory absPath <- Directory.getCurrentDirectory let name = Text.pack (takeFileName absPath) let worker = Core.Worker { Core.workerName = name, Core.workerPid = Nothing, Core.workerStatus = Core.Idle, Core.workerPath = path } let taskId = fmap Text.pack (Cli.getArg args (Cli.argument "task-id")) Worker.start worker taskId | args `Cli.has` Cli.command "merge-driver" = mergeDriver args | otherwise = putStrLn (Cli.usage help) getArgOrExit :: Cli.Arguments -> Docopt.Option -> IO String getArgOrExit args opt = case Cli.getArg args opt of Just val -> pure val Nothing -> do putText <| "Error: Missing required argument " <> Text.pack (show opt) Exit.exitFailure mergeDriver :: Cli.Arguments -> IO () mergeDriver args = do ours <- getArgOrExit args (Cli.argument "ours") theirs <- getArgOrExit args (Cli.argument "theirs") -- Set TASK_DB_PATH to ours (the file git provided as the current version) -- Since we are no longer using git-tracked tasks.jsonl, this merge driver logic needs rethinking. -- If the merge driver is called, it means git found a conflict in .tasks/tasks.jsonl, but we deleted it. -- So this code might be dead, or we might be dealing with legacy files during a rebase. -- For now, we'll keep the logic but be aware it's likely unused. Env.setEnv "TASK_DB_PATH" ours TaskCore.importTasks theirs Exit.exitSuccess test :: Test.Tree test = Test.group "Omni.Agent" [unitTests, logTests] logTests :: Test.Tree logTests = Test.group "Log tests" [ Test.unit "Log.emptyStatus" <| do let s = Log.emptyStatus "worker-1" Log.statusWorker s Test.@?= "worker-1" Log.statusFiles s Test.@?= 0 ] unitTests :: Test.Tree unitTests = Test.group "Unit tests" [ Test.unit "can parse start command" <| do let result = Docopt.parseArgs help ["start"] case result of Left err -> Test.assertFailure <| "Failed to parse 'start': " <> show err Right args -> args `Cli.has` Cli.command "start" Test.@?= True, Test.unit "can parse start command with task id" <| do let result = Docopt.parseArgs help ["start", "t-123"] case result of Left err -> Test.assertFailure <| "Failed to parse 'start t-123': " <> show err Right args -> do args `Cli.has` Cli.command "start" Test.@?= True Cli.getArg args (Cli.argument "task-id") Test.@?= Just "t-123" ]