Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
executable file 141 lines (115 sloc) 4.45 KB
(ns lancet
(:import (java.beans Introspector)
(java.util.concurrent CountDownLatch)
( Path)))
(println "WARNING: lancet namespace is deprecated; use lancet.core.")
(def #^{:doc "Dummy ant project to keep Ant tasks happy"}
(let [proj (
logger (]
(doto logger
(.setEmacsMode true)
(.setOutputPrintStream System/out)
(.setErrorPrintStream System/err))
(doto proj
(.addBuildListener logger))))
(defmulti coerce (fn [dest-class src-inst] [dest-class (class src-inst)]))
(defmethod coerce [ String] [_ str]
( str))
(defmethod coerce [Boolean/TYPE String] [_ str]
(contains? #{"on" "yes" "true"} (.toLowerCase str)))
(defmethod coerce :default [dest-cls obj] (cast dest-cls obj))
(defmethod coerce [Path String] [_ str]
(Path. lancet/ant-project str))
(defn env [val]
(System/getenv (name val)))
(defn- build-sh-args [args]
(concat (.split (first args) " +") (rest args)))
(defn property-descriptor [inst prop-name]
(filter #(= prop-name (.getName %))
(Introspector/getBeanInfo (class inst))))))
(defn get-property-class [write-method]
(first (.getParameterTypes write-method)))
(defn set-property! [inst prop value]
(let [pd (property-descriptor inst prop)]
(when-not pd
(throw (Exception. (format "No such property %s." prop))))
(let [write-method (.getWriteMethod pd)
dest-class (get-property-class write-method)]
(.invoke write-method inst (into-array [(coerce dest-class value)])))))
(defn set-properties! [inst prop-map]
(doseq [[k v] prop-map] (set-property! inst (name k) v)))
(defn instantiate-task [project name props & filesets]
(let [task (.createTask project name)]
(when-not task
(throw (Exception. (format "No task named %s." name))))
(doto task
(.setProject project)
(set-properties! props))
(doseq [fs filesets]
(.addFileset task fs))
(defn runonce
"Create a function that will only run once. All other invocations
return the first calculated value. The function *can* have side effects
and calls to runonce *can* be composed. Deadlock is possible
if you have circular dependencies.
Returns a [has-run-predicate, reset-fn, once-fn]"
(let [sentinel (Object.)
result (atom sentinel)
reset-fn (fn [] (reset! result sentinel))
has-run-fn (fn [] (not= @result sentinel))]
(fn [& args]
(locking sentinel
(if (= @result sentinel)
(reset! result (function))
(defmacro has-run? [f]
`((:has-run (meta (var ~f)))))
(defmacro reset [f]
`((:reset-fn (meta (var ~f)))))
(def targets (atom #{}))
(defmacro deftarget [sym doc & forms]
(swap! targets #(conj % sym))
(let [has-run (gensym "hr-") reset-fn (gensym "rf-")]
`(let [[~has-run ~reset-fn once-fn#] (runonce (fn [] ~@forms))]
(def ~(with-meta sym {:doc doc :has-run has-run :reset-fn reset-fn})
(defmacro define-ant-task [clj-name ant-name]
`(defn ~clj-name [& props#]
(let [task# (apply instantiate-task ant-project ~(name ant-name) props#)]
(.execute task#)
(defmacro define-ant-type [clj-name ant-name]
`(defn ~clj-name [props#]
(let [bean# (new ~ant-name)]
(set-properties! bean# props#)
(when (property-descriptor bean# "project")
(set-property! bean# "project" ant-project))
(defn task-names [] (map symbol (seq (.. ant-project getTaskDefinitions keySet))))
(defn safe-ant-name [n]
(if (ns-resolve 'clojure.core n) (symbol (str "ant-" n)) n))
(defmacro define-all-ant-tasks []
`(do ~@(map (fn [n] `(define-ant-task ~n ~n)) (task-names))))
(defmacro define-all-ant-tasks []
`(do ~@(map (fn [n] `(define-ant-task ~(safe-ant-name n) ~n)) (task-names))))
;; The version of ant that maven-ant-tasks requires doesn't have this class:
;; (define-ant-type files
(define-ant-type fileset
(defn -main [& targs]
(load-file "build.clj")
(if targs
(doseq [targ (map symbol targs)]
(eval (list targ)))
(println "Available targets: " @targets)))
Jump to Line
Something went wrong with that request. Please try again.