diff --git a/depstar b/depstar index e74b8ac0..c419b8c8 160000 --- a/depstar +++ b/depstar @@ -1 +1 @@ -Subproject commit e74b8ac05c64efb815153fbfdd2d31e3cad098cb +Subproject commit c419b8c82041855d55593c5b561fc7cea8234712 diff --git a/doc/dev.md b/doc/dev.md index 7c1121bd..da47671c 100644 --- a/doc/dev.md +++ b/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 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 Keep notes here about how adding libraries and classes to Babashka affects the binary size. diff --git a/src/babashka/main.clj b/src/babashka/main.clj index fa9828fc..99304332 100644 --- a/src/babashka/main.clj +++ b/src/babashka/main.clj @@ -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)))) opts-map))) -(defn parse-opts [options] - (let [opt (first options) - tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))] - (when opt - (cond (contains? tasks opt) - {:run opt - :command-line-args (rest options)} - (fs/regular-file? opt) - (if (str/ends-with? opt ".jar") - {:jar opt - :command-line-args (next options)} - {:file opt - :command-line-args (next options)}) - (command? 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) +(defn parse-classpath [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)))] + (when opt + (cond (contains? tasks opt) + {:run opt + :classpath classpath + :command-line-args (rest options)} + (fs/regular-file? opt) + (if (str/ends-with? opt ".jar") + {:classpath classpath + :jar opt + :command-line-args (next options)} + {:classpath classpath + :file opt + :command-line-args (next options)}) + (command? opt) + (recur (cons (str "--" opt) (next options)) opts) + :else + (let [opts (loop [options options + opts-map opts] + (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 - :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) + :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-in true :shell-out true)) - ("-iO") (recur (next options) + ("-O") (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)))) - ("--run") - (parse-run-opts opts-map (next options)) - ("--tasks") - (assoc opts-map :list-tasks true - :command-line-args (next options)) - ;; fallback - (if (some opts-map [:file :jar :socket-repl :expressions :main :run]) - (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))))) + ("-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)))) + ("--run") + (parse-run-opts opts-map (next options)) + ("--tasks") + (assoc opts-map :list-tasks true + :command-line-args (next options)) + ;; fallback + (if (and opts-map + (some opts-map [:file :jar :socket-repl :expressions :main :run])) + (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 {})) @@ -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 expression :append true))) (when uberjar - (uberjar/run {:dest uberjar - :jar :uber - :classpath (cp/get-classpath) - :main-class main - :verbose verbose?})) + (if-let [cp (cp/get-classpath)] + (uberjar/run {:dest uberjar + :jar :uber + :classpath cp + :main-class main + :verbose verbose?}) + (throw (Exception. "The uberjar task needs a classpath.")))) exit-code)))) (defn main [& args] diff --git a/test/babashka/main_test.clj b/test/babashka/main_test.clj index 2136e115..014b40ad 100644 --- a/test/babashka/main_test.clj +++ b/test/babashka/main_test.clj @@ -18,18 +18,23 @@ (apply test-utils/bb (when (some? input) (str input)) (map str args)))) (deftest parse-opts-test - (is (= {:nrepl "1667"} - (main/parse-opts ["--nrepl-server"]))) - (is (= {:socket-repl "1666"} - (main/parse-opts ["--socket-repl"]))) + (is (= "1667" + (:nrepl (main/parse-opts ["--nrepl-server"])))) + (is (= "1666" + (:socket-repl (main/parse-opts ["--socket-repl"])))) (is (= {:nrepl "1667", :classpath "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"]} (main/parse-opts ["--socket-repl" "-e" "123"]))) (is (= {:socket-repl "1666", :expressions ["123"]} (main/parse-opts ["--socket-repl" "1666" "-e" "123"]))) (is (= {:nrepl "1666", :expressions ["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 "-e" "(println 123)"))) (is (= 123 (bb nil "--eval" "(println 123)"))) diff --git a/test/babashka/uberjar_test.clj b/test/babashka/uberjar_test.clj index ef09d0d2..eb420676 100644 --- a/test/babashka/uberjar_test.clj +++ b/test/babashka/uberjar_test.clj @@ -9,7 +9,7 @@ (let [tmp-file (java.io.File/createTempFile "uber" ".jar") path (.getPath 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" (tu/bb nil "--jar" path "1" "2" "3" "4"))) (is (= "(\"1\" \"2\" \"3\" \"4\")\n" @@ -24,7 +24,7 @@ (let [tmp-file (java.io.File/createTempFile "uber" ".jar") path (.getPath 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")))) (testing "use bb.edn classpath when no other --classpath" (tu/with-config {:paths ["test-resources/babashka/uberjar/src"]}