[#780] Fix uberjar CLI parsing and throw when no classpath is provided
This commit is contained in:
parent
3dfc15f5a4
commit
15e71b0807
5 changed files with 195 additions and 155 deletions
2
depstar
2
depstar
|
|
@ -1 +1 @@
|
||||||
Subproject commit e74b8ac05c64efb815153fbfdd2d31e3cad098cb
|
Subproject commit c419b8c82041855d55593c5b561fc7cea8234712
|
||||||
18
doc/dev.md
18
doc/dev.md
|
|
@ -81,6 +81,24 @@ To progress work on sqlite and mySQL, I need a working Clojure example. If you
|
||||||
want to contribute, consider making a an example Clojure GraalVM CLI that puts
|
want to contribute, consider making a an example Clojure GraalVM CLI that puts
|
||||||
something in a sqlite / mysql DB and reads something from it.
|
something in a sqlite / mysql DB and reads something from it.
|
||||||
|
|
||||||
|
## ADR
|
||||||
|
|
||||||
|
Some decisions:
|
||||||
|
|
||||||
|
### bb.edn
|
||||||
|
|
||||||
|
- We chose the name `bb.edn` (rather than `babashka.edn`) for the configuration
|
||||||
|
file based on this
|
||||||
|
[poll](https://twitter.com/borkdude/status/1374720217608302595). The name `bb`
|
||||||
|
combined with `.edn` is not likely to cause conflicts with other tools.
|
||||||
|
- We did not choose to put the babashka configuration in `deps.edn` to keep bb config isolated (and more flexible) and also support it in projects that do not use `deps.edn`
|
||||||
|
|
||||||
|
### .babashka
|
||||||
|
|
||||||
|
- Rather than naming the home config dir `~/.bb` we chose `~/.babashka` to
|
||||||
|
prevent conflicts with other global tools. We might introduce a project local
|
||||||
|
`~/.babashka` directory for storing caches or whatnot too.
|
||||||
|
|
||||||
## Binary size
|
## Binary size
|
||||||
|
|
||||||
Keep notes here about how adding libraries and classes to Babashka affects the binary size.
|
Keep notes here about how adding libraries and classes to Babashka affects the binary size.
|
||||||
|
|
|
||||||
|
|
@ -415,154 +415,169 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
|
||||||
(assoc opts-map :run fst :command-line-args (next args))))
|
(assoc opts-map :run fst :command-line-args (next args))))
|
||||||
opts-map)))
|
opts-map)))
|
||||||
|
|
||||||
(defn parse-opts [options]
|
(defn parse-classpath [options]
|
||||||
(let [opt (first options)
|
(when-let [f (first options)]
|
||||||
tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))]
|
(case f
|
||||||
(when opt
|
("--classpath" "-cp") [(nnext options) (second options)]
|
||||||
(cond (contains? tasks opt)
|
[options nil])))
|
||||||
{:run opt
|
|
||||||
:command-line-args (rest options)}
|
(defn parse-opts
|
||||||
(fs/regular-file? opt)
|
([options] (parse-opts options nil))
|
||||||
(if (str/ends-with? opt ".jar")
|
([options opts]
|
||||||
{:jar opt
|
(let [[options classpath] (parse-classpath options)
|
||||||
:command-line-args (next options)}
|
opts (if classpath (assoc opts :classpath classpath)
|
||||||
{:file opt
|
opts)
|
||||||
:command-line-args (next options)})
|
opt (first options)
|
||||||
(command? opt)
|
tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))]
|
||||||
(recur (cons (str "--" opt) (next options)))
|
(when opt
|
||||||
:else
|
(cond (contains? tasks opt)
|
||||||
(let [opts (loop [options options
|
{:run opt
|
||||||
opts-map {}]
|
:classpath classpath
|
||||||
(if options
|
:command-line-args (rest options)}
|
||||||
(let [opt (first options)]
|
(fs/regular-file? opt)
|
||||||
(case opt
|
(if (str/ends-with? opt ".jar")
|
||||||
("--") (assoc opts-map :command-line-args (next options))
|
{:classpath classpath
|
||||||
("--clojure") (assoc opts-map :clojure true
|
:jar opt
|
||||||
:command-line-args (rest options))
|
:command-line-args (next options)}
|
||||||
("--version") {:version true}
|
{:classpath classpath
|
||||||
("--help" "-h" "-?" "help")
|
:file opt
|
||||||
{:help true
|
:command-line-args (next options)})
|
||||||
:command-line-args (rest options)}
|
(command? opt)
|
||||||
("--doc")
|
(recur (cons (str "--" opt) (next options)) opts)
|
||||||
{:doc true
|
:else
|
||||||
:command-line-args (rest options)}
|
(let [opts (loop [options options
|
||||||
("--verbose") (recur (next options)
|
opts-map opts]
|
||||||
(assoc opts-map
|
(if options
|
||||||
:verbose? true))
|
(let [opt (first options)]
|
||||||
("--describe") (recur (next 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
|
(assoc opts-map
|
||||||
:describe? true))
|
:verbose? true))
|
||||||
("--stream") (recur (next options)
|
("--describe") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:stream? true))
|
:describe? true))
|
||||||
("-i") (recur (next options)
|
("--stream") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:shell-in true))
|
:stream? true))
|
||||||
("-I") (recur (next options)
|
("-i") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:edn-in true))
|
:shell-in true))
|
||||||
("-o") (recur (next options)
|
("-I") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:shell-out true))
|
:edn-in true))
|
||||||
("-O") (recur (next options)
|
("-o") (recur (next options)
|
||||||
(assoc opts-map
|
|
||||||
:edn-out true))
|
|
||||||
("-io") (recur (next options)
|
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:shell-in true
|
|
||||||
:shell-out true))
|
:shell-out true))
|
||||||
("-iO") (recur (next options)
|
("-O") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:shell-in true
|
|
||||||
:edn-out true))
|
:edn-out true))
|
||||||
("-Io") (recur (next options)
|
("-io") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:edn-in true
|
:shell-in true
|
||||||
:shell-out true))
|
:shell-out true))
|
||||||
("-IO") (recur (next options)
|
("-iO") (recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
:edn-in true
|
:shell-in true
|
||||||
:edn-out true))
|
:edn-out true))
|
||||||
("--classpath", "-cp")
|
("-Io") (recur (next options)
|
||||||
(let [options (next options)]
|
(assoc opts-map
|
||||||
(recur (next options)
|
:edn-in true
|
||||||
(assoc opts-map :classpath (first options))))
|
:shell-out true))
|
||||||
("--uberscript")
|
("-IO") (recur (next options)
|
||||||
(let [options (next options)]
|
(assoc opts-map
|
||||||
(recur (next options)
|
:edn-in true
|
||||||
(assoc opts-map
|
:edn-out true))
|
||||||
:uberscript (first options))))
|
("--classpath", "-cp")
|
||||||
("--uberjar")
|
(let [options (next options)]
|
||||||
(let [options (next options)]
|
(recur (next options)
|
||||||
(recur (next options)
|
(assoc opts-map :classpath (first options))))
|
||||||
(assoc opts-map
|
("--uberscript")
|
||||||
:uberjar (first options))))
|
(let [options (next options)]
|
||||||
("-f" "--file")
|
(recur (next options)
|
||||||
(let [options (next options)]
|
(assoc opts-map
|
||||||
(recur (next options)
|
:uberscript (first options))))
|
||||||
(assoc opts-map
|
("--uberjar")
|
||||||
:file (first options))))
|
(let [options (next options)]
|
||||||
("--jar" "-jar")
|
(recur (next options)
|
||||||
(let [options (next options)]
|
(assoc opts-map
|
||||||
(recur (next options)
|
:uberjar (first options))))
|
||||||
(assoc opts-map
|
("-f" "--file")
|
||||||
:jar (first options))))
|
(let [options (next options)]
|
||||||
("--repl")
|
(recur (next options)
|
||||||
(let [options (next options)]
|
(assoc opts-map
|
||||||
(recur (next options)
|
:file (first options))))
|
||||||
(assoc opts-map
|
("--jar" "-jar")
|
||||||
:repl true)))
|
(let [options (next options)]
|
||||||
("--socket-repl")
|
(recur (next options)
|
||||||
(let [options (next options)
|
(assoc opts-map
|
||||||
opt (first options)
|
:jar (first options))))
|
||||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
("--repl")
|
||||||
opt)
|
(let [options (next options)]
|
||||||
options (if opt (next options)
|
(recur (next options)
|
||||||
options)]
|
(assoc opts-map
|
||||||
(recur options
|
:repl true)))
|
||||||
(assoc opts-map
|
("--socket-repl")
|
||||||
:socket-repl (or opt "1666"))))
|
(let [options (next options)
|
||||||
("--nrepl-server")
|
opt (first options)
|
||||||
(let [options (next options)
|
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||||
opt (first options)
|
opt)
|
||||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
options (if opt (next options)
|
||||||
opt)
|
options)]
|
||||||
options (if opt (next options)
|
(recur options
|
||||||
options)]
|
(assoc opts-map
|
||||||
(recur options
|
:socket-repl (or opt "1666"))))
|
||||||
(assoc opts-map
|
("--nrepl-server")
|
||||||
:nrepl (or opt "1667"))))
|
(let [options (next options)
|
||||||
("--eval", "-e")
|
opt (first options)
|
||||||
(let [options (next options)]
|
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||||
(recur (next options)
|
opt)
|
||||||
(update opts-map :expressions (fnil conj []) (first options))))
|
options (if opt (next options)
|
||||||
("--main", "-m",)
|
options)]
|
||||||
(let [options (next options)]
|
(recur options
|
||||||
(recur (next options)
|
(assoc opts-map
|
||||||
(assoc opts-map :main (first options))))
|
:nrepl (or opt "1667"))))
|
||||||
("--run")
|
("--eval", "-e")
|
||||||
(parse-run-opts opts-map (next options))
|
(let [options (next options)]
|
||||||
("--tasks")
|
(recur (next options)
|
||||||
(assoc opts-map :list-tasks true
|
(update opts-map :expressions (fnil conj []) (first options))))
|
||||||
:command-line-args (next options))
|
("--main", "-m",)
|
||||||
;; fallback
|
(let [options (next options)]
|
||||||
(if (some opts-map [:file :jar :socket-repl :expressions :main :run])
|
(recur (next options)
|
||||||
(assoc opts-map
|
(assoc opts-map :main (first options))))
|
||||||
:command-line-args options)
|
("--run")
|
||||||
(let [trimmed-opt (str/triml opt)
|
(parse-run-opts opts-map (next options))
|
||||||
c (.charAt trimmed-opt 0)]
|
("--tasks")
|
||||||
(case c
|
(assoc opts-map :list-tasks true
|
||||||
(\( \{ \[ \* \@ \#)
|
:command-line-args (next options))
|
||||||
(-> opts-map
|
;; fallback
|
||||||
(update :expressions (fnil conj []) (first options))
|
(if (and opts-map
|
||||||
(assoc :command-line-args (next options)))
|
(some opts-map [:file :jar :socket-repl :expressions :main :run]))
|
||||||
(assoc opts-map
|
(assoc opts-map
|
||||||
(if (str/ends-with? opt ".jar")
|
:command-line-args options)
|
||||||
:jar
|
(let [trimmed-opt (str/triml opt)
|
||||||
:file) opt
|
c (.charAt trimmed-opt 0)]
|
||||||
:command-line-args (next options)))))))
|
(case c
|
||||||
opts-map))]
|
(\( \{ \[ \* \@ \#)
|
||||||
opts)))))
|
(-> 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 {}))
|
(def env (atom {}))
|
||||||
|
|
||||||
|
|
@ -750,11 +765,13 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
|
||||||
(spit uberscript-out preloads :append true)
|
(spit uberscript-out preloads :append true)
|
||||||
(spit uberscript-out expression :append true)))
|
(spit uberscript-out expression :append true)))
|
||||||
(when uberjar
|
(when uberjar
|
||||||
(uberjar/run {:dest uberjar
|
(if-let [cp (cp/get-classpath)]
|
||||||
:jar :uber
|
(uberjar/run {:dest uberjar
|
||||||
:classpath (cp/get-classpath)
|
:jar :uber
|
||||||
:main-class main
|
:classpath cp
|
||||||
:verbose verbose?}))
|
:main-class main
|
||||||
|
:verbose verbose?})
|
||||||
|
(throw (Exception. "The uberjar task needs a classpath."))))
|
||||||
exit-code))))
|
exit-code))))
|
||||||
|
|
||||||
(defn main [& args]
|
(defn main [& args]
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,23 @@
|
||||||
(apply test-utils/bb (when (some? input) (str input)) (map str args))))
|
(apply test-utils/bb (when (some? input) (str input)) (map str args))))
|
||||||
|
|
||||||
(deftest parse-opts-test
|
(deftest parse-opts-test
|
||||||
(is (= {:nrepl "1667"}
|
(is (= "1667"
|
||||||
(main/parse-opts ["--nrepl-server"])))
|
(:nrepl (main/parse-opts ["--nrepl-server"]))))
|
||||||
(is (= {:socket-repl "1666"}
|
(is (= "1666"
|
||||||
(main/parse-opts ["--socket-repl"])))
|
(:socket-repl (main/parse-opts ["--socket-repl"]))))
|
||||||
(is (= {:nrepl "1667", :classpath "src"}
|
(is (= {:nrepl "1667", :classpath "src"}
|
||||||
(main/parse-opts ["--nrepl-server" "-cp" "src"])))
|
(main/parse-opts ["--nrepl-server" "-cp" "src"])))
|
||||||
|
(is (= {:nrepl "1667", :classpath "src"}
|
||||||
|
(main/parse-opts ["-cp" "src" "nrepl-server"])))
|
||||||
(is (= {:socket-repl "1666", :expressions ["123"]}
|
(is (= {:socket-repl "1666", :expressions ["123"]}
|
||||||
(main/parse-opts ["--socket-repl" "-e" "123"])))
|
(main/parse-opts ["--socket-repl" "-e" "123"])))
|
||||||
(is (= {:socket-repl "1666", :expressions ["123"]}
|
(is (= {:socket-repl "1666", :expressions ["123"]}
|
||||||
(main/parse-opts ["--socket-repl" "1666" "-e" "123"])))
|
(main/parse-opts ["--socket-repl" "1666" "-e" "123"])))
|
||||||
(is (= {:nrepl "1666", :expressions ["123"]}
|
(is (= {:nrepl "1666", :expressions ["123"]}
|
||||||
(main/parse-opts ["--nrepl-server" "1666" "-e" "123"])))
|
(main/parse-opts ["--nrepl-server" "1666" "-e" "123"])))
|
||||||
|
(is (= {:classpath "src"
|
||||||
|
:uberjar "foo.jar"}
|
||||||
|
(main/parse-opts ["--classpath" "src" "uberjar" "foo.jar"])))
|
||||||
(is (= 123 (bb nil "(println 123)")))
|
(is (= 123 (bb nil "(println 123)")))
|
||||||
(is (= 123 (bb nil "-e" "(println 123)")))
|
(is (= 123 (bb nil "-e" "(println 123)")))
|
||||||
(is (= 123 (bb nil "--eval" "(println 123)")))
|
(is (= 123 (bb nil "--eval" "(println 123)")))
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
||||||
path (.getPath tmp-file)]
|
path (.getPath tmp-file)]
|
||||||
(.deleteOnExit tmp-file)
|
(.deleteOnExit tmp-file)
|
||||||
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src" "-m" "my.main-main")
|
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "uberjar" path "-m" "my.main-main")
|
||||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
(tu/bb nil "--jar" path "1" "2" "3" "4")))
|
(tu/bb nil "--jar" path "1" "2" "3" "4")))
|
||||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
||||||
path (.getPath tmp-file)]
|
path (.getPath tmp-file)]
|
||||||
(.deleteOnExit tmp-file)
|
(.deleteOnExit tmp-file)
|
||||||
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src")
|
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "uberjar" path)
|
||||||
(is (str/includes? (tu/bb "(+ 1 2 3)" path) "6"))))
|
(is (str/includes? (tu/bb "(+ 1 2 3)" path) "6"))))
|
||||||
(testing "use bb.edn classpath when no other --classpath"
|
(testing "use bb.edn classpath when no other --classpath"
|
||||||
(tu/with-config {:paths ["test-resources/babashka/uberjar/src"]}
|
(tu/with-config {:paths ["test-resources/babashka/uberjar/src"]}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue