(ns leiningen.do "Higher-order task to perform other tasks in succession." (:refer-clojure :exclude [do]) (:require [leiningen.core.main :as main])) (defn- conj-to-last [coll x] (update-in coll [(dec (count coll))] conj x)) (defn- butlast-char "Removes the last character in the string." [s] (subs s 0 (dec (count s)))) (defn- pop-if-last "Pops the collection if (pred (peek coll)) is truthy." [coll pred] (if (pred (peek coll)) (pop coll) coll)) (defn ^:internal group-args ([args] (-> (reduce group-args [[]] args) (pop-if-last empty?))) ([groups arg] (cond (coll? arg) (-> (pop-if-last groups empty?) (conj arg [])) (.endsWith arg ",") (-> groups (conj-to-last (butlast-char arg)) (conj [])) :else (conj-to-last groups arg)))) (defn ^:no-project-needed ^:higher-order do "Higher-order task to perform other tasks in succession. Each comma-separated group should be a task name followed by optional arguments. USAGE: lein do test, compile :all, deploy private-repo" [project & args] (doseq [arg-group (group-args args)] (main/resolve-and-apply project arg-group)))