WIP supporting library-bootstrapped pods

Still need to make this work w/ :local/root pod libs and in uberscripts
This commit is contained in:
Wes Morgan 2022-10-07 10:57:11 -06:00
parent 9241c81238
commit a2966d5967
No known key found for this signature in database
GPG key ID: 5639E4CBFA17DC84
3 changed files with 66 additions and 28 deletions

View file

@ -23,20 +23,20 @@
(when (.exists f)
(if url?
;; manual conversion, faster than going through .toURI
(java.net.URL. "file" nil (.getAbsolutePath f))
(URL. "file" nil (.getAbsolutePath f))
{:file (.getAbsolutePath f)
:source (slurp f)}))))
resource-paths)))
(defn path-from-jar
[^java.io.File jar-file resource-paths url?]
[^File jar-file resource-paths url?]
(with-open [jar (JarFile. jar-file)]
(some (fn [path]
(when-let [entry (.getEntry jar path)]
(if url?
;; manual conversion, faster than going through .toURI
(java.net.URL. "jar" nil
(str "file:" (.getAbsolutePath jar-file) "!/" path))
(URL. "jar" nil
(str "file:" (.getAbsolutePath jar-file) "!/" path))
{:file path
:source (slurp (.getInputStream jar entry))})))
resource-paths)))
@ -61,19 +61,36 @@
(def path-sep (System/getProperty "path.separator"))
(defn loader [^String classpath]
(let [parts (.split classpath path-sep)
entries (keep part->entry parts)]
(Loader. entries)))
(defn classpath-entries [^String classpath]
(let [parts (.split classpath path-sep)]
(keep part->entry parts)))
(defn source-for-namespace [loader namespace opts]
(let [ns-str (name namespace)
^String ns-str (munge ns-str)
;; do NOT pick the platform specific file separator here, since that doesn't work for searching in .jar files
;; (io/file "foo" "bar/baz") does work on Windows, despite the forward slash
base-path (.replace ns-str "." "/")
resource-paths (mapv #(str base-path %) [".bb" ".clj" ".cljc"])]
(getResource loader resource-paths opts)))
(defn loader [^String classpath]
(Loader. (classpath-entries classpath)))
(declare get-classpath)
(defn source-for-namespace
([namespace opts]
(some-> (get-classpath) loader (source-for-namespace namespace opts)))
([loader namespace opts]
(let [ns-str (name namespace)
^String ns-str (munge ns-str)
;; do NOT pick the platform specific file separator here, since that doesn't work for searching in .jar files
;; (io/file "foo" "bar/baz") does work on Windows, despite the forward slash
base-path (.replace ns-str "." "/")
manifest-paths (loop [ns (str/split ns-str #"\.")
paths []]
(let [path (str/join "/" (conj ns "pod-manifest.edn"))
next-ns (-> ns butlast vec)
next-paths (conj paths path)]
(if (< 1 (count next-ns)) ; don't look in top-level (e.g. com, pod) namespaces
(recur next-ns next-paths)
next-paths)))
resource-paths (into (mapv #(str base-path %)
[".bb" ".clj" ".cljc"])
manifest-paths)]
(getResource loader resource-paths opts))))
(defn main-ns [manifest-resource]
(with-open [is (io/input-stream manifest-resource)]

View file

@ -32,6 +32,14 @@
"for pods on your local filesystem."))))))
{} pods-map))
(defn load-pod-from-manifest
[manifest]
(pods/load-pod-from-manifest manifest (-> @bb-edn :file io/file)))
(defn pod-manifest-file
[manifest]
(pods/pod-manifest-file manifest))
(def podns (sci/create-ns 'babashka.pods nil))
(def pods-namespace

View file

@ -408,14 +408,14 @@ Use bb run --help to show this help output.
(sci/create-ns 'clojure.core.rrb-vector))})
'edamame.core edamame-namespace
'sci.core {'format-stacktrace (sci/copy-var sci/format-stacktrace sci-ns)
'stacktrace (sci/copy-var sci/stacktrace sci-ns)
'stacktrace (sci/copy-var sci/stacktrace sci-ns)}
;; 'eval-string (sci/copy-var sci/eval-string sci-ns)
;; 'eval-string* (sci/copy-var sci/eval-string* sci-ns)
;; 'init (sci/copy-var sci/init sci-ns)
;; 'fork (sci/copy-var sci/fork sci-ns)
}
'babashka.cli cli/cli-namespace
}
'babashka.cli cli/cli-namespace}
features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace)
'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace)
'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
@ -843,15 +843,28 @@ Use bb run --help to show this help output.
(dissoc (:opts pod)
:version :metadata)))
{})
(pods/load-pod (:pod-spec pod) (:opts pod)))))
(do
(pods/load-pod (:pod-spec pod) (:opts pod))
{}))))
(when loader
(when-let [res (cp/source-for-namespace loader namespace nil)]
(if uberscript
(do (swap! uberscript-sources conj (:source res))
(uberscript/uberscript {:ctx @common/ctx
:expressions [(:source res)]})
{})
res)))
(println "load-fn source-for-namespace res:" (pr-str res))
(if (str/ends-with? (:file res) "/pod-manifest.edn")
(let [manifest (-> res :source edn/read-string)]
(when-let [pod-nses (pods/load-pod-from-manifest manifest)]
(println "load-fn got pod namespaces:" (pr-str pod-nses))
(spit (pods/pod-manifest-file manifest) (:source res))
(vswap! pod-namespaces merge pod-nses)
(let [pod (get pod-nses namespace)]
(pods/load-pod (:pod-spec pod) (:opts pod)))
{}))
;; TODO: Figure out how to handle library pods in uberscripts
(if uberscript
(do (swap! uberscript-sources conj (:source res))
(uberscript/uberscript {:ctx @common/ctx
:expressions [(:source res)]})
{})
res))))
(case namespace
clojure.spec.alpha
(binding [*out* *err*]
@ -887,7 +900,7 @@ Use bb run --help to show this help output.
_ (when-let [pods (:pods @common/bb-edn)]
(when-let [pod-metadata (pods/load-pods-metadata
pods {:download-only (download-only?)})]
(vreset! pod-namespaces pod-metadata)))
(vswap! pod-namespaces merge pod-metadata)))
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
[expressions exit-code]
(cond expressions [expressions nil]