add io/resource

This commit is contained in:
Michiel Borkent 2019-12-29 23:37:08 +01:00 committed by GitHub
parent 283783bdd3
commit 16ca4098c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 23 deletions

View file

@ -7,31 +7,37 @@
(set! *warn-on-reflection* true)
(defprotocol IResourceResolver
(getResource [this path]))
(getResource [this path opts]))
(deftype DirectoryResolver [path]
IResourceResolver
(getResource [this resource-path]
(getResource [this resource-path {:keys [:url?]}]
(let [f (io/file path resource-path)]
(when (.exists f)
(if url?
(java.net.URL. (str "file:"
(.getCanonicalPath f)))
{:file (.getCanonicalPath f)
:source (slurp f)}))))
:source (slurp f)})))))
(defn path-from-jar
[^java.io.File jar-file path]
[^java.io.File jar-file path {:keys [:url?]}]
(with-open [jar (JarFile. jar-file)]
(let [entries (enumeration-seq (.entries jar))
entry (some (fn [^JarFile$JarFileEntry x]
(let [nm (.getName x)]
(when (and (not (.isDirectory x)) (= path nm))
(if url?
(java.net.URL.
(str "jar:file:" (.getCanonicalPath jar-file) "!/" path))
{:file path
:source (slurp (.getInputStream jar x))}))) entries)]
:source (slurp (.getInputStream jar x))})))) entries)]
entry)))
(deftype JarFileResolver [path]
IResourceResolver
(getResource [this resource-path]
(path-from-jar path resource-path)))
(getResource [this resource-path opts]
(path-from-jar path resource-path opts)))
(defn part->entry [part]
(if (str/ends-with? part ".jar")
@ -40,25 +46,25 @@
(deftype Loader [entries]
IResourceResolver
(getResource [this resource-path]
(some #(getResource % resource-path) entries)))
(getResource [this resource-path opts]
(some #(getResource % resource-path opts) entries)))
(defn loader [^String classpath]
(let [parts (.split classpath (System/getProperty "path.separator"))
entries (map part->entry parts)]
(Loader. entries)))
(defn source-for-namespace [loader namespace]
(defn source-for-namespace [loader namespace opts]
(let [ns-str (name namespace)
^String ns-str (munge ns-str)
path (.replace ns-str "." (System/getProperty "file.separator"))
paths (map #(str path %) [".bb" ".clj" ".cljc"])]
(some #(getResource loader %) paths)))
(some #(getResource loader % opts) paths)))
;;;; Scratch
(comment
(def l (loader "src:/Users/borkdude/.m2/repository/cheshire/cheshire/5.9.0/cheshire-5.9.0.jar"))
(source-for-namespace l 'babashka.impl.cheshire)
(:file (source-for-namespace l 'cheshire.core))
(source-for-namespace l 'babashka.impl.cheshire nil)
(:file (source-for-namespace l 'cheshire.core nil))
)

View file

@ -275,17 +275,20 @@ Everything after that is bound to *command-line-args*."))
(cp/loader classpath))
load-fn (when classpath
(fn [{:keys [:namespace]}]
(let [res (cp/source-for-namespace loader namespace)]
(let [res (cp/source-for-namespace loader namespace nil)]
(when uberscript (swap! uberscript-sources conj (:source res)))
res)))
_ (when file (vars/bindRoot vars/file-var (.getCanonicalPath (io/file file))))
ctx {:aliases aliases
:namespaces (assoc namespaces 'clojure.core
:namespaces (-> namespaces
(assoc 'clojure.core
(assoc core-extras
'*command-line-args*
(sci/new-dynamic-var '*command-line-args* command-line-args)
'*file* vars/file-var
'*warn-on-reflection* reflection-var))
(assoc-in ['clojure.java.io 'resource]
#(when classpath (cp/getResource loader % {:url? true}))))
:bindings bindings
:env env
:features #{:bb}

View file

@ -2,7 +2,8 @@
(:require
[babashka.test-utils :as tu]
[clojure.edn :as edn]
[clojure.test :as t :refer [deftest is]]))
[clojure.test :as t :refer [deftest is]]
[clojure.java.io :as io]))
(defn bb [input & args]
(edn/read-string (apply tu/bb (when (some? input) (str input)) (map str args))))
@ -41,3 +42,10 @@
(require '[ns-with-error])
(catch Exception nil))
(nil? (resolve 'ns-with-error/x))"))))
(deftest resource-test
(let [tmp-file (java.io.File/createTempFile "icon" ".png")]
(.deleteOnExit tmp-file)
(bb nil "--classpath" "logo" "-e" (format "(io/copy (io/input-stream (io/resource \"icon.png\")) (io/file \"%s\"))" (.getPath tmp-file)))
(is (= (.length (io/file "logo" "icon.png"))
(.length tmp-file)))))