Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

97 lines (83 sloc) 3.656 kb
"Display a list of tasks or help for a given task."
(:use [leiningen.util.ns :only [namespaces-matching]])
(:require [clojure.string :as string]
[ :as io]))
(def tasks (->> (namespaces-matching "leiningen")
(filter #(re-find #"^leiningen\.(?!core|util)[^\.]+$" (name %)))
(defn get-arglists [task]
(for [args (or (:help-arglists (meta task)) (:arglists (meta task)))]
(vec (remove #(= 'project %) args))))
(def help-padding 3)
(defn- formatted-docstring [command docstring padding]
(apply str
(apply str
(cons \newline (repeat (+ padding (count command)) \space)))}
(defn- formatted-help [command docstring longest-key-length]
(let [padding (+ longest-key-length help-padding (- (count command)))]
(format (str "%1s" (apply str (repeat padding \space)) "%2s")
(formatted-docstring command docstring padding))))
(defn- get-subtasks-and-docstrings-for [task]
(into {}
(map (fn [subtask]
(let [m (meta subtask)]
[(str (:name m)) (:doc m)]))
(:subtasks (meta task)))))
(defn subtask-help-for
[task-ns task]
(let [subtasks (get-subtasks-and-docstrings-for task)]
(if (empty? subtasks)
(let [longest-key-length (apply max (map count (keys subtasks)))
help-fn (ns-resolve task-ns 'help)]
(string/join "\n"
(concat ["\n\nSubtasks available:"]
(for [[subtask doc] subtasks]
(formatted-help subtask doc longest-key-length))))))))
(defn- resolve-task [task-name]
(let [task-ns (doto (symbol (str "leiningen." task-name)) require)
task (ns-resolve task-ns (symbol task-name))]
[task-ns task]))
(defn static-help [name]
(when-let [reader (io/resource (format "leiningen/help/%s" name))]
(slurp reader)))
(defn help-for
"Help for a task is stored in its docstring, or if that's not present
in its namespace."
(let [[task-ns task] (resolve-task task-name)
help-fn (ns-resolve task-ns 'help)]
(str (or (and (not= task-ns ' help-fn (help-fn))
(:doc (meta task))
(:doc (meta (find-ns task-ns))))
(subtask-help-for task-ns task)
(when (some seq (get-arglists task))
(str "\n\nArguments: " (pr-str (get-arglists task)))))))
;; affected by clojure ticket #130: bug of AOT'd namespaces losing metadata
(defn help-summary-for [task-ns]
(try (let [task-name (last (.split (name task-ns) "\\."))
ns-summary (:doc (meta (find-ns (doto task-ns require))))
first-line (first (.split (help-for task-name) "\n"))]
;; Use first line of task docstring if ns metadata isn't present
(str task-name (apply str (repeat (- 12 (count task-name)) " "))
(or ns-summary first-line)))
(catch Throwable e
(binding [*out* *err*]
(str task-ns " Problem loading: " (.getMessage e))))))
(defn help
"Display a list of tasks or help for a given task.
Also provides readme, tutorial, news, sample, deploying and copying documentation."
([task] (println (or (static-help task) (help-for task))))
(println "Leiningen is a tool for working with Clojure projects.\n")
(println "Several tasks are available:")
(doseq [task-ns tasks]
(println (help-summary-for task-ns)))
(println "\nRun lein help $TASK for details.")
(println "See also: readme, tutorial, copying, sample, deploying and news.")))
Jump to Line
Something went wrong with that request. Please try again.