Skip to content

Commit

Permalink
Add support for CLJ_JVM_OPTS and JAVA_OPTS (#60)
Browse files Browse the repository at this point in the history
Co-authored-by: ikappaki <[email protected]>
  • Loading branch information
borkdude and ikappaki authored Sep 30, 2022
1 parent d4d6d72 commit 641906f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 19 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,13 @@ $ lein run -m borkdude.deps -Spath
To run jvm tests:

```
$ script/jvm_test
$ bb test
```

To run with babashka after making changes to `src/borkdude/deps.clj`, you should run:

```
$ script/gen_script.clj
$ bb gen-script
```

and then:
Expand Down
16 changes: 16 additions & 0 deletions bb.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{:paths ["resources"]

:tasks
{:requires [[babashka.deps :as deps]
[babashka.process :as p]]

gen-script {:doc "Regen `./deps[.clj|.bat]` from `src/borkdude/deps.clj`."
:task (load-file "script/gen_script.clj")}

test {:doc "Run all tests."
:task
(doseq [args '[[-M:test] [-M -m borkdude.deps -M:test]]]
(println :testing... 'clojure args)
(-> (deps/clojure args)
p/check)
(println))}}}
41 changes: 25 additions & 16 deletions src/borkdude/deps.clj
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ For more info, see:
(print "\n ") (describe-line line))
(println "}")))

(defn ^:private ^:dynamic *getenv-fn*
"Get ENV'ironment variable."
^String [env]
(java.lang.System/getenv env))

(defn cksum
[^String s]
(let [hashed (.digest (java.security.MessageDigest/getInstance "MD5")
Expand All @@ -204,7 +209,7 @@ For more info, see:
(str sw)))

(defn which [executable]
(when-let [path (System/getenv "PATH")]
(when-let [path (*getenv-fn* "PATH")]
(let [paths (.split path path-separator)]
(loop [paths paths]
(when-first [p paths]
Expand All @@ -217,7 +222,7 @@ For more info, see:
(defn home-dir []
(if windows?
;; workaround for https://github.com/oracle/graal/issues/1630
(System/getenv "userprofile")
(*getenv-fn* "userprofile")
(System/getProperty "user.home")))

(defn download [source dest]
Expand Down Expand Up @@ -289,10 +294,10 @@ For more info, see:

(defn jvm-proxy-settings
[]
(let [http-proxy (parse-proxy-info (or (System/getenv "http_proxy")
(System/getenv "HTTP_PROXY")))
https-proxy (parse-proxy-info (or (System/getenv "https_proxy")
(System/getenv "HTTPS_PROXY")))]
(let [http-proxy (parse-proxy-info (or (*getenv-fn* "http_proxy")
(*getenv-fn* "HTTP_PROXY")))
https-proxy (parse-proxy-info (or (*getenv-fn* "https_proxy")
(*getenv-fn* "HTTPS_PROXY")))]
(when http-proxy
(System/setProperty "http.proxyHost" (:host http-proxy))
(System/setProperty "http.proxyPort" (:port http-proxy)))
Expand Down Expand Up @@ -428,10 +433,10 @@ For more info, see:
(defn -main [& command-line-args]
(let [opts (parse-args command-line-args)
java-cmd
(or (System/getenv "JAVA_CMD")
(or (*getenv-fn* "JAVA_CMD")
(let [java-cmd (which java-exe)]
(if (str/blank? java-cmd)
(let [java-home (System/getenv "JAVA_HOME")]
(let [java-home (*getenv-fn* "JAVA_HOME")]
(if-not (str/blank? java-home)
(let [f (io/file java-home "bin" java-exe)]
(if (and (.exists f)
Expand All @@ -442,8 +447,8 @@ For more info, see:
java-cmd)))
env-tools-dir (or
;; legacy name
(System/getenv "CLOJURE_TOOLS_DIR")
(System/getenv "DEPS_CLJ_TOOLS_DIR"))
(*getenv-fn* "CLOJURE_TOOLS_DIR")
(*getenv-fn* "DEPS_CLJ_TOOLS_DIR"))
tools-dir (or env-tools-dir
(.getPath (io/file (home-dir)
".deps.clj"
Expand Down Expand Up @@ -475,15 +480,18 @@ For more info, see:
deps-edn
(or (:deps-file opts)
(.getPath (io/file *dir* "deps.edn")))
clj-jvm-opts (some-> (*getenv-fn* "CLJ_JVM_OPTS") (str/split #" "))
clj-main-cmd
(vec (concat [java-cmd]
clj-jvm-opts
proxy-settings
["-Xms256m" "-classpath" tools-cp "clojure.main"]))
config-dir
(or (System/getenv "CLJ_CONFIG")
(when-let [xdg-config-home (System/getenv "XDG_CONFIG_HOME")]
(or (*getenv-fn* "CLJ_CONFIG")
(when-let [xdg-config-home (*getenv-fn* "XDG_CONFIG_HOME")]
(.getPath (io/file xdg-config-home "clojure")))
(.getPath (io/file (home-dir) ".clojure")))]
(.getPath (io/file (home-dir) ".clojure")))
java-opts (some-> (*getenv-fn* "JAVA_OPTS") (str/split #" "))]
;; If user config directory does not exist, create it
(let [config-dir (io/file config-dir)]
(when-not (.exists config-dir)
Expand All @@ -503,8 +511,8 @@ For more info, see:
(io/copy install-tools-edn config-tools-edn)))
;; Determine user cache directory
(let [user-cache-dir
(or (System/getenv "CLJ_CACHE")
(when-let [xdg-config-home (System/getenv "XDG_CACHE_HOME")]
(or (*getenv-fn* "CLJ_CACHE")
(when-let [xdg-config-home (*getenv-fn* "XDG_CACHE_HOME")]
(.getPath (io/file xdg-config-home "clojure")))
(.getPath (io/file config-dir ".cpcache")))
;; Chain deps.edn in config paths. repro=skip config dir
Expand Down Expand Up @@ -637,7 +645,7 @@ For more info, see:
{:to-string? tree?})]
(when tree?
(print res) (flush))))
(let [cp (cond (or classpath-not-needed?
(let [cp (cond (or classpath-not-needed?
(:prep opts)) nil
(not (str/blank? (:force-cp opts))) (:force-cp opts)
:else (slurp (io/file cp-file)))]
Expand Down Expand Up @@ -691,6 +699,7 @@ For more info, see:
(str cp path-separator exec-cp)
cp)
main-args (concat [java-cmd]
java-opts
proxy-settings
jvm-cache-opts
(:jvm-opts opts)
Expand Down
85 changes: 84 additions & 1 deletion test/borkdude/deps_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
[clojure.test :as t :refer [deftest is testing]]))

(def invoke-deps-cmd
"Returns the command to invoke `borkdude.deps` on the current system,
based on the value of env variable `DEPS_CLJ_TEST_ENV`."
(case (System/getenv "DEPS_CLJ_TEST_ENV")
"babashka" (let [classpath (str/join deps/path-separator ["src" "test" "resources"])]
(str "bb -cp " classpath " -m borkdude.deps "))
"native" "./deps "
"clojure -M -m borkdude.deps "))
(cond->>
"clojure -M -m borkdude.deps "
deps/windows?
(str "powershell -NoProfile -Command "))))

(deftest parse-args-test
(is (= {:mode :repl, :jvm-opts ["-Dfoo=bar" "-Dbaz=quuz"]}
Expand Down Expand Up @@ -132,3 +137,81 @@

(deftest tools-test
(deps/-main "-Ttools" "list"))

(defmacro get-shell-command-args
"Executes BODY with the given ENV'ironment variables added to the
`babashka.deps` scope, presumbably to indirectly invoke
`babashka.deps/shell-command` whose invocation ARGS captures and
returns with this call.
It overrides `baabashka.deps/*exit-fn*` so as to never exit the
program, but throws an exception in case of error while is still in
the `babashka.deps` scope."
[env-vars & body]
(let [body-str (pr-str body)]
`(let [shell-command# deps/shell-command
ret*# (promise)
sh-mock# (fn mock#
([args#]
(mock# args# nil))
([args# opts#]
(let [ret# (shell-command# args# opts#)]
(deliver ret*# args#)
ret#)))]
;; need to override both *process-fn* and deps/shell-command.
(binding [deps/*process-fn* sh-mock#
deps/*exit-fn* (fn
([exit-code#] (when-not (= exit-code# 0)
(throw (ex-info "mock-shell-failed" {:exit-code exit-code#}))))
([exit-code# msg#] (throw (ex-info "mock-shell-failed"
{:exit-code exit-code# :msg msg#}))))
deps/*getenv-fn* #(or (get ~env-vars %)
(System/getenv %))]
(with-redefs [deps/shell-command sh-mock#]
~@body
(or (deref ret*# 500 false) (ex-info "No shell-command invoked in body." {:body ~body-str})))))))

(deftest clj-jvm-opts+java-opts
;; The `CLJ_JVM_OPTS` env var should only apply to -P and -Spom.
;; The `JAVA_OPTS` env varshould only apply to everything else.
;;
;; Some harmless cli flags are used below to demonstrate the
;; succesful passing of cli arguments to the java executable.

(let [xx-pclf "-XX:+PrintCommandLineFlags"
xx-gc-threads "-XX:ConcGCThreads=1"]

(testing "CLJ-JVM-OPTS with prepare deps"
(let [sh-args (get-shell-command-args
{"CLJ_JVM_OPTS" (str/join " " [xx-pclf xx-gc-threads])}
(deps/-main "-P"))]
(is (some #{xx-pclf} sh-args))
;; second and third args
(is (= [xx-pclf xx-gc-threads] (->> (rest sh-args) (take 2))))))

(testing "CLJ-JVM-OPTS with pom"
(let [sh-args (get-shell-command-args
{"CLJ_JVM_OPTS" (str/join " " [xx-pclf xx-gc-threads])}
(deps/-main "-Spom"))]
(is (some #{xx-pclf} sh-args))
(is (= [xx-pclf xx-gc-threads] (->> (rest sh-args) (take 2))))))

(testing "CLJ-JVM-OPTS outside of prepare deps"
(let [sh-args (get-shell-command-args
{"CLJ_JVM_OPTS" xx-pclf}
(deps/-main "-e" "123"))]
;; shouldn't find the flag
(is (not (some #{xx-pclf} sh-args)))))

(testing "JAVA-OPTS outside of prepare deps"
(let [sh-args (get-shell-command-args
{"JAVA_OPTS" (str/join " " [xx-pclf xx-gc-threads])}
(deps/-main "-e" "123"))]
(is (some #{xx-pclf} sh-args))
(is (= [xx-pclf xx-gc-threads] (->> (rest sh-args) (take 2))))))

(testing "JAVA-OPTS with prepare deps"
(let [sh-args (get-shell-command-args
{"JAVA_OPTS" xx-pclf}
(deps/-main "-P"))]
(is (not (some #{xx-pclf} sh-args)))))))

0 comments on commit 641906f

Please sign in to comment.