bb.edn: first iteration
This commit is contained in:
parent
2bc935d3d8
commit
d71c3622ec
13 changed files with 382 additions and 232 deletions
|
|
@ -67,8 +67,7 @@
|
|||
:feature/hiccup
|
||||
:feature/test-check
|
||||
:feature/spec-alpha
|
||||
{:dependencies [[clj-commons/conch "0.9.2"]
|
||||
[com.clojure-goes-fast/clj-async-profiler "0.4.1"]
|
||||
{:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.4.1"]
|
||||
[com.opentable.components/otj-pg-embedded "0.13.3"]]}]
|
||||
:uberjar {:global-vars {*assert* false}
|
||||
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
||||
|
|
|
|||
|
|
@ -28,17 +28,18 @@
|
|||
resource-paths)))
|
||||
|
||||
(defn path-from-jar
|
||||
[^java.io.File jar-file resource-paths {:keys [:url?]}]
|
||||
(with-open [jar (JarFile. jar-file)]
|
||||
(some (fn [path]
|
||||
(when-let [entry (.getEntry jar path)]
|
||||
(if url?
|
||||
;; manual conversion, faster than going through .toURI
|
||||
(java.net.URL. "jar" nil
|
||||
(str "file:" (.getAbsolutePath jar-file) "!/" path))
|
||||
{:file path
|
||||
:source (slurp (.getInputStream jar entry))})))
|
||||
resource-paths)))
|
||||
[^java.io.File jar-file resource-paths opts]
|
||||
(let [url? (:url? opts)]
|
||||
(with-open [jar (JarFile. jar-file)]
|
||||
(some (fn [path]
|
||||
(when-let [entry (.getEntry jar path)]
|
||||
(if url?
|
||||
;; manual conversion, faster than going through .toURI
|
||||
(java.net.URL. "jar" nil
|
||||
(str "file:" (.getAbsolutePath jar-file) "!/" path))
|
||||
{:file path
|
||||
:source (slurp (.getInputStream jar entry))})))
|
||||
resource-paths))))
|
||||
|
||||
(deftype JarFileResolver [jar-file]
|
||||
IResourceResolver
|
||||
|
|
@ -57,8 +58,10 @@
|
|||
(getResources [_ resource-paths opts]
|
||||
(keep #(getResource % resource-paths opts) entries)))
|
||||
|
||||
(def path-sep (System/getProperty "path.separator"))
|
||||
|
||||
(defn loader [^String classpath]
|
||||
(let [parts (.split classpath (System/getProperty "path.separator"))
|
||||
(let [parts (.split classpath path-sep)
|
||||
entries (map part->entry parts)]
|
||||
(Loader. entries)))
|
||||
|
||||
|
|
@ -88,7 +91,7 @@
|
|||
(fn [{:keys [:cp]}]
|
||||
(let [new-cp
|
||||
(if-not cp extra-classpath
|
||||
(str cp (System/getProperty "path.separator") extra-classpath))]
|
||||
(str cp path-sep extra-classpath))]
|
||||
{:loader (loader new-cp)
|
||||
:cp new-cp})))
|
||||
nil)
|
||||
|
|
@ -96,7 +99,7 @@
|
|||
(defn split-classpath
|
||||
"Returns the classpath as a seq of strings, split by the platform
|
||||
specific path separator."
|
||||
([^String cp] (vec (.split cp (System/getProperty "path.separator")))))
|
||||
([^String cp] (vec (.split cp path-sep))))
|
||||
|
||||
(defn get-classpath
|
||||
"Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath."
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
ret#))
|
||||
|
||||
(def data-readers (sci/new-dynamic-var '*data-readers* nil))
|
||||
(def command-line-args (sci/new-dynamic-var '*command-line-args* nil))
|
||||
(def warn-on-reflection (sci/new-dynamic-var '*warn-on-reflection* false))
|
||||
|
||||
(defn read+string
|
||||
"Added for compatibility. Must be used with
|
||||
|
|
@ -59,4 +61,6 @@
|
|||
'default-data-readers default-data-readers
|
||||
'xml-seq (copy-core-var xml-seq)
|
||||
'read+string (fn [& args]
|
||||
(apply read+string @common/ctx args))})
|
||||
(apply read+string @common/ctx args))
|
||||
'*command-line-args* command-line-args
|
||||
'*warn-on-reflection* warn-on-reflection})
|
||||
|
|
|
|||
|
|
@ -57,11 +57,20 @@
|
|||
then used to resolve dependencies in babashka."
|
||||
([deps-map] (add-deps deps-map nil))
|
||||
([deps-map {:keys [:aliases]}]
|
||||
(let [args ["-Spath" "-Sdeps" (str deps-map)]
|
||||
args (cond-> args
|
||||
aliases (conj (str "-A:" (str/join ":" aliases))))
|
||||
cp (with-out-str (apply deps/-main args))]
|
||||
(cp/add-classpath cp))))
|
||||
(when-let [paths (:paths deps-map)]
|
||||
(cp/add-classpath (str/join cp/path-sep paths)))
|
||||
(when-let [deps-map (not-empty (dissoc deps-map :paths :tasks))]
|
||||
(let [deps-map (assoc-in deps-map [:aliases :org.babashka/defaults]
|
||||
'{:replace-paths [] ;; babashka sets paths manually
|
||||
:classpath-overrides {org.clojure/clojure ""
|
||||
org.clojure/spec.alpha ""
|
||||
org.clojure/core.specs.alpha ""}})
|
||||
args ["-Spath" "-Sdeps" (str deps-map)]
|
||||
args (conj args (str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases))))
|
||||
cp (with-out-str (apply deps/-main args))
|
||||
cp (str/trim cp)
|
||||
cp (str/replace cp (re-pattern (str cp/path-sep "+$")) "")]
|
||||
(cp/add-classpath cp)))))
|
||||
|
||||
(defn clojure
|
||||
"Starts clojure similar to CLI. Use `rlwrap bb` for `clj`-like invocation.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
{:no-doc true}
|
||||
(:refer-clojure :exclude [error-handler])
|
||||
(:require
|
||||
[babashka.fs :as fs]
|
||||
[babashka.impl.bencode :refer [bencode-namespace]]
|
||||
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
|
||||
[babashka.impl.classes :as classes]
|
||||
|
|
@ -74,185 +75,100 @@
|
|||
;; 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]
|
||||
(let [opts (loop [options options
|
||||
opts-map {}]
|
||||
(if options
|
||||
(let [opt (first options)]
|
||||
(case opt
|
||||
("--") (assoc opts-map :command-line-args (next options))
|
||||
("--clojure") (assoc opts-map :clojure true
|
||||
:opts (rest options))
|
||||
("--version") {:version true}
|
||||
("--help" "-h" "-?") {:help? true}
|
||||
("--verbose")(recur (next options)
|
||||
(assoc opts-map
|
||||
:verbose? true))
|
||||
("--describe") (recur (next options)
|
||||
(assoc opts-map
|
||||
:describe? true))
|
||||
("--stream") (recur (next options)
|
||||
(assoc opts-map
|
||||
:stream? true))
|
||||
("-i") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true))
|
||||
("-I") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in true))
|
||||
("-o") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-out true))
|
||||
("-O") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-out true))
|
||||
("-io") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true
|
||||
:shell-out true))
|
||||
("-iO") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true
|
||||
:edn-out true))
|
||||
("-Io") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in true
|
||||
:shell-out true))
|
||||
("-IO") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in 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))))
|
||||
("--uberjar")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:uberjar (first options))))
|
||||
("-f" "--file")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:file (first options))))
|
||||
("--jar" "-jar")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:jar (first options))))
|
||||
("--repl")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:repl true)))
|
||||
("--socket-repl")
|
||||
(let [options (next options)
|
||||
opt (first options)
|
||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||
opt)
|
||||
options (if opt (next options)
|
||||
options)]
|
||||
(recur options
|
||||
(assoc opts-map
|
||||
:socket-repl (or opt "1666"))))
|
||||
("--nrepl-server")
|
||||
(let [options (next options)
|
||||
opt (first options)
|
||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||
opt)
|
||||
options (if opt (next options)
|
||||
options)]
|
||||
(recur options
|
||||
(assoc opts-map
|
||||
:nrepl (or opt "1667"))))
|
||||
("--eval", "-e")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(update opts-map :expressions (fnil conj []) (first options))))
|
||||
("--main", "-m")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map :main (first options))))
|
||||
(if (some opts-map [:file :jar :socket-repl :expressions :main])
|
||||
(assoc opts-map
|
||||
:command-line-args options)
|
||||
(let [trimmed-opt (str/triml opt)
|
||||
c (.charAt trimmed-opt 0)]
|
||||
(case c
|
||||
(\( \{ \[ \* \@ \#)
|
||||
(-> opts-map
|
||||
(update :expressions (fnil conj []) (first options))
|
||||
(assoc :command-line-args (next options)))
|
||||
(assoc opts-map
|
||||
(if (str/ends-with? opt ".jar")
|
||||
:jar :file) opt
|
||||
:command-line-args (next options)))))))
|
||||
opts-map))]
|
||||
opts))
|
||||
|
||||
(def version (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
||||
|
||||
(defn print-version []
|
||||
(println (str "babashka v" version)))
|
||||
|
||||
(def bb-edn
|
||||
(volatile! nil))
|
||||
|
||||
(defn print-help []
|
||||
(defn command? [x]
|
||||
(case x
|
||||
("clojure"
|
||||
"version"
|
||||
"help"
|
||||
"doc"
|
||||
"tasks"
|
||||
"uberjar"
|
||||
"uberscript"
|
||||
"repl"
|
||||
"socket-repl"
|
||||
"nrepl-server"
|
||||
"describe") true
|
||||
false))
|
||||
|
||||
(defn print-error [& msgs]
|
||||
(binding [*out* *err*]
|
||||
(apply println msgs)))
|
||||
|
||||
(defn print-help [_ctx _command-line-args]
|
||||
(println (str "Babashka v" version))
|
||||
;; (println (str "sci v" (str/trim (slurp (io/resource "SCI_VERSION")))))
|
||||
(println)
|
||||
(println "Options must appear in the order of groups mentioned below.")
|
||||
(println "
|
||||
Help:
|
||||
|
||||
--help, -h or -? Print this help text.
|
||||
--version Print the current version of babashka.
|
||||
--describe Print an EDN map with information about this version of babashka.
|
||||
|
||||
Evaluation:
|
||||
|
||||
-e, --eval <expr> Evaluate an expression.
|
||||
-f, --file <path> Evaluate a file.
|
||||
-cp, --classpath Classpath to use.
|
||||
-m, --main <ns> Call the -main function from namespace with args.
|
||||
--verbose Print debug information and entire stacktrace in case of exception.
|
||||
help, -h or -? Print this help text.
|
||||
version Print the current version of babashka.
|
||||
describe Print an EDN map with information about this version of babashka.
|
||||
doc <var|ns> Print docstring of var or namespace. Requires namespace if necessary.
|
||||
|
||||
REPL:
|
||||
|
||||
--repl Start REPL. Use rlwrap for history.
|
||||
--socket-repl Start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666).
|
||||
--nrepl-server Start nREPL server. Specify port (e.g. 1667) or host and port separated by colon (e.g. 127.0.0.1:1667).
|
||||
Usage: <repl-command> [port/host] [eval-opts]
|
||||
Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666).
|
||||
|
||||
In- and output flags:
|
||||
|
||||
-i Bind *input* to a lazy seq of lines from stdin.
|
||||
-I Bind *input* to a lazy seq of EDN values from stdin.
|
||||
-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 *input* becomes a single value per iteration.
|
||||
|
||||
Uberscript:
|
||||
|
||||
--uberscript <file> Collect preloads, -e, -f and -m and all required namespaces from the classpath into a single file.
|
||||
|
||||
Uberjar:
|
||||
|
||||
--uberjar <jar> Similar to --uberscript but creates jar file.
|
||||
repl Start REPL. Use rlwrap for history. When invoking bb with no args, this is the default command.
|
||||
socket-repl Start socket REPL.
|
||||
nrepl-server Start nREPL server.
|
||||
|
||||
Clojure:
|
||||
|
||||
--clojure [args...] Invokes clojure. Takes same args as the official clojure CLI.
|
||||
clojure [args...] Invokes clojure. Takes same args as the official clojure CLI.
|
||||
|
||||
Packaging:
|
||||
|
||||
uberscript <file> [eval-opts] Collect preloads, -e, -f and -m and all required namespaces from the classpath into a single file.
|
||||
|
||||
uberjar <jar> [eval-opts] Similar to --uberscript but creates jar file.
|
||||
|
||||
Evaluation:
|
||||
|
||||
-e, --eval <expr> Evaluate an expression.
|
||||
-f, --file <path> Evaluate a file.
|
||||
-cp, --classpath Classpath to use.
|
||||
-m, --main <ns|var> Call the -main function from a namespace or call a fully qualified var.
|
||||
--verbose Print debug information and entire stacktrace in case of exception.
|
||||
|
||||
In- and output flags:
|
||||
|
||||
-i Bind *input* to a lazy seq of lines from stdin.
|
||||
-I Bind *input* to a lazy seq of EDN values from stdin.
|
||||
-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 *input* becomes a single value per iteration.
|
||||
|
||||
If the first argument is not any of the above options, then it treated as a file if it exists, or as an expression otherwise.
|
||||
Everything after that is bound to *command-line-args*.
|
||||
|
||||
Use -- to separate script command line args from bb command line args.
|
||||
"))
|
||||
")
|
||||
[nil 0])
|
||||
|
||||
(defn print-doc [ctx command-line-args]
|
||||
(let [arg (first command-line-args)]
|
||||
(if (sci/eval-string* ctx (format "
|
||||
(when (or (resolve '%1$s)
|
||||
(if (simple-symbol? '%1$s)
|
||||
(try (require '%1$s) true
|
||||
(catch Exception e nil))
|
||||
(requiring-resolve '%1$s)))
|
||||
(clojure.repl/doc %1$s)
|
||||
true)" arg))
|
||||
[nil 0]
|
||||
[(print-error "No docstring found for var:" arg) 1]))
|
||||
,)
|
||||
|
||||
(defn print-describe []
|
||||
(println
|
||||
|
|
@ -301,8 +217,6 @@ Use -- to separate script command line args from bb command line args.
|
|||
(str/replace x #"^#!.*" ""))
|
||||
(throw (Exception. (str "File does not exist: " file))))))
|
||||
|
||||
(def reflection-var (sci/new-dynamic-var '*warn-on-reflection* false))
|
||||
|
||||
(defn load-file* [f]
|
||||
(let [f (io/file f)
|
||||
s (slurp f)]
|
||||
|
|
@ -319,7 +233,7 @@ Use -- to separate script command line args from bb command line args.
|
|||
nrepl-opts (assoc nrepl-opts
|
||||
:debug dev?
|
||||
:describe {"versions" {"babashka" version}}
|
||||
:thread-bind [reflection-var])]
|
||||
:thread-bind [core/warn-on-reflection])]
|
||||
(nrepl-server/start-server! ctx nrepl-opts)
|
||||
(binding [*out* *err*]
|
||||
(println "For more info visit: https://book.babashka.org/#_nrepl")))
|
||||
|
|
@ -477,27 +391,156 @@ Use -- to separate script command line args from bb command line args.
|
|||
(defn shell-seq [in]
|
||||
(line-seq (java.io.BufferedReader. in)))
|
||||
|
||||
(defn main
|
||||
[& args]
|
||||
(handle-pipe!)
|
||||
(handle-sigint!)
|
||||
(defn parse-opts [options]
|
||||
(let [opt (first options)]
|
||||
(cond (and (command? opt)
|
||||
(not (fs/regular-file? opt)))
|
||||
(recur (cons (str "--" opt) (next options)))
|
||||
:else
|
||||
(let [opts (loop [options options
|
||||
opts-map {}]
|
||||
(if options
|
||||
(let [opt (first options)]
|
||||
(case opt
|
||||
("--") (assoc opts-map :command-line-args (next options))
|
||||
("--clojure") (assoc opts-map :clojure true
|
||||
:command-line-args (rest options))
|
||||
("--version") {:version true}
|
||||
("--help" "-h" "-?" "help")
|
||||
{:help true
|
||||
:command-line-args (rest options)}
|
||||
("--doc")
|
||||
{:doc true
|
||||
:command-line-args (rest options)}
|
||||
("--verbose") (recur (next options)
|
||||
(assoc opts-map
|
||||
:verbose? true))
|
||||
("--describe") (recur (next options)
|
||||
(assoc opts-map
|
||||
:describe? true))
|
||||
("--stream") (recur (next options)
|
||||
(assoc opts-map
|
||||
:stream? true))
|
||||
("-i") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true))
|
||||
("-I") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in true))
|
||||
("-o") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-out true))
|
||||
("-O") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-out true))
|
||||
("-io") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true
|
||||
:shell-out true))
|
||||
("-iO") (recur (next options)
|
||||
(assoc opts-map
|
||||
:shell-in true
|
||||
:edn-out true))
|
||||
("-Io") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in true
|
||||
:shell-out true))
|
||||
("-IO") (recur (next options)
|
||||
(assoc opts-map
|
||||
:edn-in 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))))
|
||||
("--uberjar")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:uberjar (first options))))
|
||||
("-f" "--file")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:file (first options))))
|
||||
("--jar" "-jar")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:jar (first options))))
|
||||
("--repl")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map
|
||||
:repl true)))
|
||||
("--socket-repl")
|
||||
(let [options (next options)
|
||||
opt (first options)
|
||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||
opt)
|
||||
options (if opt (next options)
|
||||
options)]
|
||||
(recur options
|
||||
(assoc opts-map
|
||||
:socket-repl (or opt "1666"))))
|
||||
("--nrepl-server")
|
||||
(let [options (next options)
|
||||
opt (first options)
|
||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||
opt)
|
||||
options (if opt (next options)
|
||||
options)]
|
||||
(recur options
|
||||
(assoc opts-map
|
||||
:nrepl (or opt "1667"))))
|
||||
("--eval", "-e")
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(update opts-map :expressions (fnil conj []) (first options))))
|
||||
("--main", "-m",)
|
||||
(let [options (next options)]
|
||||
(recur (next options)
|
||||
(assoc opts-map :main (first options))))
|
||||
;; fallback
|
||||
(if (some opts-map [:file :jar :socket-repl :expressions :main])
|
||||
(assoc opts-map
|
||||
:command-line-args options)
|
||||
(let [trimmed-opt (str/triml opt)
|
||||
c (.charAt trimmed-opt 0)]
|
||||
(case c
|
||||
(\( \{ \[ \* \@ \#)
|
||||
(-> opts-map
|
||||
(update :expressions (fnil conj []) (first options))
|
||||
(assoc :command-line-args (next options)))
|
||||
(assoc opts-map
|
||||
(if (str/ends-with? opt ".jar")
|
||||
:jar :file) opt
|
||||
:command-line-args (next options)))))))
|
||||
opts-map))]
|
||||
opts))))
|
||||
|
||||
(def env (atom {}))
|
||||
|
||||
(defn exec [opts]
|
||||
(binding [*unrestricted* true]
|
||||
(sci/binding [reflection-var false
|
||||
(sci/binding [core/warn-on-reflection @core/warn-on-reflection
|
||||
core/data-readers @core/data-readers
|
||||
sci/ns @sci/ns]
|
||||
(let [{version-opt :version
|
||||
:keys [:shell-in :edn-in :shell-out :edn-out
|
||||
:help? :file :command-line-args
|
||||
:help :file :command-line-args
|
||||
:expressions :stream?
|
||||
:repl :socket-repl :nrepl
|
||||
:verbose? :classpath
|
||||
:main :uberscript :describe?
|
||||
:jar :uberjar :clojure] :as opts}
|
||||
(parse-opts args)
|
||||
_ (when clojure
|
||||
(if-let [proc (deps/clojure (:opts opts))]
|
||||
(-> @proc :exit (System/exit))
|
||||
(System/exit 0)))
|
||||
:jar :uberjar :clojure
|
||||
:doc]}
|
||||
opts
|
||||
_ (when verbose? (vreset! common/verbose? true))
|
||||
_ (do ;; set properties
|
||||
(when main (System/setProperty "babashka.main" main))
|
||||
|
|
@ -516,7 +559,6 @@ Use -- to separate script command line args from bb command line args.
|
|||
:else
|
||||
(edn/read {:readers edn-readers} *in*))))))
|
||||
uberscript-sources (atom ())
|
||||
env (atom {})
|
||||
classpath (or classpath
|
||||
(System/getenv "BABASHKA_CLASSPATH"))
|
||||
_ (when classpath
|
||||
|
|
@ -546,15 +588,11 @@ Use -- to separate script command line args from bb command line args.
|
|||
["META-INF/MANIFEST.MF"] {:url? true})]
|
||||
(cp/main-ns res))
|
||||
main)
|
||||
|
||||
;; TODO: pull more of these values to compile time
|
||||
opts {:aliases aliases
|
||||
:namespaces (-> namespaces
|
||||
(assoc 'clojure.core
|
||||
(assoc core-extras
|
||||
'*command-line-args*
|
||||
(sci/new-dynamic-var '*command-line-args* command-line-args)
|
||||
'*warn-on-reflection* reflection-var
|
||||
'load-file load-file*))
|
||||
(assoc-in ['clojure.java.io 'resource]
|
||||
(fn [path]
|
||||
|
|
@ -579,8 +617,15 @@ Use -- to separate script command line args from bb command line args.
|
|||
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
|
||||
[expressions exit-code]
|
||||
(cond expressions [expressions nil]
|
||||
main [[(format "(ns user (:require [%1$s])) (apply %1$s/-main *command-line-args*)"
|
||||
main)] nil]
|
||||
main
|
||||
(let [sym (symbol main)
|
||||
ns? (namespace sym)
|
||||
ns (or ns? sym)
|
||||
var-name (if ns?
|
||||
(name sym)
|
||||
"-main")]
|
||||
[[(format "(ns user (:require [%1$s])) (apply %1$s/%2$s *command-line-args*)"
|
||||
ns var-name)] nil])
|
||||
file (try [[(read-file file)] nil]
|
||||
(catch Exception e
|
||||
(error-handler e {:expression expressions
|
||||
|
|
@ -610,8 +655,8 @@ Use -- to separate script command line args from bb command line args.
|
|||
(second
|
||||
(cond version-opt
|
||||
[(print-version) 0]
|
||||
help?
|
||||
[(print-help) 0]
|
||||
help (print-help sci-ctx command-line-args)
|
||||
doc (print-doc sci-ctx command-line-args)
|
||||
describe?
|
||||
[(print-describe) 0]
|
||||
repl [(repl/start-repl! sci-ctx) 0]
|
||||
|
|
@ -626,7 +671,8 @@ Use -- to separate script command line args from bb command line args.
|
|||
[nil 0] ;; done streaming
|
||||
(let [res [(let [res
|
||||
(sci/binding [sci/file (or @sci/file "<expr>")
|
||||
input-var in]
|
||||
input-var in
|
||||
core/command-line-args command-line-args]
|
||||
(sci/eval-string* sci-ctx expression))]
|
||||
(when (some? res)
|
||||
(if-let [pr-f (cond shell-out println
|
||||
|
|
@ -645,6 +691,9 @@ Use -- to separate script command line args from bb command line args.
|
|||
:verbose? verbose?
|
||||
:preloads preloads
|
||||
:loader (:loader @cp/cp-state)}))))
|
||||
clojure [nil (if-let [proc (deps/clojure command-line-args)]
|
||||
(-> @proc :exit)
|
||||
0)]
|
||||
uberscript [nil 0]
|
||||
:else [(repl/start-repl! sci-ctx) 0]))
|
||||
1)]
|
||||
|
|
@ -664,8 +713,21 @@ Use -- to separate script command line args from bb command line args.
|
|||
:verbose verbose?}))
|
||||
exit-code))))
|
||||
|
||||
(defn main [& args]
|
||||
(let [bb-edn-file (or (System/getenv "BABASHKA_EDN")
|
||||
"bb.edn")]
|
||||
(when (fs/exists? bb-edn-file)
|
||||
(let [edn (edn/read-string (slurp bb-edn-file))]
|
||||
(vreset! bb-edn edn)))
|
||||
;; we mutate the atom from tests as well, so despite the above it can contain a bb.edn
|
||||
(when-let [bb-edn @bb-edn] (deps/add-deps bb-edn)))
|
||||
(let [opts (parse-opts args)]
|
||||
(exec opts)))
|
||||
|
||||
(defn -main
|
||||
[& args]
|
||||
(handle-pipe!)
|
||||
(handle-sigint!)
|
||||
(if-let [dev-opts (System/getenv "BABASHKA_DEV")]
|
||||
(let [{:keys [:n]} (if (= "true" dev-opts) {:n 1}
|
||||
(edn/read-string dev-opts))
|
||||
|
|
|
|||
10
test-resources/bb-edn/user.clj
Normal file
10
test-resources/bb-edn/user.clj
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
(ns user
|
||||
(:require [babashka.process :as p]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn bash [& args]
|
||||
;; (prn :cmd *command-line-args*)
|
||||
(-> (p/process ["bash" "-c" (str/join " " args)]
|
||||
{:inherit true})
|
||||
p/check)
|
||||
nil)
|
||||
11
test-resources/task_scripts/tasks.clj
Normal file
11
test-resources/task_scripts/tasks.clj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(ns tasks
|
||||
"This is task ns docstring.")
|
||||
|
||||
(defn -main
|
||||
"Main docstring"
|
||||
[& args]
|
||||
args)
|
||||
|
||||
(defn foo
|
||||
"Foo docstring"
|
||||
[])
|
||||
38
test/babashka/bb_edn_test.clj
Normal file
38
test/babashka/bb_edn_test.clj
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
(ns babashka.bb-edn-test
|
||||
(:require
|
||||
[babashka.fs :as fs]
|
||||
[babashka.test-utils :as test-utils]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.string :as str]
|
||||
[clojure.test :as test :refer [deftest is]]))
|
||||
|
||||
(defn bb [& args]
|
||||
(edn/read-string
|
||||
{:readers *data-readers*
|
||||
:eof nil}
|
||||
(apply test-utils/bb nil (map str args))))
|
||||
|
||||
(defmacro with-config [cfg & body]
|
||||
`(let [temp-dir# (fs/create-temp-dir)
|
||||
bb-edn-file# (fs/file temp-dir# "bb.edn")]
|
||||
(binding [*print-meta* true]
|
||||
(spit bb-edn-file# ~cfg))
|
||||
(binding [test-utils/*bb-edn-path* (str bb-edn-file#)]
|
||||
~@body)))
|
||||
|
||||
(deftest doc-test
|
||||
(with-config {:paths ["test-resources/task_scripts"]}
|
||||
(is (str/includes? (apply test-utils/bb nil
|
||||
(map str ["doc" "tasks"]))
|
||||
"This is task ns docstring."))
|
||||
(is (str/includes? (apply test-utils/bb nil
|
||||
(map str ["doc" "tasks/foo"]))
|
||||
"Foo docstring"))
|
||||
(is (str/includes? (apply test-utils/bb nil
|
||||
(map str ["doc" "tasks/-main"]))
|
||||
"Main docstring"))))
|
||||
|
||||
(deftest deps-test
|
||||
(with-config '{:deps {medley/medley {:mvn/version "1.3.0"}}}
|
||||
(is (= '{1 {:id 1}, 2 {:id 2}}
|
||||
(bb "-e" "(require 'medley.core)" "-e" "(medley.core/index-by :id [{:id 1} {:id 2}])")))))
|
||||
|
|
@ -195,7 +195,7 @@
|
|||
:features #{:bb}})
|
||||
nrepl-opts)]
|
||||
(reset! server-state server))
|
||||
(let [pb (ProcessBuilder. ["./bb" "--nrepl-server" "0.0.0.0:1668"])
|
||||
(let [pb (ProcessBuilder. ["./bb" "nrepl-server" "0.0.0.0:1668"])
|
||||
_ (.redirectError pb ProcessBuilder$Redirect/INHERIT)
|
||||
;; _ (.redirectOutput pb ProcessBuilder$Redirect/INHERIT)
|
||||
;; env (.environment pb)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
(vreset! common/ctx ctx)
|
||||
(start-repl! "0.0.0.0:1666" ctx))
|
||||
(do (vreset! server-process
|
||||
(p/process ["./bb" "--socket-repl" "localhost:1666"]))
|
||||
(p/process ["./bb" "socket-repl" "localhost:1666"]))
|
||||
(w/wait-for-port "localhost" 1666)))
|
||||
(Thread/sleep 50)
|
||||
(is (socket-command "(+ 1 2 3)" "user=> 6"))
|
||||
|
|
|
|||
|
|
@ -7,21 +7,10 @@
|
|||
[clojure.java.io :as io]
|
||||
[clojure.java.shell :refer [sh]]
|
||||
[clojure.string :as str]
|
||||
[clojure.test :as test :refer [deftest is testing *report-counters*]]
|
||||
[clojure.test :as test :refer [deftest is testing]]
|
||||
[flatland.ordered.map :refer [ordered-map]]
|
||||
[sci.core :as sci]))
|
||||
|
||||
(defmethod clojure.test/report :begin-test-var [m]
|
||||
(println "===" (-> m :var meta :name))
|
||||
(println))
|
||||
|
||||
(defmethod clojure.test/report :end-test-var [_m]
|
||||
(let [{:keys [:fail :error]} @*report-counters*]
|
||||
(when (and (= "true" (System/getenv "BABASHKA_FAIL_FAST"))
|
||||
(or (pos? fail) (pos? error)))
|
||||
(println "=== Failing fast")
|
||||
(System/exit 1))))
|
||||
|
||||
(defn bb [input & args]
|
||||
(edn/read-string
|
||||
{:readers *data-readers*
|
||||
|
|
|
|||
|
|
@ -2,14 +2,33 @@
|
|||
(:require
|
||||
[babashka.impl.classpath :as cp]
|
||||
[babashka.main :as main]
|
||||
[me.raynes.conch :refer [let-programs] :as sh]
|
||||
[babashka.process :as p]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.test :as test :refer [*report-counters*]]
|
||||
[sci.core :as sci]
|
||||
[sci.impl.vars :as vars]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(def ^:dynamic *bb-edn-path* nil)
|
||||
|
||||
(defmethod clojure.test/report :begin-test-var [m]
|
||||
(println "===" (-> m :var meta :name))
|
||||
(println))
|
||||
|
||||
(defmethod clojure.test/report :end-test-var [_m]
|
||||
(let [{:keys [:fail :error]} @*report-counters*]
|
||||
(when (and (= "true" (System/getenv "BABASHKA_FAIL_FAST"))
|
||||
(or (pos? fail) (pos? error)))
|
||||
(println "=== Failing fast")
|
||||
(System/exit 1))))
|
||||
|
||||
(defn bb-jvm [input-or-opts & args]
|
||||
(reset! cp/cp-state nil)
|
||||
(reset! main/env {})
|
||||
(if-let [path *bb-edn-path*]
|
||||
(vreset! main/bb-edn (edn/read-string (slurp path)))
|
||||
(vreset! main/bb-edn nil))
|
||||
(let [os (java.io.StringWriter.)
|
||||
es (if-let [err (:err input-or-opts)]
|
||||
err (java.io.StringWriter.))
|
||||
|
|
@ -30,26 +49,33 @@
|
|||
(if (string? input-or-opts)
|
||||
(with-in-str input-or-opts (apply main/main args))
|
||||
(apply main/main args)))]
|
||||
;; (prn :err (str es))
|
||||
(if (zero? res)
|
||||
(str os)
|
||||
(throw (ex-info (str es)
|
||||
{:stdout (str os)
|
||||
:stderr (str es)})))))
|
||||
(do
|
||||
(println (str os))
|
||||
(throw (ex-info (str es)
|
||||
{:stdout (str os)
|
||||
:stderr (str es)}))))))
|
||||
(finally
|
||||
(when (string? input-or-opts) (vars/bindRoot sci/in *in*))
|
||||
(vars/bindRoot sci/out *out*)
|
||||
(vars/bindRoot sci/err *err*)))))
|
||||
|
||||
(defn bb-native [input & args]
|
||||
(let-programs [bb "./bb"]
|
||||
(try (if input
|
||||
(apply bb (conj (vec args)
|
||||
{:in input}))
|
||||
(apply bb args))
|
||||
(catch Exception e
|
||||
(let [d (ex-data e)
|
||||
err-msg (or (:stderr (ex-data e)) "")]
|
||||
(throw (ex-info err-msg d)))))))
|
||||
(let [res (p/process (into ["./bb"] args)
|
||||
(cond-> {:in input
|
||||
:out :string
|
||||
:err :string}
|
||||
*bb-edn-path*
|
||||
(assoc
|
||||
:env (assoc (into {} (System/getenv))
|
||||
"BABASHKA_EDN" *bb-edn-path*))))
|
||||
res (deref res)
|
||||
exit (:exit res)
|
||||
error? (pos? exit)]
|
||||
(if error? (throw (ex-info (or (:err res) "") {}))
|
||||
(:out res))))
|
||||
|
||||
(def bb
|
||||
(case (System/getenv "BABASHKA_TEST_ENV")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
(ns babashka.uberjar-test
|
||||
(:require
|
||||
[babashka.test-utils :as tu]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.string :as str]
|
||||
[clojure.test :as t :refer [deftest is testing]]))
|
||||
|
||||
|
|
@ -10,7 +9,7 @@
|
|||
path (.getPath tmp-file)]
|
||||
(.deleteOnExit tmp-file)
|
||||
(testing "uberjar"
|
||||
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "-m" "my.main-main" "--uberjar" path)
|
||||
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src" "-m" "my.main-main")
|
||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||
(tu/bb nil "--jar" path "1" "2" "3" "4")))
|
||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||
|
|
@ -25,5 +24,5 @@
|
|||
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
||||
path (.getPath tmp-file)]
|
||||
(.deleteOnExit tmp-file)
|
||||
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "--uberjar" path)
|
||||
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src")
|
||||
(is (str/includes? (tu/bb "(+ 1 2 3)" path) "6")))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue