Improve help text + print help when no args (#61)

This commit is contained in:
Michiel Borkent 2019-09-06 16:40:50 +02:00 committed by GitHub
parent 1e1712b780
commit 93f154283d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 37 deletions

View file

@ -96,7 +96,7 @@ You may also download a binary from [Github](https://github.com/borkdude/babashk
## Usage ## Usage
``` shellsession ``` shellsession
Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] ( expression | -f <file> | --socket-repl [host:]port ) Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] ( -e <expression> | -f <file> | --socket-repl [<host>:]<port> )
Options: Options:
@ -108,9 +108,13 @@ Options:
-o: write lines to stdout. -o: write lines to stdout.
-O: write EDN values to stdout. -O: write EDN values to stdout.
--stream: stream over lines or EDN values from stdin. Combined with -i or -I *in* becomes a single value per iteration. --stream: stream over lines or EDN values from stdin. Combined with -i or -I *in* becomes a single value per iteration.
--file or -f: read expressions from file instead of argument wrapped in an implicit do. -e, --eval <expression>: evaluate an expression
-f, --file <path>: evaluate a file
--socket-repl: start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666). --socket-repl: start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666).
--time: print execution time before exiting. --time: print execution time before exiting.
If neither -e, -f, or --socket-repl are specified, then the first argument that is not parsed as a option is treated as a file if it exists, or as an expression otherwise.
Everything after that is bound to *command-line-args*.
``` ```
The `clojure.core` functions are accessible without a namespace alias. The `clojure.core` functions are accessible without a namespace alias.

View file

@ -101,7 +101,7 @@
(defn print-version [] (defn print-version []
(println (str "babashka v"(str/trim (slurp (io/resource "BABASHKA_VERSION")))))) (println (str "babashka v"(str/trim (slurp (io/resource "BABASHKA_VERSION"))))))
(def usage-string "Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] ( -e <expression> | -f <file> | --socket-repl [host:]port )") (def usage-string "Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] ( -e <expression> | -f <file> | --socket-repl [<host>:]<port> )")
(defn print-usage [] (defn print-usage []
(println usage-string)) (println usage-string))
@ -121,13 +121,13 @@
-o: write lines to stdout. -o: write lines to stdout.
-O: write EDN values to stdout. -O: write EDN values to stdout.
--stream: stream over lines or EDN values from stdin. Combined with -i or -I *in* becomes a single value per iteration. --stream: stream over lines or EDN values from stdin. Combined with -i or -I *in* becomes a single value per iteration.
-e, --eval expression: evaluate an expression -e, --eval <expression>: evaluate an expression
-f, --file path: evaluate a file -f, --file <path>: evaluate a file
--socket-repl: start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666). --socket-repl: start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666).
--time: print execution time before exiting. --time: print execution time before exiting.
If neither -e, -f, or --socket-repl are specified, then the first argument is treated as a file if it exists, or as an expression otherwise. If neither -e, -f, or --socket-repl are specified, then the first argument that is not parsed as a option is treated as a file if it exists, or as an expression otherwise.
")) Everything after that is bound to *command-line-args*."))
(defn read-file [file] (defn read-file [file]
(let [f (io/file file)] (let [f (io/file file)]
@ -211,16 +211,15 @@
:else :else
(try (try
(let [expr (if file (read-file file) expression)] (let [expr (if file (read-file file) expression)]
(if expr
(loop [in (read-next *in*)] (loop [in (read-next *in*)]
(let [ctx (update ctx :bindings assoc (with-meta '*in* (let [ctx (update ctx :bindings assoc (with-meta '*in*
(when-not stream? (when-not stream?
{:sci/deref! true})) in)] {:sci/deref! true})) in)]
(if (identical? ::EOF in) (if (identical? ::EOF in)
[nil 0] ;; done streaming [nil 0] ;; done streaming
(let [res [(do (when-not (or expression file) (let [res [(let [res (sci/eval-string expr ctx)]
(throw (Exception. (str args "Babashka expected an expression. Type --help to print help.")))) (when (some? res)
(let [res (sci/eval-string expr ctx)]
(if (some? res)
(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)
@ -228,10 +227,11 @@
:while (not (pipe-signal-received?))] :while (not (pipe-signal-received?))]
(pr-f l)) (pr-f l))
(pr-f res)) (pr-f res))
(prn res))))) 0]] (prn res)))) 0]]
(if stream? (if stream?
(recur (read-next *in*)) (recur (read-next *in*))
res)))))) res)))))
[(print-help) 1]))
(catch Throwable e (catch Throwable e
(binding [*out* *err*] (binding [*out* *err*]
(let [d (ex-data e) (let [d (ex-data e)

View file

@ -101,8 +101,12 @@
(deftest malformed-command-line-args-test (deftest malformed-command-line-args-test
(is (thrown-with-msg? Exception #"File does not exist: non-existing\n" (is (thrown-with-msg? Exception #"File does not exist: non-existing\n"
(bb nil "-f" "non-existing"))) (bb nil "-f" "non-existing")))
(is (thrown-with-msg? Exception #"expression" (testing "no arguments prints help"
(bb nil)))) (is (str/includes?
(try (test-utils/bb nil)
(catch clojure.lang.ExceptionInfo e
(:stdout (ex-data e))))
"Usage:"))))
(deftest ssl-test (deftest ssl-test
(let [graalvm-home (System/getenv "GRAALVM_HOME") (let [graalvm-home (System/getenv "GRAALVM_HOME")

View file

@ -6,15 +6,19 @@
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(defn bb-jvm [input & args] (defn bb-jvm [input & args]
(let [sw (java.io.StringWriter.) (let [es (java.io.StringWriter.)
res (binding [*err* sw] os (java.io.StringWriter.)]
(with-out-str (binding [*err* es
(if input *out* os]
(let [res (if input
(with-in-str input (with-in-str input
(apply main/main args)) (apply main/main args))
(apply main/main args))))] (apply main/main args))]
(if-let [err ^String (not-empty (str sw))] (if (zero? res)
(throw (Exception. err)) res))) (str os)
(throw (ex-info (str es)
{:stdout (str os)
:stderr (str es)})))))))
(defn bb-native [input & args] (defn bb-native [input & args]
(let-programs [bb "./bb"] (let-programs [bb "./bb"]