--uberscript option (#197)
This commit is contained in:
parent
c446dced0e
commit
ded6dd2355
6 changed files with 198 additions and 130 deletions
71
README.md
71
README.md
|
|
@ -137,25 +137,26 @@ You may also download a binary from [Github](https://github.com/borkdude/babashk
|
||||||
Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] [--verbose]
|
Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] [--verbose]
|
||||||
[ ( --classpath | -cp ) <cp> ] [ ( --main | -m ) <main-namespace> ]
|
[ ( --classpath | -cp ) <cp> ] [ ( --main | -m ) <main-namespace> ]
|
||||||
( -e <expression> | -f <file> | --repl | --socket-repl [<host>:]<port> )
|
( -e <expression> | -f <file> | --repl | --socket-repl [<host>:]<port> )
|
||||||
[ arg* ]
|
[ --uberscript <file> ] [ arg* ]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
--help, -h or -? Print this help text.
|
--help, -h or -? Print this help text.
|
||||||
--version Print the current version of babashka.
|
--version Print the current version of babashka.
|
||||||
-i Bind *input* to a lazy seq of lines from stdin.
|
-i Bind *input* to a lazy seq of lines from stdin.
|
||||||
-I Bind *input* to a lazy seq of EDN values from stdin.
|
-I Bind *input* to a lazy seq of EDN values from stdin.
|
||||||
-o Write lines to stdout.
|
-o Write lines to stdout.
|
||||||
-O Write EDN values to stdout.
|
-O Write EDN values to stdout.
|
||||||
--verbose Print entire stacktrace in case of exception.
|
--verbose Print entire stacktrace in case of exception.
|
||||||
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
||||||
-e, --eval <expr> Evaluate an expression.
|
-e, --eval <expr> Evaluate an expression.
|
||||||
-f, --file <path> Evaluate a file.
|
-f, --file <path> Evaluate a file.
|
||||||
-cp, --classpath Classpath to use.
|
-cp, --classpath Classpath to use.
|
||||||
-m, --main <ns> Call the -main function from namespace with args.
|
-m, --main <ns> Call the -main function from namespace with args.
|
||||||
--repl Start REPL
|
--uberscript <file> Collect preloads, -e, -f and -m and all required namespaces from the classpath into a single executable 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).
|
--repl Start REPL
|
||||||
--time Print execution time before exiting.
|
--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 that is not parsed as a option 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*.
|
Everything after that is bound to *command-line-args*.
|
||||||
|
|
@ -408,10 +409,10 @@ Note that you can use the `clojure` tool to produce classpaths and download depe
|
||||||
``` shellsession
|
``` shellsession
|
||||||
$ cat deps.edn
|
$ cat deps.edn
|
||||||
{:deps
|
{:deps
|
||||||
{my_gist_script
|
{my_gist_script
|
||||||
{:git/url "https://gist.github.com/borkdude/263b150607f3ce03630e114611a4ef42"
|
{:git/url "https://gist.github.com/borkdude/263b150607f3ce03630e114611a4ef42"
|
||||||
:sha "cfc761d06dfb30bb77166b45d439fe8fe54a31b8"}}}
|
:sha "cfc761d06dfb30bb77166b45d439fe8fe54a31b8"}}
|
||||||
|
:aliases {:my-script {:main-opts ["-m" "my-gist-script"]}}}
|
||||||
|
|
||||||
$ CLASSPATH=$(clojure -Spath)
|
$ CLASSPATH=$(clojure -Spath)
|
||||||
$ bb --classpath "$CLASSPATH" --main my-gist-script
|
$ bb --classpath "$CLASSPATH" --main my-gist-script
|
||||||
|
|
@ -428,6 +429,36 @@ $ bb "(my-gist-script/-main)"
|
||||||
Hello from gist script!
|
Hello from gist script!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Using the [deps.clj](https://github.com/borkdude/deps.clj/) script, you can also
|
||||||
|
pass the classpath and main opts to `bb`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
$ deps.clj -A:my-script -Scommand "bb my_script.clj {{main-opts}}"
|
||||||
|
Hello from gist script!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Uberscript
|
||||||
|
|
||||||
|
The `--uberscript <file>` option collects the expressions in
|
||||||
|
`BABASHKA_PRELOADS`, the command line expression or file, the main entrypoint
|
||||||
|
and all required namespaces from the classpath into a single file. This can be
|
||||||
|
convenient for debugging purposes and deployment.
|
||||||
|
|
||||||
|
Given the `deps.edn` from above:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
$ deps.clj -A:my-script -Scommand "bb {{main-opts}} --uberscript my-script.clj"
|
||||||
|
|
||||||
|
$ cat my-script.clj
|
||||||
|
(ns my-gist-script)
|
||||||
|
(defn -main [& args]
|
||||||
|
(println "Hello from gist script!"))(require '[my-gist-script])
|
||||||
|
(ns user (:require [my-gist-script])) (apply my-gist-script/-main *command-line-args*)%
|
||||||
|
|
||||||
|
$ bb my-script.clj
|
||||||
|
Hello from gist script!
|
||||||
|
```
|
||||||
|
|
||||||
## Parsing command line arguments
|
## Parsing command line arguments
|
||||||
|
|
||||||
Babashka ships with `clojure.tools.cli`:
|
Babashka ships with `clojure.tools.cli`:
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.0.51-SNAPSHOT
|
0.0.51
|
||||||
2
sci
2
sci
|
|
@ -1 +1 @@
|
||||||
Subproject commit 79563a0c94daa11e56e0969c963a52af9f7ee00f
|
Subproject commit 92f2251fcc2ca795db05e78605e1c78bb8462884
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
(ns babashka.impl.utils
|
|
||||||
{:no-doc true}
|
|
||||||
(:require
|
|
||||||
[sci.impl.vars :as vars]
|
|
||||||
[sci.core :as sci]))
|
|
||||||
|
|
||||||
(sci.impl.vars/bindRoot sci/in *in*)
|
|
||||||
(sci.impl.vars/bindRoot sci/out *out*)
|
|
||||||
(sci.impl.vars/bindRoot sci/err *err*)
|
|
||||||
|
|
||||||
(defn eval-string [expr ctx]
|
|
||||||
(sci/eval-string expr ctx))
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
[babashka.impl.repl :as repl]
|
[babashka.impl.repl :as repl]
|
||||||
[babashka.impl.socket-repl :as socket-repl]
|
[babashka.impl.socket-repl :as socket-repl]
|
||||||
[babashka.impl.tools.cli :refer [tools-cli-namespace]]
|
[babashka.impl.tools.cli :refer [tools-cli-namespace]]
|
||||||
[babashka.impl.utils :refer [eval-string]]
|
|
||||||
[babashka.wait :as wait]
|
[babashka.wait :as wait]
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
|
|
@ -26,6 +25,10 @@
|
||||||
[sci.impl.interpreter :refer [eval-string*]])
|
[sci.impl.interpreter :refer [eval-string*]])
|
||||||
(:gen-class))
|
(:gen-class))
|
||||||
|
|
||||||
|
(sci.impl.vars/bindRoot sci/in *in*)
|
||||||
|
(sci.impl.vars/bindRoot sci/out *out*)
|
||||||
|
(sci.impl.vars/bindRoot sci/err *err*)
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
;; To detect problems when generating the image, run:
|
;; To detect problems when generating the image, run:
|
||||||
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
|
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
|
||||||
|
|
@ -68,6 +71,15 @@
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:edn-in true
|
:edn-in true
|
||||||
:edn-out true))
|
:edn-out true))
|
||||||
|
("--classpath", "-cp")
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(assoc opts-map :classpath (first options))))
|
||||||
|
("--uberscript")
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:uberscript (first options))))
|
||||||
("-f" "--file")
|
("-f" "--file")
|
||||||
(let [options (next options)]
|
(let [options (next options)]
|
||||||
(recur (next options)
|
(recur (next options)
|
||||||
|
|
@ -87,10 +99,6 @@
|
||||||
(let [options (next options)]
|
(let [options (next options)]
|
||||||
(recur (next options)
|
(recur (next options)
|
||||||
(assoc opts-map :expression (first options))))
|
(assoc opts-map :expression (first options))))
|
||||||
("--classpath", "-cp")
|
|
||||||
(let [options (next options)]
|
|
||||||
(recur (next options)
|
|
||||||
(assoc opts-map :classpath (first options))))
|
|
||||||
("--main", "-m")
|
("--main", "-m")
|
||||||
(let [options (next options)]
|
(let [options (next options)]
|
||||||
(recur (next options)
|
(recur (next options)
|
||||||
|
|
@ -128,7 +136,7 @@
|
||||||
(def usage-string "Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] [--verbose]
|
(def usage-string "Usage: bb [ -i | -I ] [ -o | -O ] [ --stream ] [--verbose]
|
||||||
[ ( --classpath | -cp ) <cp> ] [ ( --main | -m ) <main-namespace> ]
|
[ ( --classpath | -cp ) <cp> ] [ ( --main | -m ) <main-namespace> ]
|
||||||
( -e <expression> | -f <file> | --repl | --socket-repl [<host>:]<port> )
|
( -e <expression> | -f <file> | --repl | --socket-repl [<host>:]<port> )
|
||||||
[ arg* ]")
|
[ --uberscript <file> ] [ arg* ]")
|
||||||
(defn print-usage []
|
(defn print-usage []
|
||||||
(println usage-string))
|
(println usage-string))
|
||||||
|
|
||||||
|
|
@ -140,21 +148,22 @@
|
||||||
(println)
|
(println)
|
||||||
(println "Options:")
|
(println "Options:")
|
||||||
(println "
|
(println "
|
||||||
--help, -h or -? Print this help text.
|
--help, -h or -? Print this help text.
|
||||||
--version Print the current version of babashka.
|
--version Print the current version of babashka.
|
||||||
-i Bind *input* to a lazy seq of lines from stdin.
|
-i Bind *input* to a lazy seq of lines from stdin.
|
||||||
-I Bind *input* to a lazy seq of EDN values from stdin.
|
-I Bind *input* to a lazy seq of EDN values from stdin.
|
||||||
-o Write lines to stdout.
|
-o Write lines to stdout.
|
||||||
-O Write EDN values to stdout.
|
-O Write EDN values to stdout.
|
||||||
--verbose Print entire stacktrace in case of exception.
|
--verbose Print entire stacktrace in case of exception.
|
||||||
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
||||||
-e, --eval <expr> Evaluate an expression.
|
-e, --eval <expr> Evaluate an expression.
|
||||||
-f, --file <path> Evaluate a file.
|
-f, --file <path> Evaluate a file.
|
||||||
-cp, --classpath Classpath to use.
|
-cp, --classpath Classpath to use.
|
||||||
-m, --main <ns> Call the -main function from namespace with args.
|
-m, --main <ns> Call the -main function from namespace with args.
|
||||||
--repl Start REPL
|
--uberscript <file> Collect preloads, -e, -f and -m and all required namespaces from the classpath into a single executable 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).
|
--repl Start REPL
|
||||||
--time Print execution time before exiting.
|
--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 that is not parsed as a option 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*."))
|
Everything after that is bound to *command-line-args*."))
|
||||||
|
|
@ -173,14 +182,14 @@ Everything after that is bound to *command-line-args*."))
|
||||||
|
|
||||||
(def reflection-var (sci/new-dynamic-var '*warn-on-reflection* false))
|
(def reflection-var (sci/new-dynamic-var '*warn-on-reflection* false))
|
||||||
|
|
||||||
(defn load-file* [ctx f]
|
(defn load-file* [sci-ctx f]
|
||||||
(let [f (io/file f)
|
(let [f (io/file f)
|
||||||
s (slurp f)]
|
s (slurp f)]
|
||||||
(sci/with-bindings {vars/file-var (.getCanonicalPath f)}
|
(sci/with-bindings {vars/file-var (.getCanonicalPath f)}
|
||||||
(eval-string s ctx))))
|
(eval-string* sci-ctx s))))
|
||||||
|
|
||||||
(defn eval* [ctx form]
|
(defn eval* [sci-ctx form]
|
||||||
(eval-string (pr-str form) ctx))
|
(eval-string* sci-ctx (pr-str form)))
|
||||||
|
|
||||||
(defn start-socket-repl! [address ctx]
|
(defn start-socket-repl! [address ctx]
|
||||||
(socket-repl/start-repl! address ctx)
|
(socket-repl/start-repl! address ctx)
|
||||||
|
|
@ -194,6 +203,45 @@ Everything after that is bound to *command-line-args*."))
|
||||||
;; (sci/set-var-root! sci/*out* *out*)
|
;; (sci/set-var-root! sci/*out* *out*)
|
||||||
;; (sci/set-var-root! sci/*err* *err*)
|
;; (sci/set-var-root! sci/*err* *err*)
|
||||||
|
|
||||||
|
(def aliases
|
||||||
|
'{tools.cli 'clojure.tools.cli
|
||||||
|
edn clojure.edn
|
||||||
|
wait babashka.wait
|
||||||
|
sig babashka.signal
|
||||||
|
shell clojure.java.shell
|
||||||
|
io clojure.java.io
|
||||||
|
async clojure.core.async
|
||||||
|
csv clojure.data.csv
|
||||||
|
json cheshire.core})
|
||||||
|
|
||||||
|
(def namespaces
|
||||||
|
{'clojure.tools.cli tools-cli-namespace
|
||||||
|
'clojure.edn {'read edn/read
|
||||||
|
'read-string edn/read-string}
|
||||||
|
'clojure.java.shell {'sh shell/sh}
|
||||||
|
'babashka.wait {'wait-for-port wait/wait-for-port
|
||||||
|
'wait-for-path wait/wait-for-path}
|
||||||
|
'babashka.signal {'pipe-signal-received? pipe-signal-received?}
|
||||||
|
'clojure.java.io io-namespace
|
||||||
|
'clojure.core.async async-namespace
|
||||||
|
'clojure.data.csv csv/csv-namespace
|
||||||
|
'cheshire.core cheshire-core-namespace})
|
||||||
|
|
||||||
|
(def bindings
|
||||||
|
{'java.lang.System/exit exit ;; override exit, so we have more control
|
||||||
|
'System/exit exit})
|
||||||
|
|
||||||
|
(defn error-handler* [^Exception e verbose?]
|
||||||
|
(binding [*out* *err*]
|
||||||
|
(let [d (ex-data e)
|
||||||
|
exit-code (:bb/exit-code d)]
|
||||||
|
(if exit-code [nil exit-code]
|
||||||
|
(do (if verbose?
|
||||||
|
(print-stack-trace e)
|
||||||
|
(println (.getMessage e)))
|
||||||
|
(flush)
|
||||||
|
[nil 1])))))
|
||||||
|
|
||||||
(defn main
|
(defn main
|
||||||
[& args]
|
[& args]
|
||||||
(handle-pipe!)
|
(handle-pipe!)
|
||||||
|
|
@ -205,7 +253,7 @@ Everything after that is bound to *command-line-args*."))
|
||||||
:expression :stream? :time?
|
:expression :stream? :time?
|
||||||
:repl :socket-repl
|
:repl :socket-repl
|
||||||
:verbose? :classpath
|
:verbose? :classpath
|
||||||
:main] :as _opts}
|
:main :uberscript] :as _opts}
|
||||||
(parse-opts args)
|
(parse-opts args)
|
||||||
read-next (fn [*in*]
|
read-next (fn [*in*]
|
||||||
(if (pipe-signal-received?)
|
(if (pipe-signal-received?)
|
||||||
|
|
@ -219,6 +267,7 @@ Everything after that is bound to *command-line-args*."))
|
||||||
(edn-seq *in*)
|
(edn-seq *in*)
|
||||||
:else
|
:else
|
||||||
(edn/read *in*))))))
|
(edn/read *in*))))))
|
||||||
|
uberscript-sources (atom ())
|
||||||
env (atom {})
|
env (atom {})
|
||||||
classpath (or classpath
|
classpath (or classpath
|
||||||
(System/getenv "BABASHKA_CLASSPATH"))
|
(System/getenv "BABASHKA_CLASSPATH"))
|
||||||
|
|
@ -226,35 +275,18 @@ Everything after that is bound to *command-line-args*."))
|
||||||
(cp/loader classpath))
|
(cp/loader classpath))
|
||||||
load-fn (when classpath
|
load-fn (when classpath
|
||||||
(fn [{:keys [:namespace]}]
|
(fn [{:keys [:namespace]}]
|
||||||
(cp/source-for-namespace loader namespace)))
|
(let [res (cp/source-for-namespace loader namespace)]
|
||||||
|
(when uberscript (swap! uberscript-sources conj (:source res)))
|
||||||
|
res)))
|
||||||
_ (when file (vars/bindRoot vars/file-var (.getCanonicalPath (io/file file))))
|
_ (when file (vars/bindRoot vars/file-var (.getCanonicalPath (io/file file))))
|
||||||
ctx {:aliases '{tools.cli 'clojure.tools.cli
|
ctx {:aliases aliases
|
||||||
edn clojure.edn
|
:namespaces (assoc namespaces 'clojure.core
|
||||||
wait babashka.wait
|
(assoc core-extras
|
||||||
sig babashka.signal
|
'*command-line-args*
|
||||||
shell clojure.java.shell
|
(sci/new-dynamic-var '*command-line-args* command-line-args)
|
||||||
io clojure.java.io
|
'*file* vars/file-var
|
||||||
async clojure.core.async
|
'*warn-on-reflection* reflection-var))
|
||||||
csv clojure.data.csv
|
:bindings bindings
|
||||||
json cheshire.core}
|
|
||||||
:namespaces {'clojure.core (assoc core-extras
|
|
||||||
'*command-line-args*
|
|
||||||
(sci/new-dynamic-var '*command-line-args* command-line-args)
|
|
||||||
'*file* vars/file-var
|
|
||||||
'*warn-on-reflection* reflection-var)
|
|
||||||
'clojure.tools.cli tools-cli-namespace
|
|
||||||
'clojure.edn {'read edn/read
|
|
||||||
'read-string edn/read-string}
|
|
||||||
'clojure.java.shell {'sh shell/sh}
|
|
||||||
'babashka.wait {'wait-for-port wait/wait-for-port
|
|
||||||
'wait-for-path wait/wait-for-path}
|
|
||||||
'babashka.signal {'pipe-signal-received? pipe-signal-received?}
|
|
||||||
'clojure.java.io io-namespace
|
|
||||||
'clojure.core.async async-namespace
|
|
||||||
'clojure.data.csv csv/csv-namespace
|
|
||||||
'cheshire.core cheshire-core-namespace}
|
|
||||||
:bindings {'java.lang.System/exit exit ;; override exit, so we have more control
|
|
||||||
'System/exit exit}
|
|
||||||
:env env
|
:env env
|
||||||
:features #{:bb}
|
:features #{:bb}
|
||||||
:classes classes/class-map
|
:classes classes/class-map
|
||||||
|
|
@ -271,37 +303,47 @@ Everything after that is bound to *command-line-args*."))
|
||||||
String java.lang.String
|
String java.lang.String
|
||||||
System java.lang.System
|
System java.lang.System
|
||||||
Thread java.lang.Thread}
|
Thread java.lang.Thread}
|
||||||
:load-fn load-fn}
|
:load-fn load-fn
|
||||||
ctx (update-in ctx [:namespaces 'clojure.core] assoc
|
:dry-run uberscript}
|
||||||
'eval #(eval* ctx %)
|
|
||||||
'load-file #(load-file* ctx %))
|
|
||||||
ctx (assoc-in ctx [:namespaces 'clojure.main 'repl]
|
|
||||||
(fn [& opts]
|
|
||||||
(let [opts (apply hash-map opts)]
|
|
||||||
(repl/start-repl! ctx opts))))
|
|
||||||
ctx (addons/future ctx)
|
ctx (addons/future ctx)
|
||||||
_preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim) (eval-string ctx))
|
|
||||||
expression (if main
|
|
||||||
(format "(ns user (:require [%1$s])) (apply %1$s/-main *command-line-args*)"
|
|
||||||
main)
|
|
||||||
expression)
|
|
||||||
sci-ctx (sci-opts/init ctx)
|
sci-ctx (sci-opts/init ctx)
|
||||||
|
_ (swap! (:env sci-ctx)
|
||||||
|
(fn [env]
|
||||||
|
(update-in env [:namespaces 'clojure.core] assoc
|
||||||
|
'eval #(eval* sci-ctx %)
|
||||||
|
'load-file #(load-file* sci-ctx %))))
|
||||||
|
_ (swap! (:env sci-ctx)
|
||||||
|
(fn [env]
|
||||||
|
(assoc-in env [:namespaces 'clojure.main 'repl]
|
||||||
|
(fn [& opts]
|
||||||
|
(let [opts (apply hash-map opts)]
|
||||||
|
(repl/start-repl! sci-ctx opts))))))
|
||||||
|
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
|
||||||
|
[expression exit-code]
|
||||||
|
(cond expression [expression nil]
|
||||||
|
main [(format "(ns user (:require [%1$s])) (apply %1$s/-main *command-line-args*)"
|
||||||
|
main) nil]
|
||||||
|
file (try [(read-file file) nil]
|
||||||
|
(catch Exception e
|
||||||
|
(error-handler* e verbose?))))
|
||||||
|
expression (str (when preloads
|
||||||
|
(str preloads "\n"))
|
||||||
|
expression)
|
||||||
exit-code
|
exit-code
|
||||||
(sci/with-bindings {reflection-var false}
|
(or exit-code
|
||||||
(or
|
(sci/with-bindings {reflection-var false}
|
||||||
#_(binding [*out* *err*]
|
(or
|
||||||
(prn ">>" _opts))
|
#_(binding [*out* *err*]
|
||||||
(second
|
(prn ">>" _opts))
|
||||||
(cond version
|
(second
|
||||||
[(print-version) 0]
|
(cond version
|
||||||
help?
|
[(print-version) 0]
|
||||||
[(print-help) 0]
|
help?
|
||||||
repl [(repl/start-repl! sci-ctx) 0]
|
[(print-help) 0]
|
||||||
socket-repl [(start-socket-repl! socket-repl sci-ctx) 0]
|
repl [(repl/start-repl! sci-ctx) 0]
|
||||||
:else
|
socket-repl [(start-socket-repl! socket-repl sci-ctx) 0]
|
||||||
(try
|
expression
|
||||||
(let [ expr (if file (read-file file) expression)]
|
(try
|
||||||
(if expr
|
|
||||||
(loop [in (read-next *in*)]
|
(loop [in (read-next *in*)]
|
||||||
(let [_ (swap! env update-in [:namespaces 'user]
|
(let [_ (swap! env update-in [:namespaces 'user]
|
||||||
assoc (with-meta '*input*
|
assoc (with-meta '*input*
|
||||||
|
|
@ -310,7 +352,7 @@ Everything after that is bound to *command-line-args*."))
|
||||||
(sci/new-dynamic-var '*input* in))]
|
(sci/new-dynamic-var '*input* in))]
|
||||||
(if (identical? ::EOF in)
|
(if (identical? ::EOF in)
|
||||||
[nil 0] ;; done streaming
|
[nil 0] ;; done streaming
|
||||||
(let [res [(let [res (eval-string* sci-ctx expr)]
|
(let [res [(let [res (eval-string* sci-ctx expression)]
|
||||||
(when (some? res)
|
(when (some? res)
|
||||||
(if-let [pr-f (cond shell-out println
|
(if-let [pr-f (cond shell-out println
|
||||||
edn-out prn)]
|
edn-out prn)]
|
||||||
|
|
@ -323,22 +365,22 @@ Everything after that is bound to *command-line-args*."))
|
||||||
(if stream?
|
(if stream?
|
||||||
(recur (read-next *in*))
|
(recur (read-next *in*))
|
||||||
res)))))
|
res)))))
|
||||||
[(repl/start-repl! sci-ctx) 0]))
|
(catch Throwable e
|
||||||
(catch Throwable e
|
(error-handler* e verbose?)))
|
||||||
(binding [*out* *err*]
|
:else [(repl/start-repl! sci-ctx) 0]))
|
||||||
(let [d (ex-data e)
|
1)))
|
||||||
exit-code (:bb/exit-code d)]
|
|
||||||
(if exit-code [nil exit-code]
|
|
||||||
(do (if verbose?
|
|
||||||
(print-stack-trace e)
|
|
||||||
(println (.getMessage e)))
|
|
||||||
(flush)
|
|
||||||
[nil 1]))))))))
|
|
||||||
1))
|
|
||||||
t1 (System/currentTimeMillis)]
|
t1 (System/currentTimeMillis)]
|
||||||
|
(flush)
|
||||||
|
(when uberscript
|
||||||
|
uberscript
|
||||||
|
(let [uberscript-out uberscript]
|
||||||
|
(spit uberscript-out "") ;; reset file
|
||||||
|
(doseq [s @uberscript-sources]
|
||||||
|
(spit uberscript-out s :append true))
|
||||||
|
(spit uberscript-out expression :append true)
|
||||||
|
(spit uberscript-out file :append true)))
|
||||||
(when time? (binding [*out* *err*]
|
(when time? (binding [*out* *err*]
|
||||||
(println "bb took" (str (- t1 t0) "ms."))))
|
(println "bb took" (str (- t1 t0) "ms."))))
|
||||||
(flush)
|
|
||||||
exit-code))
|
exit-code))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,13 @@
|
||||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
(tu/bb nil "--classpath" "test-resources/babashka/src_for_classpath_test" "-m" "my.main" "1" "2" "3" "4"))))
|
(tu/bb nil "--classpath" "test-resources/babashka/src_for_classpath_test" "-m" "my.main" "1" "2" "3" "4"))))
|
||||||
|
|
||||||
|
(deftest uberscript-test
|
||||||
|
(let [tmp-file (java.io.File/createTempFile "uberscript" ".clj")]
|
||||||
|
(.deleteOnExit tmp-file)
|
||||||
|
(tu/bb nil "--classpath" "test-resources/babashka/src_for_classpath_test" "-m" "my.main" "--uberscript" (.getPath tmp-file))
|
||||||
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
|
(tu/bb nil "--file" (.getPath tmp-file) "1" "2" "3" "4")))))
|
||||||
|
|
||||||
(deftest error-while-loading-test
|
(deftest error-while-loading-test
|
||||||
(is (true?
|
(is (true?
|
||||||
(bb nil "--classpath" "test-resources/babashka/src_for_classpath_test"
|
(bb nil "--classpath" "test-resources/babashka/src_for_classpath_test"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue