Skip to content

Instantly share code, notes, and snippets.

@noprompt noprompt/dup.clj Secret
Last active Aug 29, 2015

Embed
What would you like to do?
(ns leiningen.pdo
(:require [leiningen.do :refer [group-args]]
[leiningen.core.main :refer [apply-task lookup-alias]]
[robert.hooke :refer [add-hook]]
[clojure.string :as string]))
(defn make-tagged-out [tag]
(let [tag (format "[%s] " tag)
tag-lines (fn [s]
(string/replace s #"(^|\n)" (str "$1" tag)))
buffer ()
old-out *out*]
(proxy [java.io.Writer] []
(flush []
(. old-out (flush)))
(append [c]
(. old-out (append c)))
(write
([^String s]
(locking old-out
(.write old-out (tag-lines s))))))))
(defmacro with-out-tag [tag & body]
`(binding [*out* (make-tagged-out ~tag)]
~@body))
(defn apply-in-future [project task-name args]
(future
(with-out-tag task-name
(apply-task (lookup-alias task-name project) project args))))
(defn ^:no-project-needed ^:higher-order pdo
"Higher-order task to perform other tasks in parallel.
Each comma-separated group should be a task named followed by optional arguments.
Each task will be executed in a separate future. The last task will be executed
in the current (main) thread. After it finishes, each future will be dereffed in
order to prevent Leiningen from exiting before all tasks have finished.
This task is primarily useful for running multiple tasks that block forever.
USAGE: lein pdo cljsbuild auto, repl"
[project & args]
(let [[last parallel] ((juxt last butlast) (group-args args))
futures (when (seq parallel)
(doall
(for [[task-name & args] parallel]
(apply-in-future project task-name args))))
[task-name & args] last]
(with-out-tag task-name
(apply-task (lookup-alias task-name project) project args))
(doseq [task futures]
@task)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.