Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #101 #102

Merged
merged 2 commits into from
Jun 8, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix #101
borkdude committed Jun 8, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 58e76b10b2e19d4f245ee1eb8ca73c9b53855166
10 changes: 10 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -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.
@@ -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

76 changes: 52 additions & 24 deletions deps.bat
Original file line number Diff line number Diff line change
@@ -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:

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

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

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

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

@@ -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)
@@ -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)
@@ -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)
76 changes: 52 additions & 24 deletions deps.clj
Original file line number Diff line number Diff line change
@@ -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:

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

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

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

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

@@ -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)
@@ -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)
@@ -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)
16 changes: 12 additions & 4 deletions src/borkdude/deps.clj
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
;; see https://github.com/clojure/brew-install/blob/1.11.1/CHANGELOG.md
(def ^:private version
(delay (or (System/getenv "DEPS_CLJ_TOOLS_VERSION")
"1.11.1.1273")))
"1.11.1.1347")))

(def ^:private cache-version "4")

@@ -233,8 +233,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))

@@ -652,6 +652,14 @@ public class ClojureToolsDownloader {
(unixify (.toAbsolutePath (as-path f))))
f))))

(defn- resolve-dir
"Resolves against directory (when provided). Absolute paths are unchanged.
Returns string."
[dir path]
(if dir
(str (.resolve (as-path dir) (str path)))
(str path)))

(defn- get-env-tools-dir
"Retrieves the tools-directory from environment variable `DEPS_CLJ_TOOLS_DIR`"
[]
@@ -902,7 +910,7 @@ public class ClojureToolsDownloader {
entries (vec (.split ^String cp java.io.File/pathSeparator))]
(some (fn [entry]
(when (str/ends-with? entry ".jar")
(not (.exists (io/file entry)))))
(not (.exists (io/file (resolve-dir *dir* entry))))))
entries)))
tools-args
(when (or stale (:pom cli-opts))