diff --git a/.gitignore b/.gitignore index 4d308908..1b98c17b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,6 @@ pom.xml.asc !java/src/babashka/impl/LockFix.class !test-resources/babashka/src_for_classpath_test/foo.jar .cpcache -reflection.json +*reflection.json /tmp /reports diff --git a/README.md b/README.md index 5ac8d5c7..63ba3c0c 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,7 @@ enumerated explicitly. - [`clojure.tools.cli`](https://github.com/clojure/tools.cli) aliased as `tools.cli` - [`clojure.data.csv`](https://github.com/clojure/data.csv) aliased as `csv` - [`cheshire.core`](https://github.com/dakrone/cheshire) aliased as `json` +- [`cognitect.transit`](https://github.com/cognitect/transit-clj) aliased as `transit` A selection of java classes are available, see `babashka/impl/classes.clj`. diff --git a/doc/dev.md b/doc/dev.md index c97f7f8f..4fefb30b 100644 --- a/doc/dev.md +++ b/doc/dev.md @@ -53,6 +53,9 @@ Then run: Keep notes here about how adding libraries and classes to Babashka affects the binary size. +2020/03/20 Added transit write, writer, read, reader +42004796 - 41025212 = 980kb added (305kb zipped). + 2020/03/19 Added java.lang.NumberFormatException, java.lang.RuntimeException, java.util.MissingResourceException and java.util.Properties to support [cprop](https://github.com/tolitius/cprop/). diff --git a/project.clj b/project.clj index d28931e5..becb1397 100644 --- a/project.clj +++ b/project.clj @@ -18,7 +18,8 @@ [org.clojure/tools.cli "0.4.2"] [org.clojure/data.csv "1.0.0"] [cheshire "5.10.0"] - [fipp "0.6.22"]] + [fipp "0.6.22"] + [com.cognitect/transit-clj "1.0.324"]] :profiles {:test {:dependencies [[clj-commons/conch "0.9.2"] [com.clojure-goes-fast/clj-async-profiler "0.4.0"]]} :uberjar {:global-vars {*assert* false} diff --git a/src/babashka/impl/classes.clj b/src/babashka/impl/classes.clj index 25a057e4..4a4e404a 100644 --- a/src/babashka/impl/classes.clj +++ b/src/babashka/impl/classes.clj @@ -198,7 +198,9 @@ (instance? java.io.ByteArrayOutputStream v) java.io.ByteArrayOutputStream (instance? java.security.MessageDigest v) - java.security.MessageDigest))))) + java.security.MessageDigest + (instance? java.io.InputStream v) + java.io.InputStream))))) (def class-map (gen-class-map)) diff --git a/src/babashka/impl/transit.clj b/src/babashka/impl/transit.clj new file mode 100644 index 00000000..e7c84311 --- /dev/null +++ b/src/babashka/impl/transit.clj @@ -0,0 +1,12 @@ +(ns babashka.impl.transit + (:require [cognitect.transit :as transit] + [sci.impl.namespaces :refer [copy-var]] + [sci.impl.vars :as vars])) + +(def tns (vars/->SciNamespace 'cognitect.transit nil)) + +(def transit-namespace + {'write (copy-var transit/write tns) + 'writer (copy-var transit/writer tns) + 'read (copy-var transit/read tns) + 'reader (copy-var transit/reader tns)}) diff --git a/src/babashka/main.clj b/src/babashka/main.clj index a224eed3..3f9d1d37 100644 --- a/src/babashka/main.clj +++ b/src/babashka/main.clj @@ -19,6 +19,7 @@ [babashka.impl.socket-repl :as socket-repl] [babashka.impl.test :as t] [babashka.impl.tools.cli :refer [tools-cli-namespace]] + [babashka.impl.transit :refer [transit-namespace]] [babashka.wait :as wait] [clojure.edn :as edn] [clojure.java.io :as io] @@ -26,11 +27,11 @@ [clojure.string :as str] [sci.addons :as addons] [sci.core :as sci] - [sci.impl.interpreter :refer [eval-string* eval-form]] + [sci.impl.interpreter :refer [eval-string*]] [sci.impl.opts :as sci-opts] + [sci.impl.types :as sci-types] [sci.impl.unrestrict :refer [*unrestricted*]] - [sci.impl.vars :as vars] - [sci.impl.types :as sci-types]) + [sci.impl.vars :as vars]) (:gen-class)) (binding [*unrestricted* true] @@ -234,7 +235,8 @@ Everything after that is bound to *command-line-args*.")) async clojure.core.async csv clojure.data.csv json cheshire.core - curl babashka.curl}) + curl babashka.curl + transit cognitect.transit}) (def cp-state (atom nil)) @@ -265,7 +267,8 @@ Everything after that is bound to *command-line-args*.")) 'clojure.test t/clojure-test-namespace 'babashka.classpath {'add-classpath add-classpath*} 'clojure.pprint pprint-namespace - 'babashka.curl curl-namespace}) + 'babashka.curl curl-namespace + 'cognitect.transit transit-namespace}) (def bindings {'java.lang.System/exit exit ;; override exit, so we have more control diff --git a/test-resources/babashka/transit.clj b/test-resources/babashka/transit.clj new file mode 100644 index 00000000..3d3bda6a --- /dev/null +++ b/test-resources/babashka/transit.clj @@ -0,0 +1,18 @@ +(require '[cognitect.transit :as transit]) +(import [java.io ByteArrayInputStream ByteArrayOutputStream]) + +;; Write data to a stream +(def out (ByteArrayOutputStream. 4096)) +(def writer (transit/writer out :json)) +(transit/write writer "foo") +(transit/write writer {:a [1 2]}) + +;; Take a peek at the JSON +(.toString out) +;; => "{\"~#'\":\"foo\"} [\"^ \",\"~:a\",[1,2]]" + +;; Read data from a stream +(def in (ByteArrayInputStream. (.toByteArray out))) +(def reader (transit/reader in :json)) +(prn (transit/read reader)) ;; => "foo" +(prn (transit/read reader)) ;; => {:a [1 2]} diff --git a/test/babashka/main_test.clj b/test/babashka/main_test.clj index c4a90a47..ac98ab9a 100644 --- a/test/babashka/main_test.clj +++ b/test/babashka/main_test.clj @@ -29,7 +29,7 @@ (deftest main-test (testing "-io behaves as identity" - (= "foo\nbar\n" (test-utils/bb "foo\nbar\n" "-io" "*input*"))) + (is (= "foo\nbar\n" (test-utils/bb "foo\nbar\n" "-io" "*input*")))) (testing "if and when" (is (= 1 (bb 0 '(if (zero? *input*) 1 2)))) (is (= 2 (bb 1 '(if (zero? *input*) 1 2)))) @@ -355,6 +355,9 @@ (is (= :clojure.string/foo (bb nil "(ns foo (:require [clojure.string :as str])) (read-string \"::str/foo\")"))))) +(deftest available-stream-test + (is (= 0 (bb nil "(.available System/in)")))) + ;;;; Scratch (comment diff --git a/test/babashka/transit_test.clj b/test/babashka/transit_test.clj new file mode 100644 index 00000000..86523771 --- /dev/null +++ b/test/babashka/transit_test.clj @@ -0,0 +1,13 @@ +(ns babashka.transit-test + (:require + [babashka.test-utils :as test-utils] + [clojure.java.io :as io] + [clojure.test :as t :refer [deftest is]])) + +(defn bb [& args] + (apply test-utils/bb nil (map str args))) + +(deftest transit-test + (is (= "\"foo\"\n{:a [1 2]}\n" + (bb (format "(load-file \"%s\")" + (.getPath (io/file "test-resources" "babashka" "transit.clj")))))))