From 1539ba0cb528476611473792e4687f61ad3905b5 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Fri, 25 Dec 2020 21:25:04 +0100 Subject: [PATCH] wip --- deps.edn | 2 +- src/babashka/pods/impl.clj | 2 +- src/babashka/pods/impl/resolver.clj | 110 +++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/deps.edn b/deps.edn index aab6415..ec186b0 100644 --- a/deps.edn +++ b/deps.edn @@ -5,7 +5,7 @@ {:sci {:extra-deps {borkdude/sci {:git/url "https://github.com/borkdude/sci" - :sha "a7f8d05f08ab150621c2403dacdd57c47ea09ff4"}}} + :sha "5aa9031eb3692a2207106076088fcab7347c2299"}}} :test {:extra-deps {cognitect/test-runner diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index d0cdcd9..be55c4b 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -280,7 +280,7 @@ ([pod-spec] (load-pod pod-spec nil)) ([pod-spec {:keys [:remove-ns :resolve :transport]}] (let [pod-spec (cond (string? pod-spec) [pod-spec] - (qualified-symbol? pod-spec) (resolver/resolve qualified-symbol?) + (qualified-symbol? pod-spec) (resolver/resolve pod-spec) :else pod-spec) pb (ProcessBuilder. ^java.util.List pod-spec) socket? (identical? :socket transport) diff --git a/src/babashka/pods/impl/resolver.clj b/src/babashka/pods/impl/resolver.clj index 3a3b9c1..0725f5e 100644 --- a/src/babashka/pods/impl/resolver.clj +++ b/src/babashka/pods/impl/resolver.clj @@ -24,7 +24,7 @@ (apply println strs))) (defn match-artifacts [package] - (let [artifacts (:package/artifacts package)] + (let [artifacts (:pod/artifacts package)] (filter (fn [{os-name :os/name os-arch :os/arch}] (let [os-arch (normalize-arch os-arch)] @@ -90,22 +90,114 @@ (io/copy is dest)) (when verbose? (warn "Download complete.")))) -(def pod-data-dir +(def pod-meta-dir ;; wrapped in delay for GraalVM native-image (delay (io/file (System/getProperty "user.home") - ".babashka" "pods" "data"))) + ".babashka" "pods" "meta"))) (defn pod-meta ([qsym] (pod-meta qsym nil)) ([qsym version] (let [version (or version "latest") - f (io/file @pod-data-dir qsym (str version ".edn"))] - (if (.exists f) f + f (io/file @pod-meta-dir (str qsym) (str version ".edn"))] + (if (.exists f) (edn/read-string (slurp f)) ;; TODO: download from github? - )))) + (case qsym + 'org.babashka/pod-babashka-postgresql + '{:pod/name org.babashka/pod-babashka-postgresql + :pod/description "" + :pod/version "0.0.1" + :pod/license "" + :pod/artifacts + [{:os/name "Mac.*" + :os/arch "x86_64" + :artifact/url "https://github.com/babashka/babashka-sql-pods/releases/download/v0.0.1/pod-babashka-postgresql-0.0.1-macos-amd64.zip" + #_#_:artifact/hash "sha256:sfEkDVDKf/owDyW+hCj22N5eNgFNYk62fxpvKexwva0=" + ;; TODO: should this be a command vector rather? + :artifact/executable "pod-babashka-postgresql" + ;; or rather, give optional args here. + } + {:os/name "Linux.*" + :os/arch "amd64" + :artifact/url "https://github.com/babashka/babashka-sql-pods/releases/download/v0.0.1/pod-babashka-postgresql-0.0.1-linux-amd64.zip" + #_#_:artifact/hash "sha256:NlCox8UXMq/y0dBGTjYkDSJEcJ8UZrkBQsK/OyRIQ6c=" + :artifact/executable "pod-babashka-postgresql"} + #_{:os/name "Windows.*" + :os/arch "amd64" + :artifact/url "https://github.com/borkdude/babashka/releases/download/v0.2.2/babashka-0.2.2-windows-amd64.zip" + :artifact/hash "sha256:AAMks+jCr5JbeU4jHwaGxPHG22jyfvB5lzVEaRTpcHE=" + :artifact/executable "bb.exe"}]}))))) +(defn cache-dir + ^java.io.File + [{pod-name :pod/name + pod-version :pod/version}] + (io/file (or + (System/getenv "XDG_CACHE_HOME") + (System/getProperty "user.home")) + ".babashka" + "pods" + "repository" + (str pod-name) + pod-version)) +(defn data-dir + ^java.io.File + [{pod-name :pod/name + pod-version :pod/version}] + (io/file (or + (System/getenv "XDG_DATA_HOME") + (System/getProperty "user.home")) + ".babashka" + "pods" + "repository" + (str pod-name) + pod-version)) -(defn resolve [qsym] ;; TODO: version - (if-let [m (pod-meta qsym)] - )) +(defn sha256 [file] + (let [buf (byte-array 8192) + digest (java.security.MessageDigest/getInstance "SHA-256")] + (with-open [bis (io/input-stream (io/file file))] + (loop [] + (let [count (.read bis buf)] + (when (pos? count) + (.update digest buf 0 count) + (recur))))) + (-> (.encode (java.util.Base64/getEncoder) + (.digest digest)) + (String. "UTF-8")))) + +(defn resolve [qsym] + (when-let [package (pod-meta qsym)] + (let [artifacts (match-artifacts package) + cdir (cache-dir package) + ddir (data-dir package) + execs (mapv (fn [artifact] + (let [url (:artifact/url artifact) + file-name (last (str/split url #"/")) + cache-file (io/file cdir file-name) + executable (io/file ddir (:artifact/executable artifact))] + (if (.exists executable) + nil #_(when verbose? + (warn "Package" (pkg-name package) "already installed")) + (do (download url cache-file false) + (when-let [expected-sha (:artifact/hash artifact)] + (let [sha (sha256 cache-file)] + (when-not (= (str/replace expected-sha #"^sha256:" "") + sha) + (throw (ex-info (str "Wrong SHA-256 for file" (str cache-file)) + {:sha sha + :expected-sha expected-sha}))))) + (let [filename (.getName cache-file)] + (cond (str/ends-with? filename ".zip") + (unzip {:zip-file cache-file + :destination-dir ddir + :verbose false}) + (or (str/ends-with? filename ".tgz") + (str/ends-with? filename ".tar.gz")) + (un-tgz cache-file ddir + false))) + (make-executable ddir [(:artifact/executable artifact)] false) + (io/file ddir (:artifact/executable artifact))) ) + (io/file ddir (:artifact/executable artifact)))) artifacts)] + [(.getAbsolutePath ^java.io.File (first execs))])))