diff --git a/src/babashka/impl/tasks.clj b/src/babashka/impl/tasks.clj index 7cad019f..d4fb19bf 100644 --- a/src/babashka/impl/tasks.clj +++ b/src/babashka/impl/tasks.clj @@ -225,13 +225,15 @@ prog)) (defn target-order - ([tasks task-name] (target-order tasks task-name (volatile! #{}))) - ([tasks task-name processed] + ([tasks task-name] (target-order tasks task-name (volatile! #{}) #{})) + ([tasks task-name processed processing] (let [task (tasks task-name) depends (:depends task)] + (when (contains? processing task-name) + (throw (Exception. (str "Cyclic task: " task-name)))) (loop [deps (seq depends)] (let [deps (remove #(contains? @processed %) deps) - order (vec (mapcat #(target-order tasks % processed) deps))] + order (vec (mapcat #(target-order tasks % processed (conj processing task-name)) deps))] (if-not (contains? @processed task-name) (do (vswap! processed conj task-name) (conj order task-name)) diff --git a/test/babashka/bb_edn_test.clj b/test/babashka/bb_edn_test.clj index 0f9e24c2..a57f6aa7 100644 --- a/test/babashka/bb_edn_test.clj +++ b/test/babashka/bb_edn_test.clj @@ -170,6 +170,18 @@ :task (+ a 4 5 6)}}} (is (thrown-with-msg? Exception #"No such task: x" + (bb "run" "b"))))) + (testing "cyclic task" + (test-utils/with-config '{:tasks {b {:depends [b] + :task (+ a 4 5 6)}}} + (is (thrown-with-msg? + Exception #"Cyclic task: b" + (bb "run" "b")))) + (test-utils/with-config '{:tasks {c {:depends [b]} + b {:depends [c] + :task (+ a 4 5 6)}}} + (is (thrown-with-msg? + Exception #"Cyclic task: b" (bb "run" "b")))))) (deftest list-tasks-test