Skip to content

Commit

Permalink
Fix #101 (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude authored Jun 8, 2023
1 parent 77b3970 commit 7600777
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 52 deletions.
10 changes: 10 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [`*clojure-tools-download-fn*`](#borkdude.deps/*clojure-tools-download-fn*) - Can be dynamically rebound to customise the download of the Clojure tools.
- [`*dir*`](#borkdude.deps/*dir*) - Directory in which deps.clj should be executed.
- [`*exit-fn*`](#borkdude.deps/*exit-fn*) - Function that is called on exit with <code>:exit</code> code and <code>:message</code>, an exceptional message when exit is non-zero.
- [`*getenv-fn*`](#borkdude.deps/*getenv-fn*) - Get ENV'ironment variable, typically used for getting <code>CLJ_CONFIG</code>, etc.
- [`-main`](#borkdude.deps/-main) - See <code>help-text</code>.
- [`clojure-tools-download-direct!`](#borkdude.deps/clojure-tools-download-direct!) - Downloads from <code>:url</code> to <code>:dest</code> file returning true on success.
- [`clojure-tools-download-java!`](#borkdude.deps/clojure-tools-download-java!) - Downloads <code>:url</code> zip file to <code>:dest</code> by invoking <code>java</code> with <code>:proxy</code> options on a <code>.java</code> program file, and returns true on success.
Expand Down Expand Up @@ -101,6 +102,15 @@ Directory in which deps.clj should be executed.
Function that is called on exit with `:exit` code and `:message`, an exceptional message when exit is non-zero
<p><sub><a href="https://github.com/borkdude/deps.clj/blob/master/src/borkdude/deps.clj#L39-L43">Source</a></sub></p>

## <a name="borkdude.deps/*getenv-fn*">`*getenv-fn*`</a><a name="borkdude.deps/*getenv-fn*"></a>
``` clojure

(*getenv-fn* env)
```

Get ENV'ironment variable, typically used for getting `CLJ_CONFIG`, etc.
<p><sub><a href="https://github.com/borkdude/deps.clj/blob/master/src/borkdude/deps.clj#L236-L239">Source</a></sub></p>

## <a name="borkdude.deps/-main">`-main`</a><a name="borkdude.deps/-main"></a>
``` clojure

Expand Down
76 changes: 52 additions & 24 deletions deps.bat
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@

(defn ^:dynamic *aux-process-fn*
"Invokes `java` with arguments to calculate classpath, etc. May be
replacement by rebinding this dynamic var.
replaced by rebinding this dynamic var.

Called with a map of:

Expand All @@ -138,13 +138,13 @@

(defn ^:dynamic *clojure-process-fn*
"Invokes `java` with arguments to `clojure.main` to start Clojure. May
be replacement by rebinding this dynamic var.
be replaced by rebinding this dynamic var.

Called with a map of:

- `:cmd`: a vector of strings

Must return a map of `:exit`, the exit code of te process."
Must return a map of `:exit`, the exit code of the process."
[{:keys [cmd]}]
(internal-shell-command cmd))

Expand Down Expand Up @@ -241,8 +241,8 @@ For more info, see:
(print "\n ") (describe-line line))
(println "}")))

(defn- ^:dynamic *getenv-fn*
"Get ENV'ironment variable. Only used for testing, not part of the public API (yet)."
(defn ^:dynamic *getenv-fn*
"Get ENV'ironment variable, typically used for getting `CLJ_CONFIG`, etc."
^String [env]
(java.lang.System/getenv env))

Expand Down Expand Up @@ -335,7 +335,7 @@ For more info, see:

(defn set-proxy-system-props!
"Sets the proxy system properties in the current JVM.
proxy-info parameter is as returned from env-proxy-info."
proxy-info parameter is as returned from `get-proxy-info.`"
[{:keys [http-proxy https-proxy]}]
(when http-proxy
(System/setProperty "http.proxyHost" (:host http-proxy))
Expand Down Expand Up @@ -454,7 +454,7 @@ public class ClojureToolsDownloader {
(defn proxy-jvm-opts
"Returns a vector containing the JVM system property arguments to be passed to a new process
to set its proxy system properties.
proxy-info parameter is as returned from env-proxy-info."
proxy-info parameter is as returned from `get-proxy-info.`"
[{:keys [http-proxy https-proxy]}]
(cond-> []
http-proxy (concat [(str "-Dhttp.proxyHost=" (:host http-proxy))
Expand Down Expand Up @@ -490,16 +490,20 @@ public class ClojureToolsDownloader {
- `:dest`: The path to the file to download it to, as a string
- `:proxy-opts`: a map as returned by `get-proxy-info`
- `:clj-jvm-opts`: a vector of JVM opts (as passed on the command line).
Should return true if the `download` was successful, or false if not."

Should return `true` if the download was successful, or false if not."
nil)

(defn clojure-tools-download!
"Downloads clojure tools archive in `:out-dir`, if not already there,
and extracts in-place the clojure tools jar file and other important
files.
(defn clojure-tools-install!
"Installs clojure tools archive by downloading it in `:out-dir`, if not already there,
and extracting in-place.

If `*clojure-tools-download-fn*` is set, it will be called for
download the tools archive. This function should return a truthy
value to indicate a successful download.

The download is attempted directly from this process, unless
`:jvm-opts` is set, in which case a java subprocess
`:clj-jvm-opts` is set, in which case a java subprocess
is created to download the archive passing in its value as command
line options.

Expand Down Expand Up @@ -722,16 +726,19 @@ public class ClojureToolsDownloader {
[(.getPath (io/file config-dir "deps.edn"))
deps-edn])))

(defn- calculate-checksum [opts config-paths]
(defn get-checksum
"Returns checksum based on cli-opts (as returned by `parse-cli-opts`)
and config-paths (as returned by `get-config-paths`)"
[{:keys [cli-opts config-paths]}]
(let [val*
(str/join "|"
(concat [cache-version]
(:repl-aliases opts)
[(:exec-aliases opts)
(:main-aliases opts)
(:deps-data opts)
(:tool-name opts)
(:tool-aliases opts)]
(:repl-aliases cli-opts)
[(:exec-aliases cli-opts)
(:main-aliases cli-opts)
(:deps-data cli-opts)
(:tool-name cli-opts)
(:tool-aliases cli-opts)]
(map (fn [config-path]
(if (.exists (io/file config-path))
config-path
Expand All @@ -749,6 +756,27 @@ public class ClojureToolsDownloader {
[]
(println @help-text))

(defn get-basis-file
"Returns path to basis file. Required options:

* - `cache-dir` as returned by `get-cache-dir`
* - `checksum` as returned by `get-check-sum`"
[{:keys [cache-dir checksum]}]
(.getPath (io/file cache-dir (str checksum ".basis"))))

(defn- auto-file-arg [cp]
;; see https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
;; command line limit on Windows with process builder
(if (and windows? (> (count cp) 32766))
(let [tmp-file (.toFile (java.nio.file.Files/createTempFile
"file_arg" ".txt"
(into-array java.nio.file.attribute.FileAttribute [])))]
(.deleteOnExit tmp-file)
;; we use pr-str since whitespaces in the classpath will be treated as separate args otherwise
(spit tmp-file (pr-str cp))
(str "@" tmp-file))
cp))

(defn -main
"See `help-text`.

Expand Down Expand Up @@ -789,7 +817,7 @@ public class ClojureToolsDownloader {
(when (.exists tools-jar) (.getPath tools-jar))
(binding [*out* *err*]
(warn "Clojure tools not yet in expected location:" (str tools-jar))
(clojure-tools-download! {:out-dir libexec-dir :debug debug :clj-jvm-opts clj-jvm-opts :proxy-opts proxy-opts})
(clojure-tools-install! {:out-dir libexec-dir :debug debug :clj-jvm-opts clj-jvm-opts :proxy-opts proxy-opts})
tools-jar))
mode (:mode cli-opts)
exec? (= :exec mode)
Expand Down Expand Up @@ -835,11 +863,11 @@ public class ClojureToolsDownloader {
;; Construct location of cached classpath file
tool-name (:tool-name cli-opts)
tool-aliases (:tool-aliases cli-opts)
ck (calculate-checksum cli-opts config-paths)
ck (get-checksum {:cli-opts cli-opts :config-paths config-paths})
cp-file (.getPath (io/file cache-dir (str ck ".cp")))
jvm-file (.getPath (io/file cache-dir (str ck ".jvm")))
main-file (.getPath (io/file cache-dir (str ck ".main")))
basis-file (.getPath (io/file cache-dir (str ck ".basis")))
basis-file (get-basis-file {:cache-dir cache-dir :checksum ck})
manifest-file (.getPath (io/file cache-dir (str ck ".manifest")))
_ (when (:verbose cli-opts)
(println "deps.clj version =" deps-clj-version)
Expand Down Expand Up @@ -988,7 +1016,7 @@ public class ClojureToolsDownloader {
jvm-cache-opts
(:jvm-opts cli-opts)
[(str "-Dclojure.basis=" (relativize basis-file))
"-classpath" cp
"-classpath" (auto-file-arg cp)
"clojure.main"]
main-opts)
main-args (filterv some? main-args)
Expand Down
76 changes: 52 additions & 24 deletions deps.clj
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@

(defn ^:dynamic *aux-process-fn*
"Invokes `java` with arguments to calculate classpath, etc. May be
replacement by rebinding this dynamic var.
replaced by rebinding this dynamic var.
Called with a map of:
Expand All @@ -133,13 +133,13 @@

(defn ^:dynamic *clojure-process-fn*
"Invokes `java` with arguments to `clojure.main` to start Clojure. May
be replacement by rebinding this dynamic var.
be replaced by rebinding this dynamic var.
Called with a map of:
- `:cmd`: a vector of strings
Must return a map of `:exit`, the exit code of te process."
Must return a map of `:exit`, the exit code of the process."
[{:keys [cmd]}]
(internal-shell-command cmd))

Expand Down Expand Up @@ -236,8 +236,8 @@ For more info, see:
(print "\n ") (describe-line line))
(println "}")))

(defn- ^:dynamic *getenv-fn*
"Get ENV'ironment variable. Only used for testing, not part of the public API (yet)."
(defn ^:dynamic *getenv-fn*
"Get ENV'ironment variable, typically used for getting `CLJ_CONFIG`, etc."
^String [env]
(java.lang.System/getenv env))

Expand Down Expand Up @@ -330,7 +330,7 @@ For more info, see:

(defn set-proxy-system-props!
"Sets the proxy system properties in the current JVM.
proxy-info parameter is as returned from env-proxy-info."
proxy-info parameter is as returned from `get-proxy-info.`"
[{:keys [http-proxy https-proxy]}]
(when http-proxy
(System/setProperty "http.proxyHost" (:host http-proxy))
Expand Down Expand Up @@ -449,7 +449,7 @@ public class ClojureToolsDownloader {
(defn proxy-jvm-opts
"Returns a vector containing the JVM system property arguments to be passed to a new process
to set its proxy system properties.
proxy-info parameter is as returned from env-proxy-info."
proxy-info parameter is as returned from `get-proxy-info.`"
[{:keys [http-proxy https-proxy]}]
(cond-> []
http-proxy (concat [(str "-Dhttp.proxyHost=" (:host http-proxy))
Expand Down Expand Up @@ -485,16 +485,20 @@ public class ClojureToolsDownloader {
- `:dest`: The path to the file to download it to, as a string
- `:proxy-opts`: a map as returned by `get-proxy-info`
- `:clj-jvm-opts`: a vector of JVM opts (as passed on the command line).
Should return true if the `download` was successful, or false if not."
Should return `true` if the download was successful, or false if not."
nil)

(defn clojure-tools-download!
"Downloads clojure tools archive in `:out-dir`, if not already there,
and extracts in-place the clojure tools jar file and other important
files.
(defn clojure-tools-install!
"Installs clojure tools archive by downloading it in `:out-dir`, if not already there,
and extracting in-place.
If `*clojure-tools-download-fn*` is set, it will be called for
download the tools archive. This function should return a truthy
value to indicate a successful download.
The download is attempted directly from this process, unless
`:jvm-opts` is set, in which case a java subprocess
`:clj-jvm-opts` is set, in which case a java subprocess
is created to download the archive passing in its value as command
line options.
Expand Down Expand Up @@ -717,16 +721,19 @@ public class ClojureToolsDownloader {
[(.getPath (io/file config-dir "deps.edn"))
deps-edn])))

(defn- calculate-checksum [opts config-paths]
(defn get-checksum
"Returns checksum based on cli-opts (as returned by `parse-cli-opts`)
and config-paths (as returned by `get-config-paths`)"
[{:keys [cli-opts config-paths]}]
(let [val*
(str/join "|"
(concat [cache-version]
(:repl-aliases opts)
[(:exec-aliases opts)
(:main-aliases opts)
(:deps-data opts)
(:tool-name opts)
(:tool-aliases opts)]
(:repl-aliases cli-opts)
[(:exec-aliases cli-opts)
(:main-aliases cli-opts)
(:deps-data cli-opts)
(:tool-name cli-opts)
(:tool-aliases cli-opts)]
(map (fn [config-path]
(if (.exists (io/file config-path))
config-path
Expand All @@ -744,6 +751,27 @@ public class ClojureToolsDownloader {
[]
(println @help-text))

(defn get-basis-file
"Returns path to basis file. Required options:
* - `cache-dir` as returned by `get-cache-dir`
* - `checksum` as returned by `get-check-sum`"
[{:keys [cache-dir checksum]}]
(.getPath (io/file cache-dir (str checksum ".basis"))))

(defn- auto-file-arg [cp]
;; see https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
;; command line limit on Windows with process builder
(if (and windows? (> (count cp) 32766))
(let [tmp-file (.toFile (java.nio.file.Files/createTempFile
"file_arg" ".txt"
(into-array java.nio.file.attribute.FileAttribute [])))]
(.deleteOnExit tmp-file)
;; we use pr-str since whitespaces in the classpath will be treated as separate args otherwise
(spit tmp-file (pr-str cp))
(str "@" tmp-file))
cp))

(defn -main
"See `help-text`.
Expand Down Expand Up @@ -784,7 +812,7 @@ public class ClojureToolsDownloader {
(when (.exists tools-jar) (.getPath tools-jar))
(binding [*out* *err*]
(warn "Clojure tools not yet in expected location:" (str tools-jar))
(clojure-tools-download! {:out-dir libexec-dir :debug debug :clj-jvm-opts clj-jvm-opts :proxy-opts proxy-opts})
(clojure-tools-install! {:out-dir libexec-dir :debug debug :clj-jvm-opts clj-jvm-opts :proxy-opts proxy-opts})
tools-jar))
mode (:mode cli-opts)
exec? (= :exec mode)
Expand Down Expand Up @@ -830,11 +858,11 @@ public class ClojureToolsDownloader {
;; Construct location of cached classpath file
tool-name (:tool-name cli-opts)
tool-aliases (:tool-aliases cli-opts)
ck (calculate-checksum cli-opts config-paths)
ck (get-checksum {:cli-opts cli-opts :config-paths config-paths})
cp-file (.getPath (io/file cache-dir (str ck ".cp")))
jvm-file (.getPath (io/file cache-dir (str ck ".jvm")))
main-file (.getPath (io/file cache-dir (str ck ".main")))
basis-file (.getPath (io/file cache-dir (str ck ".basis")))
basis-file (get-basis-file {:cache-dir cache-dir :checksum ck})
manifest-file (.getPath (io/file cache-dir (str ck ".manifest")))
_ (when (:verbose cli-opts)
(println "deps.clj version =" deps-clj-version)
Expand Down Expand Up @@ -983,7 +1011,7 @@ public class ClojureToolsDownloader {
jvm-cache-opts
(:jvm-opts cli-opts)
[(str "-Dclojure.basis=" (relativize basis-file))
"-classpath" cp
"-classpath" (auto-file-arg cp)
"clojure.main"]
main-opts)
main-args (filterv some? main-args)
Expand Down
Loading

0 comments on commit 7600777

Please sign in to comment.