Add support for installing pods from local manifests

...as a part of supporting library-bootstrapped pods
This commit is contained in:
Wes Morgan 2022-10-07 10:24:34 -06:00
parent 8bc0852799
commit 189548ca50
No known key found for this signature in database
GPG key ID: 5639E4CBFA17DC84
2 changed files with 93 additions and 45 deletions

View file

@ -131,9 +131,13 @@
"https://raw.githubusercontent.com/babashka/pod-registry/master/manifests/%s/%s/manifest.edn" "https://raw.githubusercontent.com/babashka/pod-registry/master/manifests/%s/%s/manifest.edn"
qsym version)) qsym version))
(defn pod-manifest-file
[qsym version]
(io/file @pods-repo-dir (str qsym) (str version) "manifest.edn"))
(defn pod-manifest (defn pod-manifest
[qsym version force?] [qsym version force?]
(let [f (io/file @pods-repo-dir (str qsym) (str version) "manifest.edn")] (let [f (pod-manifest-file qsym version)]
(if (and (not force?) (if (and (not force?)
(.exists f)) (.exists f))
(edn/read-string (slurp f)) (edn/read-string (slurp f))
@ -182,20 +186,16 @@
(.digest digest)) (.digest digest))
(String. "UTF-8")))) (String. "UTF-8"))))
(defn resolve [qsym version force?] (defn install-pod-artifacts
(when-not (string? version) [artifacts {cdir :cache-dir, ddir :data-dir, :keys [:force? :pod/options]}]
(throw (IllegalArgumentException. "Version must be provided for resolving from pod registry!"))) (let [execs (mapv (fn [artifact]
(when-let [manifest (pod-manifest qsym version force?)]
(let [artifacts (match-artifacts manifest)
cdir (cache-dir manifest)
ddir (data-dir manifest)
execs (mapv (fn [artifact]
(let [url (:artifact/url artifact) (let [url (:artifact/url artifact)
file-name (last (str/split url #"/")) file-name (last (str/split url #"/"))
cache-file (io/file cdir file-name) cache-file (io/file cdir file-name)
executable (io/file ddir (:artifact/executable artifact))] exe-file-name (:artifact/executable artifact)
executable (io/file ddir exe-file-name)]
(when (or force? (not (.exists executable))) (when (or force? (not (.exists executable)))
(warn (format "Downloading pod %s (%s)" qsym version)) (warn (format "Downloading pod %s" url))
(download url cache-file false) (download url cache-file false)
(when-let [expected-sha (:artifact/hash artifact)] (when-let [expected-sha (:artifact/hash artifact)]
(let [sha (sha256 cache-file)] (let [sha (sha256 cache-file)]
@ -214,9 +214,23 @@
(un-tgz cache-file ddir (un-tgz cache-file ddir
false)) false))
(.delete cache-file)) (.delete cache-file))
(make-executable ddir [(:artifact/executable artifact)] false) (make-executable ddir [exe-file-name] false)
(warn (format "Successfully installed pod %s (%s)" qsym version)) (warn (format "Successfully installed pod %s" exe-file-name))
(io/file ddir (:artifact/executable artifact))) (io/file ddir exe-file-name))
(io/file ddir (:artifact/executable artifact)))) artifacts)] (io/file ddir exe-file-name)))
artifacts)]
{:executable (.getAbsolutePath ^java.io.File (first execs)) {:executable (.getAbsolutePath ^java.io.File (first execs))
:options (:pod/options manifest)}))) :options options}))
(defn resolve [qsym version force?]
(when-not (string? version)
(throw (IllegalArgumentException. "Version must be provided for resolving from pod registry!")))
(when-let [manifest (pod-manifest qsym version force?)]
(let [cdir (cache-dir manifest)
ddir (data-dir manifest)
artifacts (match-artifacts manifest)
pod-options (:pod/options manifest)]
(install-pod-artifacts artifacts {:cache-dir cdir
:data-dir ddir
:force? force?
:pod/options pod-options}))))

View file

@ -41,17 +41,32 @@
(with-open [r (PushbackInputStream. (io/input-stream cache-file))] (with-open [r (PushbackInputStream. (io/input-stream cache-file))]
(impl/read r))))) (impl/read r)))))
(defn load-pod-metadata* [bb-edn-file pod-spec {:keys [:version :cache] :as opts}] (defn cache-pod-metadata! [metadata {:keys [:bb-edn-file :pod-name :pod-version]}]
(let [metadata (impl/load-pod-metadata pod-spec opts) (let [cache-file (metadata-cache-file bb-edn-file pod-name
cache-file (when (and metadata cache) {:version pod-version})]
(metadata-cache-file bb-edn-file pod-spec opts))]
(when cache-file (when cache-file
(io/make-parents cache-file) (io/make-parents cache-file)
(when (fs/writable? (fs/parent cache-file)) (when (fs/writable? (fs/parent cache-file))
(with-open [w (io/output-stream cache-file)] (with-open [w (io/output-stream cache-file)]
(impl/write w metadata)))) (impl/write w metadata))))))
(defn load-pod-metadata* [bb-edn-file pod-spec {:keys [:version :cache] :as opts}]
(let [metadata (impl/load-pod-metadata pod-spec opts)]
(when (and metadata cache)
(cache-pod-metadata! metadata {:bb-edn-file bb-edn-file
:pod-name pod-spec
:pod-version version}))
metadata)) metadata))
(defn pod-namespaces
[pod-name metadata opts]
(reduce
(fn [pod-namespaces ns]
(let [ns-sym (-> ns (get "name") impl/bytes->string symbol)]
(assoc pod-namespaces ns-sym {:pod-spec pod-name
:opts (assoc opts :metadata metadata)})))
{} (get metadata "namespaces")))
(defn load-pod-metadata (defn load-pod-metadata
([pod-spec opts] (load-pod-metadata nil pod-spec opts)) ([pod-spec opts] (load-pod-metadata nil pod-spec opts))
([bb-edn-file pod-spec {:keys [:cache] :as opts}] ([bb-edn-file pod-spec {:keys [:cache] :as opts}]
@ -62,12 +77,7 @@
opts))] opts))]
cached-metadata cached-metadata
(load-pod-metadata* bb-edn-file pod-spec opts))] (load-pod-metadata* bb-edn-file pod-spec opts))]
(reduce (pod-namespaces pod-spec metadata opts))))
(fn [pod-namespaces ns]
(let [ns-sym (-> ns (get "name") impl/bytes->string symbol)]
(assoc pod-namespaces ns-sym {:pod-spec pod-spec
:opts (assoc opts :metadata metadata)})))
{} (get metadata "namespaces")))))
(defn load-pod (defn load-pod
([ctx pod-spec] (load-pod ctx pod-spec nil)) ([ctx pod-spec] (load-pod ctx pod-spec nil))
@ -122,6 +132,30 @@
(sci/future (impl/processor pod)) (sci/future (impl/processor pod))
{:pod/id (:pod-id pod)}))) {:pod/id (:pod-id pod)})))
(defn load-pod-from-manifest
[manifest {:keys [:bb-edn-file]}]
(let [artifacts (resolver/match-artifacts manifest)
pod-name (:pod/name manifest)]
(when artifacts
(let [cdir (resolver/cache-dir manifest)
ddir (resolver/data-dir manifest)
pod (resolver/install-pod-artifacts
artifacts {:cache-dir cdir
:data-dir ddir
:pod/options (:pod/options manifest)})
metadata (impl/run-pod-for-metadata [(:executable pod)] nil)]
(let [pod-version (:pod/version manifest)
opts {:bb-edn-file bb-edn-file
:pod-name pod-name
:pod-version pod-version}]
(cache-pod-metadata! metadata opts)
;; TODO: Support local library pods too w/ a :path key here
(pod-namespaces pod-name metadata {:version pod-version}))))))
(defn pod-manifest-file
[manifest]
(resolver/pod-manifest-file (-> manifest :pod/name symbol) (:pod/version manifest)))
(defn unload-pod (defn unload-pod
([pod-id] (unload-pod pod-id {})) ([pod-id] (unload-pod pod-id {}))
([pod-id _opts] ([pod-id _opts]