Add an -e/--eval option, and automatically detect file name args (#60)

When an argument is a file name (i.e. the file exists), then treat it as a file,
rather than as an expression.

Update dev docs.
This commit is contained in:
Arne Brasseur 2019-09-06 15:31:54 +02:00 committed by Michiel Borkent
parent 619b3fe2b5
commit 1e1712b780
3 changed files with 62 additions and 26 deletions

View file

@ -321,7 +321,27 @@ $ bb '(slurp "https://www.clojure.org")' | bb '(subs *in* 0 50)'
"<!doctype html><html itemscope=\"\" itemtype=\"http:/"
```
## Test
## Developing Babashka
To work on Babashka itself make sure Git submodules are checked out.
``` shellsession
$ git clone https://github.com/borkdude/babashka --recursive
```
To update later on:
``` shellsession
$ git submodule update --recursive
```
You need [Leiningen](https://leiningen.org/), and for building binaries you need GraalVM.
### REPL
`lein repl` will get you a standard REPL/nREPL connection. To work on tests use `lein with-profiles +test repl`.
### Test
Test on the JVM:
@ -334,22 +354,7 @@ Test the native version:
BABASHKA_TEST_ENV=native script/test
## Build
You will need leiningen and GraalVM.
This repo contains a submodule, so you will have clone that too. If you're
doing that for the first time:
``` shellsession
$ git submodule update --init --recursive
```
and for subsequent updates:
``` shellsession
$ git submodule update --recursive
```
### Build
To build this project, set `$GRAALVM_HOME` to the GraalVM distribution directory.

View file

@ -24,7 +24,7 @@
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
;; with the java provided by GraalVM.
(defn- parse-opts [options]
(defn parse-opts [options]
(let [opts (loop [options options
opts-map {}]
(if-let [opt (first options)]
@ -67,13 +67,21 @@
(recur (rest options)
(assoc opts-map
:socket-repl (first options))))
(if (not (or (:file opts-map)
(:socket-repl opts-map)))
("--eval", "-e")
(let [options (rest options)]
(recur (rest options)
(assoc opts-map :expression (first options))))
(if (some opts-map [:file :socket-repl :expression])
(assoc opts-map
:expression opt
:command-line-args (rest options))
(assoc opts-map
:command-line-args options)))
:command-line-args options)
(if (and (not= \( (first (str/trim opt)))
(.exists (io/file opt)))
(assoc opts-map
:file opt
:command-line-args (rest options))
(assoc opts-map
:expression opt
:command-line-args (rest options)))))
opts-map))]
opts))
@ -93,7 +101,7 @@
(defn print-version []
(println (str "babashka v"(str/trim (slurp (io/resource "BABASHKA_VERSION"))))))
(def usage-string "Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] ( 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 []
(println usage-string))
@ -113,9 +121,12 @@
-o: write lines 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.
--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).
--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.
"))
(defn read-file [file]

View file

@ -10,6 +10,26 @@
(defn bb [input & args]
(edn/read-string (apply test-utils/bb (str input) (map str args))))
(deftest parse-opts-test
(is (= {:expression "(println 123)"}
(main/parse-opts ["-e" "(println 123)"])))
(is (= {:expression "(println 123)"}
(main/parse-opts ["--eval" "(println 123)"])))
(testing "distinguish automatically between expression or file name"
(is (= {:expression "(println 123)"
:command-line-args []}
(main/parse-opts ["(println 123)"])))
(is (= {:file "src/babashka/main.clj"
:command-line-args []}
(main/parse-opts ["src/babashka/main.clj"])))
(is (= {:expression "does-not-exist"
:command-line-args []}
(main/parse-opts ["does-not-exist"])))))
(deftest main-test
(testing "-io behaves as identity"
(= "foo\nbar\n" (test-utils/bb "foo\nbar\n" "-io" "*in*")))