summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Omni/Agent/Git.hs16
-rw-r--r--Omni/Agent/Worker.hs32
2 files changed, 47 insertions, 1 deletions
diff --git a/Omni/Agent/Git.hs b/Omni/Agent/Git.hs
index cf9a122..7717cee 100644
--- a/Omni/Agent/Git.hs
+++ b/Omni/Agent/Git.hs
@@ -11,6 +11,8 @@ module Omni.Agent.Git
commit,
createBranch,
getCurrentBranch,
+ branchExists,
+ isMerged,
main,
test,
)
@@ -175,3 +177,17 @@ getCurrentBranch repo = do
case code of
Exit.ExitSuccess -> pure <| Text.strip (Text.pack out)
_ -> panic "git branch failed"
+
+branchExists :: FilePath -> Text -> IO Bool
+branchExists repo branch = do
+ let cmd = (Process.proc "git" ["show-ref", "--verify", "refs/heads/" <> Text.unpack branch]) {Process.cwd = Just repo}
+ (code, _, _) <- Process.readCreateProcessWithExitCode cmd ""
+ pure (code == Exit.ExitSuccess)
+
+isMerged :: FilePath -> Text -> Text -> IO Bool
+isMerged repo branch target = do
+ -- Check if 'branch' is merged into 'target'
+ -- git merge-base --is-ancestor <branch> <target>
+ let cmd = (Process.proc "git" ["merge-base", "--is-ancestor", Text.unpack branch, Text.unpack target]) {Process.cwd = Just repo}
+ (code, _, _) <- Process.readCreateProcessWithExitCode cmd ""
+ pure (code == Exit.ExitSuccess)
diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs
index 511f309..23dd759 100644
--- a/Omni/Agent/Worker.hs
+++ b/Omni/Agent/Worker.hs
@@ -66,7 +66,16 @@ processTask worker task = do
currentBranch <- Git.getCurrentBranch repo
if currentBranch == taskBranch
then Log.info ["worker", "resuming branch", taskBranch]
- else Git.createBranch repo taskBranch
+ else do
+ -- Determine base branch from dependencies
+ baseBranch <- findBaseBranch repo task
+ if baseBranch /= "live"
+ then do
+ Log.info ["worker", "basing", taskBranch, "on", baseBranch]
+ Git.checkout repo baseBranch
+ else Log.info ["worker", "basing", taskBranch, "on live"]
+
+ Git.createBranch repo taskBranch
-- Run Amp
exitCode <- runAmp repo task
@@ -154,6 +163,27 @@ formatTask t =
<> "Updated: "
<> Text.pack (show (TaskCore.taskUpdatedAt t))
<> "\n"
+ <> maybe "" (\d -> "Description:\n" <> d <> "\n\n") (TaskCore.taskDescription t)
<> (if null (TaskCore.taskDependencies t) then "" else "\nDependencies:\n" <> Text.unlines (map formatDep (TaskCore.taskDependencies t)))
where
formatDep dep = " - " <> TaskCore.depId dep <> " [" <> Text.pack (show (TaskCore.depType dep)) <> "]"
+
+findBaseBranch :: FilePath -> TaskCore.Task -> IO Text
+findBaseBranch repo task = do
+ let deps = TaskCore.taskDependencies task
+ -- Filter for blocking dependencies
+ let blockingDeps = filter (\d -> TaskCore.depType d == TaskCore.Blocks || TaskCore.depType d == TaskCore.ParentChild) deps
+
+ -- Check if any have unmerged branches
+ candidates <- flip filterM blockingDeps <| \dep -> do
+ let branch = "task/" <> TaskCore.depId dep
+ exists <- Git.branchExists repo branch
+ if exists
+ then do
+ merged <- Git.isMerged repo branch "live"
+ pure (not merged)
+ else pure False
+
+ case candidates of
+ (candidate : _) -> pure ("task/" <> TaskCore.depId candidate)
+ [] -> pure "live"