From e1ab6a00e5d264597b0f1fec365b837f940a131d Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Thu, 15 Oct 2020 11:27:23 +0200 Subject: [PATCH] [#21] Support transit+json --- deps.edn | 5 ++-- script/test | 9 +++++++ src/babashka/pods/impl.clj | 26 +++++++++++++++++--- test-pod/pod/test_pod.clj | 43 +++++++++++++++++++++++---------- test-resources/test_program.clj | 3 ++- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/deps.edn b/deps.edn index 60a9e5e..aab6415 100644 --- a/deps.edn +++ b/deps.edn @@ -1,5 +1,6 @@ {:deps {nrepl/bencode {:mvn/version "1.1.0"} - cheshire {:mvn/version "5.10.0"}} + cheshire/cheshire {:mvn/version "5.10.0"} + com.cognitect/transit-clj {:mvn/version "1.0.324"}} :aliases {:sci {:extra-deps @@ -7,7 +8,7 @@ :sha "a7f8d05f08ab150621c2403dacdd57c47ea09ff4"}}} :test {:extra-deps - {test-runner + {cognitect/test-runner {:git/url "https://github.com/cognitect-labs/test-runner" :sha "cb96e80f6f3d3b307c59cbeb49bb0dcb3a2a780b"}} :extra-paths ["test"] diff --git a/script/test b/script/test index bf2bad3..aec1da0 100755 --- a/script/test +++ b/script/test @@ -5,17 +5,26 @@ export BABASHKA_POD_TEST_SOCKET # format = edn BABASHKA_POD_TEST_FORMAT=edn +echo "Testing edn" clojure -A:test -n babashka.pods.jvm-test clojure -A:sci:test -n babashka.pods.sci-test # format = json BABASHKA_POD_TEST_FORMAT=json +echo "Testing json" +clojure -A:test -n babashka.pods.jvm-test +clojure -A:sci:test -n babashka.pods.sci-test + +# format = json +BABASHKA_POD_TEST_FORMAT="transit+json" +echo "Testing transit" clojure -A:test -n babashka.pods.jvm-test clojure -A:sci:test -n babashka.pods.sci-test # socket = true unset BABASHKA_POD_TEST_FORMAT BABASHKA_POD_TEST_SOCKET=true +echo "Testing socket" clojure -A:test -n babashka.pods.jvm-test clojure -A:sci:test -n babashka.pods.sci-test diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index dd85394..3391281 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -5,7 +5,8 @@ [cheshire.core :as cheshire] [clojure.edn :as edn] [clojure.java.io :as io] - [clojure.string :as str]) + [clojure.string :as str] + [cognitect.transit :as transit]) (:import [java.io PushbackInputStream] [java.net Socket])) @@ -37,6 +38,17 @@ (defn next-id [] (str (java.util.UUID/randomUUID))) +(defn transit-json-read [^String s] + (with-open [bais (java.io.ByteArrayInputStream. (.getBytes s "UTF-8"))] + (let [r (transit/reader bais :json)] + (transit/read r)))) + +(defn transit-json-write [^String s] + (with-open [baos (java.io.ByteArrayOutputStream. 4096)] + (let [w (transit/writer baos :json)] + (transit/write w s) + (str baos)))) + (defn invoke [pod pod-var args opts] (let [handlers (:handlers opts) stream (:stdin pod) @@ -44,7 +56,8 @@ chans (:chans pod) write-fn (case format :edn pr-str - :json cheshire/generate-string) + :json cheshire/generate-string + :transit+json transit-json-write) id (next-id) chan (if handlers handlers (promise)) @@ -95,7 +108,14 @@ (catch Exception e (binding [*out* *err*] (println "Cannot read JSON: " (pr-str s)) - (throw e))))))] + (throw e))))) + :transit+json + (fn [s] + (try (transit-json-read s) + (catch Exception e + (binding [*out* *err*] + (println "Cannot read Transit JSON: " (pr-str s)) + (throw e))))))] (try (loop [] (let [reply (try (read stdout) diff --git a/test-pod/pod/test_pod.clj b/test-pod/pod/test_pod.clj index b813444..989a5dd 100644 --- a/test-pod/pod/test_pod.clj +++ b/test-pod/pod/test_pod.clj @@ -3,7 +3,8 @@ (:require [bencode.core :as bencode] [cheshire.core :as cheshire] [clojure.edn :as edn] - [clojure.java.io :as io]) + [clojure.java.io :as io] + [cognitect.transit :as transit]) (:import [java.io PushbackInputStream] [java.net ServerSocket]) (:gen-class)) @@ -33,16 +34,29 @@ (format "(def x%s (inc x%s))" i (dec i)) "(def x0 0)")})) +(defn transit-json-read [^String s] + (with-open [bais (java.io.ByteArrayInputStream. (.getBytes s "UTF-8"))] + (let [r (transit/reader bais :json)] + (transit/read r)))) + +(defn transit-json-write [^String s] + (with-open [baos (java.io.ByteArrayOutputStream. 4096)] + (let [w (transit/writer baos :json)] + (transit/write w s) + (str baos)))) + (defn run-pod [cli-args] - (let [format (if (contains? cli-args "--json") - :json - :edn) - write-fn (if (identical? :json format) - cheshire/generate-string - pr-str) - read-fn (if (identical? :json format) - #(cheshire/parse-string % true) - edn/read-string) + (let [format (cond (contains? cli-args "--json") :json + (contains? cli-args "--transit+json") :transit+json + :else :edn) + write-fn (case format + :edn pr-str + :json cheshire/generate-string + :transit+json transit-json-write) + read-fn (case format + :edn edn/read-string + :json #(cheshire/parse-string % true) + :transit+json transit-json-read) socket (= "true" (System/getenv "BABASHKA_POD_SOCKET")) [in out] (if socket (let [server (ServerSocket. 0) @@ -70,9 +84,10 @@ op (keyword op)] (case op :describe - (do (write out {"format" (if (= format :json) - "json" - "edn") + (do (write out {"format" (case format + :edn "edn" + :json "json" + :transit+json "transit+json") "readers" {"my/tag" "identity" ;; NOTE: this function is defined later, ;; which should be supported @@ -209,5 +224,7 @@ (prn e)))))) (defn -main [& args] + #_(binding [*out* *err*] + (prn :args args)) (when (= "true" (System/getenv "BABASHKA_POD")) (run-pod (set args)))) diff --git a/test-resources/test_program.clj b/test-resources/test_program.clj index 938edd7..5f458d8 100644 --- a/test-resources/test_program.clj +++ b/test-resources/test_program.clj @@ -6,7 +6,8 @@ (def socket (System/getenv "BABASHKA_POD_TEST_SOCKET")) (def pod-id (:pod/id (pods/load-pod (cond-> ["clojure" "-A:test-pod"] - (= "json" fmt) (conj "--json")) + (= "json" fmt) (conj "--json") + (= "transit+json" fmt) (conj "--transit+json")) {:socket (boolean socket)}))) (require '[pod.test-pod :as pod])