Tasks: support :continue in shell fn

This commit is contained in:
Michiel Borkent 2021-04-25 13:34:26 +02:00
parent 21bb768e9f
commit c5d61996d4
3 changed files with 69 additions and 43 deletions

View file

@ -23,20 +23,25 @@
(let [log-level @log-level] (let [log-level @log-level]
(when (or (when (or
;; log error also in case of info level ;; log error also in case of info level
(identical? :info @log-level) (identical? :info log-level)
(identical? :error @log-level)) (identical? :error log-level))
(binding [*out* *err*] (binding [*out* *err*]
(println (format "[bb %s]" @task-name) (str/join " " strs)))))) (println (format "[bb %s]" @task-name) (str/join " " strs))))))
(defn- handle-non-zero [proc opts] (defn- handle-non-zero [proc opts]
(when-let [proc (when proc (deref proc))] (when proc
(let [exit-code (:exit proc)] (when-let [proc (deref proc)]
(if (and (not (zero? exit-code)) (let [exit-code (:exit proc)
(not (:continue opts))) zero-exit? (zero? exit-code)
(do (log-error "Terminating with non-zero exit code: " exit-code) continue (:continue opts)
(System/exit exit-code)) continue? (if continue
(with-meta proc (or (true? continue)
{:babashka/no-print true}))))) (continue proc))
zero-exit?)]
(if continue? proc
(do (when-not zero-exit?
(log-error "Terminating with non-zero exit code: " exit-code))
(System/exit exit-code)))))))
(def default-opts (def default-opts
{:in :inherit {:in :inherit
@ -244,7 +249,7 @@
(concat requires (:requires task)) (concat requires (:requires task))
(assemble-task-1 task-name task log-level parallel? true))] nil])] (assemble-task-1 task-name task log-level parallel? true))] nil])]
(when (= "true" (System/getenv "BABASHKA_DEV")) (when (= "true" (System/getenv "BABASHKA_DEV"))
(println (ffirst prog))) (.println System/out (ffirst prog)))
prog) prog)
[(binding [*out* *err*] [(binding [*out* *err*]
(println "No such task:" task-name)) 1]))) (println "No such task:" task-name)) 1])))

View file

@ -423,6 +423,11 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
(let [args (next args)] (let [args (next args)]
(recur (assoc opts-map :log-level (keyword (first args))) (recur (assoc opts-map :log-level (keyword (first args)))
(next args))) (next args)))
"--prn"
(let [args (next args)]
(recur (assoc opts-map :prn true)
args))
;; default
(assoc opts-map :run fst :command-line-args (next args)))) (assoc opts-map :run fst :command-line-args (next args))))
opts-map))) opts-map)))
@ -750,7 +755,8 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
(sci/eval-string* sci-ctx expression))] (sci/eval-string* sci-ctx expression))]
;; return value printing ;; return value printing
(when (and (some? res) (when (and (some? res)
(not (:babashka/no-print (meta res)))) (or (not run)
(:prn cli-opts)))
(if-let [pr-f (cond shell-out println (if-let [pr-f (cond shell-out println
edn-out prn)] edn-out prn)]
(if (coll? res) (if (coll? res)

View file

@ -9,10 +9,16 @@
[clojure.test :as test :refer [deftest is testing]])) [clojure.test :as test :refer [deftest is testing]]))
(defn bb [& args] (defn bb [& args]
(edn/read-string (let [args (map str args)
{:readers *data-readers* ret (apply test-utils/bb nil args)]
:eof nil} ;; (.println System/out :args)
(apply test-utils/bb nil (map str args)))) ;; (.println System/out (vec args))
;; (.println System/out :ret)
;; (.println System/out ret)
(edn/read-string
{:readers *data-readers*
:eof nil}
ret)))
(deftest doc-test (deftest doc-test
(test-utils/with-config {:paths ["test-resources/task_scripts"]} (test-utils/with-config {:paths ["test-resources/task_scripts"]}
@ -37,7 +43,7 @@
(deftest task-test (deftest task-test
(test-utils/with-config '{:tasks {foo (+ 1 2 3)}} (test-utils/with-config '{:tasks {foo (+ 1 2 3)}}
(is (= 6 (bb "foo")))) (is (= 6 (bb "run" "--prn" "foo"))))
(let [tmp-dir (fs/create-temp-dir) (let [tmp-dir (fs/create-temp-dir)
out (str (fs/file tmp-dir "out.txt"))] out (str (fs/file tmp-dir "out.txt"))]
(testing "shell test" (testing "shell test"
@ -53,6 +59,15 @@
(bb "foo") (bb "foo")
(is (str/includes? (slurp out) (is (str/includes? (slurp out)
"foobar")))) "foobar"))))
(testing "shell test with :continue fn"
(test-utils/with-config {:tasks {'foo (list 'shell {:out out
:err out
:continue '(fn [proc]
(contains? proc :exit))}
"ls foobar")}}
(bb "foo")
(is (str/includes? (slurp out)
"foobar"))))
(fs/delete out) (fs/delete out)
(testing "clojure test" (testing "clojure test"
(test-utils/with-config {:tasks {'foo (list 'clojure {:out out} (test-utils/with-config {:tasks {'foo (list 'clojure {:out out}
@ -70,47 +85,47 @@
(bb "foo") (bb "foo")
(is (= "quux\nbaz\nbar\nfoo\n" (slurp out))))) (is (= "quux\nbaz\nbar\nfoo\n" (slurp out)))))
(fs/delete out) (fs/delete out)
(testing "init test" ;; This is why we don't support :when for now
#_(testing "depends with :when"
(test-utils/with-config {:tasks {'quux (list 'spit out "quux\n")
'baz (list 'spit out "baz\n" :append true)
'bar {:when false
:depends ['baz]
:task (list 'spit out "bar\n" :append true)}
'foo {:depends ['quux 'bar]
:task (list 'spit out "foo\n" :append true)}}}
(bb "foo")
(is (= "quux\nbaz\nbar\nfoo\n" (slurp out))))))
(testing "init test"
(test-utils/with-config '{:tasks {:init (def x 1) (test-utils/with-config '{:tasks {:init (def x 1)
foo x}} foo x}}
(is (= 1 (bb "foo"))))) (is (= 1 (bb "run" "--prn" "foo")))))
(testing "requires test" (testing "requires test"
(test-utils/with-config '{:tasks {:requires ([babashka.fs :as fs]) (test-utils/with-config '{:tasks {:requires ([babashka.fs :as fs])
foo (fs/exists? ".")}} foo (fs/exists? ".")}}
(is (= true (bb "foo")))) (is (= true (bb "run" "--prn" "foo"))))
(test-utils/with-config '{:tasks {foo {:requires ([babashka.fs :as fs]) (test-utils/with-config '{:tasks {foo {:requires ([babashka.fs :as fs])
:task (fs/exists? ".")}}} :task (fs/exists? ".")}}}
(is (= true (bb "foo")))) (is (= true (bb "run" "--prn" "foo"))))
(test-utils/with-config '{:tasks {bar {:requires ([babashka.fs :as fs])} (test-utils/with-config '{:tasks {bar {:requires ([babashka.fs :as fs])}
foo {:depends [bar] foo {:depends [bar]
:task (fs/exists? ".")}}} :task (fs/exists? ".")}}}
(is (= true (bb "foo"))))) (is (= true (bb "run" "--prn" "foo")))))
;; This is why we don't support :when for now (testing "map returned from task"
#_(testing "depends with :when"
(test-utils/with-config {:tasks {'quux (list 'spit out "quux\n")
'baz (list 'spit out "baz\n" :append true)
'bar {:when false
:depends ['baz]
:task (list 'spit out "bar\n" :append true)}
'foo {:depends ['quux 'bar]
:task (list 'spit out "foo\n" :append true)}}}
(bb "foo")
(is (= "quux\nbaz\nbar\nfoo\n" (slurp out)))))
(testing "map returned from task"
(test-utils/with-config '{:tasks {foo {:task {:a 1 :b 2}}}} (test-utils/with-config '{:tasks {foo {:task {:a 1 :b 2}}}}
(is (= {:a 1 :b 2} (bb "foo"))))) (is (= {:a 1 :b 2} (bb "run" "--prn" "foo")))))
(testing "fully qualified symbol execution" (testing "fully qualified symbol execution"
(test-utils/with-config {:paths ["test-resources/task_scripts"] (test-utils/with-config {:paths ["test-resources/task_scripts"]
:tasks '{foo tasks/foo}} :tasks '{foo tasks/foo}}
(is (= :foo (bb "foo")))) (is (= :foo (bb "run" "--prn" "foo"))))
(test-utils/with-config {:paths ["test-resources/task_scripts"] (test-utils/with-config {:paths ["test-resources/task_scripts"]
:tasks '{:requires ([tasks :as t]) :tasks '{:requires ([tasks :as t])
foo t/foo}} foo t/foo}}
(is (= :foo (bb "foo")))) (is (= :foo (bb "run" "--prn" "foo"))))
(test-utils/with-config {:paths ["test-resources/task_scripts"] (test-utils/with-config {:paths ["test-resources/task_scripts"]
:tasks '{foo {:requires ([tasks :as t]) :tasks '{foo {:requires ([tasks :as t])
:task t/foo}}} :task t/foo}}}
(is (= :foo (bb "foo"))))))) (is (= :foo (bb "run" "--prn" "foo"))))))
(deftest list-tasks-test (deftest list-tasks-test
(test-utils/with-config {} (test-utils/with-config {}
@ -164,6 +179,6 @@
;; Or do we want `--aliases :foo:bar` ;; Or do we want `--aliases :foo:bar`
;; Let's wait for a good use case ;; Let's wait for a good use case
#_(deftest alias-deps-test #_(deftest alias-deps-test
(test-utils/with-config '{:aliases {:medley {:deps {medley/medley {:mvn/version "1.3.0"}}}}} (test-utils/with-config '{:aliases {:medley {:deps {medley/medley {:mvn/version "1.3.0"}}}}}
(is (= '{1 {:id 1}, 2 {:id 2}} (is (= '{1 {:id 1}, 2 {:id 2}}
(bb "-A:medley" "-e" "(require 'medley.core)" "-e" "(medley.core/index-by :id [{:id 1} {:id 2}])"))))) (bb "-A:medley" "-e" "(require 'medley.core)" "-e" "(medley.core/index-by :id [{:id 1} {:id 2}])")))))