From b3fbe7e12eb66255b5633ac874fe28827fe0de71 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Sat, 17 Oct 2020 21:13:21 +0200 Subject: [PATCH] [#601] Support clojure.java.io/Coercions --- src/babashka/impl/clojure/java/io.clj | 74 +++++++++++++++++++++++---- test/babashka/main_test.clj | 2 +- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/babashka/impl/clojure/java/io.clj b/src/babashka/impl/clojure/java/io.clj index 5c26164b..1bac8ea4 100644 --- a/src/babashka/impl/clojure/java/io.clj +++ b/src/babashka/impl/clojure/java/io.clj @@ -1,15 +1,67 @@ (ns babashka.impl.clojure.java.io {:no-doc true} - (:require [clojure.java.io :as io])) + (:require [clojure.java.io :as io] + [sci.core :as sci :refer [copy-var]] + [sci.impl.types :as types]) + (:import [java.io File FileInputStream])) + +;;;; datafy + +(defmulti as-file types/type-impl) + +(defmethod as-file :sci.impl.protocols/reified [x] + (let [methods (types/getMethods x)] + ((get methods 'as-file) x))) + +(defmethod as-file :default [x] + (io/as-file x)) + +(defmulti as-url types/type-impl) + +(defmethod as-file :sci.impl.protocols/reified [x] + (let [methods (types/getMethods x)] + ((get methods 'as-url) x))) + +(defmethod as-url :default [x] + (io/as-url x)) + +;; patch this impl with new impl of as-file +(defn ^String as-relative-path + "Take an as-file-able thing and return a string if it is + a relative path, else IllegalArgumentException." + {:added "1.2"} + [x] + (let [^File f (as-file x)] + (if (.isAbsolute f) + (throw (IllegalArgumentException. (str f " is not a relative path"))) + (.getPath f)))) + +;; patch this impl with new impl of as-file and as-relative-path +(defn ^java.io.File file + "Returns a java.io.File, passing each arg to as-file. Multiple-arg + versions treat the first argument as parent and subsequent args as + children relative to the parent." + {:added "1.2"} + ([arg] + (as-file arg)) + ([parent child] + (File. ^File (as-file parent) ^String (as-relative-path child))) + ([parent child & more] + (reduce file (file parent child) more))) + +(def io-ns (sci/create-ns 'clojure.java.io nil)) (def io-namespace - {'as-relative-path io/as-relative-path - 'as-url io/as-url - 'copy io/copy - 'delete-file io/delete-file - 'file io/file - 'input-stream io/input-stream - 'make-parents io/make-parents - 'output-stream io/output-stream - 'reader io/reader - 'writer io/writer}) + {'Coercions (sci/new-var 'Coercions {:methods #{'as-file 'as-url} + :ns io-ns}) + 'as-relative-path (copy-var as-relative-path io-ns) + 'as-file as-file + 'file (copy-var file io-ns) + 'as-url as-url + 'copy (copy-var io/copy io-ns) + 'delete-file (copy-var io/delete-file io-ns) + 'input-stream (copy-var io/input-stream io-ns) + 'make-parents (copy-var io/make-parents io-ns) + 'output-stream (copy-var io/output-stream io-ns) + 'reader (copy-var io/reader io-ns) + 'writer (copy-var io/writer io-ns)}) diff --git a/test/babashka/main_test.clj b/test/babashka/main_test.clj index 4ffb30bf..e8ff53ff 100644 --- a/test/babashka/main_test.clj +++ b/test/babashka/main_test.clj @@ -15,7 +15,7 @@ (println "===" (-> m :var meta :name)) (println)) -(defmethod clojure.test/report :end-test-var [m] +(defmethod clojure.test/report :end-test-var [_m] (let [{:keys [:fail :error]} @*report-counters*] (when (and (= "true" (System/getenv "BABASHKA_FAIL_FAST")) (or (pos? fail) (pos? error)))