[#780] Fix uberjar CLI parsing and throw when no classpath is provided

This commit is contained in:
Michiel Borkent 2021-04-22 11:56:13 +02:00 committed by GitHub
parent 3dfc15f5a4
commit 15e71b0807
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 195 additions and 155 deletions

@ -1 +1 @@
Subproject commit e74b8ac05c64efb815153fbfdd2d31e3cad098cb Subproject commit c419b8c82041855d55593c5b561fc7cea8234712

View file

@ -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.

View file

@ -415,24 +415,38 @@ 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)]
(case f
("--classpath" "-cp") [(nnext options) (second options)]
[options nil])))
(defn parse-opts
([options] (parse-opts options nil))
([options opts]
(let [[options classpath] (parse-classpath options)
opts (if classpath (assoc opts :classpath classpath)
opts)
opt (first options)
tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))] tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))]
(when opt (when opt
(cond (contains? tasks opt) (cond (contains? tasks opt)
{:run opt {:run opt
:classpath classpath
:command-line-args (rest options)} :command-line-args (rest options)}
(fs/regular-file? opt) (fs/regular-file? opt)
(if (str/ends-with? opt ".jar") (if (str/ends-with? opt ".jar")
{:jar opt {:classpath classpath
:jar opt
:command-line-args (next options)} :command-line-args (next options)}
{:file opt {:classpath classpath
:file opt
:command-line-args (next options)}) :command-line-args (next options)})
(command? opt) (command? opt)
(recur (cons (str "--" opt) (next options))) (recur (cons (str "--" opt) (next options)) opts)
:else :else
(let [opts (loop [options options (let [opts (loop [options options
opts-map {}] opts-map opts]
(if options (if options
(let [opt (first options)] (let [opt (first options)]
(case opt (case opt
@ -546,7 +560,8 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
(assoc opts-map :list-tasks true (assoc opts-map :list-tasks true
:command-line-args (next options)) :command-line-args (next options))
;; fallback ;; fallback
(if (some opts-map [:file :jar :socket-repl :expressions :main :run]) (if (and opts-map
(some opts-map [:file :jar :socket-repl :expressions :main :run]))
(assoc opts-map (assoc opts-map
:command-line-args options) :command-line-args options)
(let [trimmed-opt (str/triml opt) (let [trimmed-opt (str/triml opt)
@ -562,7 +577,7 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
:file) opt :file) opt
:command-line-args (next options))))))) :command-line-args (next options)))))))
opts-map))] opts-map))]
opts))))) 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
(if-let [cp (cp/get-classpath)]
(uberjar/run {:dest uberjar (uberjar/run {:dest uberjar
:jar :uber :jar :uber
:classpath (cp/get-classpath) :classpath cp
:main-class main :main-class main
:verbose verbose?})) :verbose verbose?})
(throw (Exception. "The uberjar task needs a classpath."))))
exit-code)))) exit-code))))
(defn main [& args] (defn main [& args]

View file

@ -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)")))

View file

@ -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"]}