diff --git a/src/babashka/impl/tasks.clj b/src/babashka/impl/tasks.clj index 2f1619f5..48f6e0e2 100644 --- a/src/babashka/impl/tasks.clj +++ b/src/babashka/impl/tasks.clj @@ -248,6 +248,31 @@ [(binding [*out* *err*] (println "No such task:" task-name)) 1]))) +(defn doc-from-task [sci-ctx tasks task] + (or (:doc task) + (when-let [fn-sym (cond (qualified-symbol? task) + task + (map? task) + (let [t (:task task)] + (when (qualified-symbol? t) + t)))] + (let [requires (:requires tasks) + requires (map (fn [x] + (list 'quote x)) + (concat requires (:requires task))) + prog (format " +;; first try to require the fully qualified namespace, as this is the cheapest option +(try (require '%s) + ;; on failure, the namespace might have been an alias so we require other namespaces + (catch Exception _ %s)) +(:doc (meta (resolve '%s)))" + (namespace fn-sym) + (if (seq requires) + (list* 'require requires) + "") + fn-sym)] + (sci/eval-string* sci-ctx prog))))) + (defn list-tasks [sci-ctx] (let [tasks (:tasks @bb-edn)] @@ -264,15 +289,7 @@ (println) (doseq [k names :let [task (get tasks (symbol k))]] - (let [task (if (qualified-symbol? task) - {:doc (sci/eval-string* - sci-ctx - (format " -(try (require '%s) (catch Exception _ nil)) -(:doc (meta (resolve '%s)))" (namespace task) task))} - task)] - (println (str (format fmt k) - (when-let [d (:doc task)] - (str " " d))))))) + (println (str (format fmt k) + (when-let [d (doc-from-task sci-ctx tasks task)] + (str " " d)))))) (println "No tasks found.")))) - diff --git a/test/babashka/bb_edn_test.clj b/test/babashka/bb_edn_test.clj index 93417f10..f23487d3 100644 --- a/test/babashka/bb_edn_test.clj +++ b/test/babashka/bb_edn_test.clj @@ -105,7 +105,8 @@ (let [res (test-utils/bb nil "tasks")] (is (str/includes? res "No tasks found.")))) (test-utils/with-config {:paths ["test-resources/task_scripts"] - :tasks {'task1 + :tasks {:requires '([tasks :as t]) + 'task1 {:doc "task1 doc" :task '(+ 1 2 3)} 'task2 @@ -117,9 +118,12 @@ {:task '(+ 1 2 3) :private true} 'foo 'tasks/foo - 'bar 'non-existing/bar}} + 'bar 't/foo + 'baz 'non-existing/bar + 'quux {:requires '([tasks :as t2]) + :task 't2/foo}}} (let [res (test-utils/bb nil "tasks")] - (is (= "The following tasks are available:\n\nbar \nfoo Foo docstring\ntask1 task1 doc\ntask2 task2 doc\n" + (is (= "The following tasks are available:\n\nbar Foo docstring\nbaz \nfoo Foo docstring\nquux Foo docstring\ntask1 task1 doc\ntask2 task2 doc\n" res))))) (deftest task-priority-test