Support reader_tags.clj(c) (#1481)

This commit is contained in:
Michiel Borkent 2023-02-03 21:21:56 +01:00 committed by GitHub
parent ca1e2d7769
commit a19d05b8da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 90 deletions

View file

@ -11,6 +11,7 @@ A preview of the next release can be installed from
- [#1473](https://github.com/babashka/babashka/issues/1473): make relative paths in bb.edn resolve relative to it ([@lispyclouds](https://github.com/lispyclouds)) - [#1473](https://github.com/babashka/babashka/issues/1473): make relative paths in bb.edn resolve relative to it ([@lispyclouds](https://github.com/lispyclouds))
- Compatibility with `clojure.tools.namespace.repl/refresh` and `clojure.java.classpath` - Compatibility with `clojure.tools.namespace.repl/refresh` and `clojure.java.classpath`
- Support reading tags from `data_readers.clj` and `data_readers.cljc`
## 1.1.172 (2023-01-23) ## 1.1.172 (2023-01-23)

View file

@ -92,7 +92,11 @@
args (concat args [(str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases)))]) args (concat args [(str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases)))])
bindings (cond-> bindings (cond->
{#'deps/*env* env {#'deps/*env* env
#'deps/*extra-env* extra-env} #'deps/*extra-env* extra-env
#'deps/*exit-fn* (fn
([_])
([_exit-code msg]
(throw (Exception. msg))))}
deps-root (assoc #'deps/*dir* (str deps-root))) deps-root (assoc #'deps/*dir* (str deps-root)))
cp (with-out-str (with-bindings bindings cp (with-out-str (with-bindings bindings
(apply deps/-main args))) (apply deps/-main args)))

View file

@ -56,6 +56,7 @@
[clojure.edn :as edn] [clojure.edn :as edn]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
[edamame.core :as edamame]
[hf.depstar.uberjar :as uberjar] [hf.depstar.uberjar :as uberjar]
[sci.addons :as addons] [sci.addons :as addons]
[sci.core :as sci] [sci.core :as sci]
@ -63,6 +64,7 @@
[sci.impl.copy-vars :as sci-copy-vars] [sci.impl.copy-vars :as sci-copy-vars]
[sci.impl.io :as sio] [sci.impl.io :as sio]
[sci.impl.namespaces :as sci-namespaces] [sci.impl.namespaces :as sci-namespaces]
[sci.impl.parser]
[sci.impl.types :as sci-types] [sci.impl.types :as sci-types]
[sci.impl.unrestrict :refer [*unrestricted*]] [sci.impl.unrestrict :refer [*unrestricted*]]
[sci.impl.vars :as vars]) [sci.impl.vars :as vars])
@ -234,8 +236,7 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
(clojure.repl/doc %1$s) (clojure.repl/doc %1$s)
true)" arg))) true)" arg)))
[nil 0] [nil 0]
[nil 1])) [nil 1])))
,)
(defn print-run-help [] (defn print-run-help []
(println (str/trim " (println (str/trim "
@ -322,20 +323,20 @@ Use bb run --help to show this help output.
(def aliases (def aliases
(cond-> (cond->
'{str clojure.string '{str clojure.string
set clojure.set set clojure.set
tools.cli clojure.tools.cli tools.cli clojure.tools.cli
edn clojure.edn edn clojure.edn
wait babashka.wait wait babashka.wait
signal babashka.signal signal babashka.signal
shell clojure.java.shell shell clojure.java.shell
io clojure.java.io io clojure.java.io
json cheshire.core json cheshire.core
curl babashka.curl curl babashka.curl
fs babashka.fs fs babashka.fs
bencode bencode.core bencode bencode.core
deps babashka.deps deps babashka.deps
async clojure.core.async} async clojure.core.async}
features/xml? (assoc 'xml 'clojure.data.xml) features/xml? (assoc 'xml 'clojure.data.xml)
features/yaml? (assoc 'yaml 'clj-yaml.core) features/yaml? (assoc 'yaml 'clj-yaml.core)
features/jdbc? (assoc 'jdbc 'next.jdbc) features/jdbc? (assoc 'jdbc 'next.jdbc)
@ -357,74 +358,73 @@ Use bb run --help to show this help output.
(def namespaces (def namespaces
(cond-> (cond->
{'user {'*input* (reify {'user {'*input* (reify
sci-types/Eval sci-types/Eval
(eval [_ _ctx _bindings] (eval [_ _ctx _bindings]
(force @input-var)))} (force @input-var)))}
'clojure.core core-extras 'clojure.core core-extras
'clojure.tools.cli tools-cli-namespace 'clojure.tools.cli tools-cli-namespace
'clojure.java.shell shell-namespace 'clojure.java.shell shell-namespace
'babashka.core bbcore/core-namespace 'babashka.core bbcore/core-namespace
'babashka.nrepl.server nrepl-server-namespace 'babashka.nrepl.server nrepl-server-namespace
'babashka.wait wait-namespace 'babashka.wait wait-namespace
'babashka.signal signal-ns 'babashka.signal signal-ns
'clojure.java.io io-namespace 'clojure.java.io io-namespace
'cheshire.core cheshire-core-namespace 'cheshire.core cheshire-core-namespace
'clojure.data data/data-namespace 'clojure.data data/data-namespace
'clojure.instant instant/instant-namespace 'clojure.instant instant/instant-namespace
'clojure.stacktrace stacktrace-namespace 'clojure.stacktrace stacktrace-namespace
'clojure.zip zip-namespace 'clojure.zip zip-namespace
'clojure.main {:obj clojure-main-ns 'clojure.main {:obj clojure-main-ns
'demunge (sci/copy-var demunge clojure-main-ns) 'demunge (sci/copy-var demunge clojure-main-ns)
'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns) 'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns)
'repl (sci/new-var 'repl 'repl (sci/new-var 'repl
(fn [& opts] (fn [& opts]
(let [opts (apply hash-map opts)] (let [opts (apply hash-map opts)]
(repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns}) (repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns})
'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns) 'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)
'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns) 'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns)
'main main-var} 'main main-var}
'clojure.test t/clojure-test-namespace 'clojure.test t/clojure-test-namespace
'clojure.math math-namespace 'clojure.math math-namespace
'babashka.classpath classpath-namespace 'babashka.classpath classpath-namespace
'babashka.classes classes-namespace 'babashka.classes classes-namespace
'clojure.pprint pprint-namespace 'clojure.pprint pprint-namespace
'babashka.curl curl-namespace 'babashka.curl curl-namespace
'babashka.fs fs-namespace 'babashka.fs fs-namespace
'babashka.pods pods/pods-namespace 'babashka.pods pods/pods-namespace
'bencode.core bencode-namespace 'bencode.core bencode-namespace
'clojure.java.browse browse-namespace 'clojure.java.browse browse-namespace
'clojure.datafy datafy-namespace 'clojure.datafy datafy-namespace
'clojure.core.protocols protocols-namespace 'clojure.core.protocols protocols-namespace
'babashka.process process-namespace 'babashka.process process-namespace
'clojure.core.server clojure-core-server-namespace 'clojure.core.server clojure-core-server-namespace
'babashka.deps deps-namespace 'babashka.deps deps-namespace
'babashka.tasks tasks-namespace 'babashka.tasks tasks-namespace
'clojure.tools.reader.edn edn-namespace 'clojure.tools.reader.edn edn-namespace
'clojure.tools.reader.reader-types reader-types-namespace 'clojure.tools.reader.reader-types reader-types-namespace
'clojure.tools.reader reader-namespace 'clojure.tools.reader reader-namespace
'clojure.core.async async-namespace 'clojure.core.async async-namespace
'clojure.core.async.impl.protocols async-protocols-namespace 'clojure.core.async.impl.protocols async-protocols-namespace
'rewrite-clj.node rewrite/node-namespace 'rewrite-clj.node rewrite/node-namespace
'rewrite-clj.paredit rewrite/paredit-namespace 'rewrite-clj.paredit rewrite/paredit-namespace
'rewrite-clj.parser rewrite/parser-namespace 'rewrite-clj.parser rewrite/parser-namespace
'rewrite-clj.zip rewrite/zip-namespace 'rewrite-clj.zip rewrite/zip-namespace
'rewrite-clj.zip.subedit rewrite/subedit-namespace 'rewrite-clj.zip.subedit rewrite/subedit-namespace
'clojure.core.rrb-vector (if features/rrb-vector? 'clojure.core.rrb-vector (if features/rrb-vector?
@(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace) @(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace)
{'catvec (sci/copy-var catvec {'catvec (sci/copy-var catvec
(sci/create-ns 'clojure.core.rrb-vector))}) (sci/create-ns 'clojure.core.rrb-vector))})
'edamame.core edamame-namespace 'edamame.core edamame-namespace
'sci.core {'format-stacktrace (sci/copy-var sci/format-stacktrace sci-ns) 'sci.core {'format-stacktrace (sci/copy-var sci/format-stacktrace sci-ns)
'stacktrace (sci/copy-var sci/stacktrace sci-ns) 'stacktrace (sci/copy-var sci/stacktrace sci-ns)
;; 'eval-string (sci/copy-var sci/eval-string sci-ns) ;; 'eval-string (sci/copy-var sci/eval-string sci-ns)
;; 'eval-string* (sci/copy-var sci/eval-string* sci-ns) ;; 'eval-string* (sci/copy-var sci/eval-string* sci-ns)
;; 'init (sci/copy-var sci/init sci-ns) ;; 'init (sci/copy-var sci/init sci-ns)
;; 'fork (sci/copy-var sci/fork sci-ns) ;; 'fork (sci/copy-var sci/fork sci-ns)
} }
'babashka.cli cli/cli-namespace 'babashka.cli cli/cli-namespace
'babashka.http-client http-client-namespace 'babashka.http-client http-client-namespace}
}
features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace) features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace)
'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace) 'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace)
'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace)) 'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
@ -461,7 +461,7 @@ Use bb run --help to show this help output.
@(resolve 'babashka.impl.clojure.test.check/test-check-namespace) @(resolve 'babashka.impl.clojure.test.check/test-check-namespace)
;; it's better to load this from source by adding the clojure.test.check dependency ;; it's better to load this from source by adding the clojure.test.check dependency
#_#_'clojure.test.check.clojure-test #_#_'clojure.test.check.clojure-test
@(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace)) @(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace))
features/spec-alpha? (-> (assoc ;; spec features/spec-alpha? (-> (assoc ;; spec
'clojure.spec.alpha @(resolve 'babashka.impl.spec/spec-namespace) 'clojure.spec.alpha @(resolve 'babashka.impl.spec/spec-namespace)
'clojure.spec.gen.alpha @(resolve 'babashka.impl.spec/gen-namespace) 'clojure.spec.gen.alpha @(resolve 'babashka.impl.spec/gen-namespace)
@ -650,13 +650,13 @@ Use bb run --help to show this help output.
opts-map (assoc opts-map :prn true)] opts-map (assoc opts-map :prn true)]
(recur (next options) (recur (next options)
(update opts-map :expressions (fnil conj []) (first options)))) (update opts-map :expressions (fnil conj []) (first options))))
("--main", "-m",) ("--main", "-m")
(let [options (next options)] (let [options (next options)]
(assoc opts-map :main (first options) (assoc opts-map :main (first options)
:command-line-args (if (= "--" (second options)) :command-line-args (if (= "--" (second options))
(nthrest options 2) (nthrest options 2)
(rest options)))) (rest options))))
("--exec", "-x",) ("--exec", "-x")
(let [options (next options)] (let [options (next options)]
(assoc opts-map :exec (first options) (assoc opts-map :exec (first options)
:command-line-args (if (= "--" (second options)) :command-line-args (if (= "--" (second options))
@ -780,6 +780,39 @@ Use bb run --help to show this help output.
env-os-name-present? (not= env-os-name sys-os-name) env-os-name-present? (not= env-os-name sys-os-name)
env-os-arch-present? (not= env-os-arch sys-os-arch)))) env-os-arch-present? (not= env-os-arch sys-os-arch))))
(def seen-urls (atom nil))
(defn read-data-readers [url]
(edamame/parse-string (slurp url)
{:read-cond :allow
:features #{:bb :clj}
:eof nil}))
(defn readers-fn
"Lazy reading of data reader functions"
[ctx t]
(or (@core/data-readers t)
(default-data-readers t)
(when (simple-symbol? t)
(when-let [the-var (sci/resolve ctx t)]
(some-> the-var meta :sci.impl.record/map-constructor)))
(when-let [f @sci.impl.parser/default-data-reader-fn]
(fn [form]
(f t form)))
(let [;; urls is a vector for equality check
urls (vec (.getURLs ^java.net.URLClassLoader @cp/the-url-loader))
parsed-resources (or (get @seen-urls urls)
(let [^java.net.URLClassLoader cl @cp/the-url-loader
resources (concat (enumeration-seq (.getResources cl "data_readers.clj"))
(enumeration-seq (.getResources cl "data_readers.cljc")))
parsed-resources (apply merge (map read-data-readers resources))
_ (swap! seen-urls assoc urls parsed-resources)]
parsed-resources))]
(when-let [var-sym (get parsed-resources t)]
(when-let [the-var (sci/resolve ctx var-sym)]
(sci/eval-form ctx (list 'clojure.core/var-set core/data-readers (list 'quote (assoc @core/data-readers t the-var))))
the-var)))))
(defn exec [cli-opts] (defn exec [cli-opts]
(with-bindings {#'*unrestricted* true (with-bindings {#'*unrestricted* true
clojure.lang.Compiler/LOADER @cp/the-url-loader} clojure.lang.Compiler/LOADER @cp/the-url-loader}
@ -841,10 +874,10 @@ Use bb run --help to show this help output.
(let [loader @cp/the-url-loader] (let [loader @cp/the-url-loader]
(or (or
(when ;; ignore built-in namespaces when uberscripting, unless with :reload (when ;; ignore built-in namespaces when uberscripting, unless with :reload
(and uberscript (and uberscript
(not reload) (not reload)
(or (contains? namespaces namespace) (or (contains? namespaces namespace)
(contains? sci-namespaces/namespaces namespace))) (contains? sci-namespaces/namespaces namespace)))
"") "")
;; pod namespaces go before namespaces from source, ;; pod namespaces go before namespaces from source,
;; unless reload is used ;; unless reload is used
@ -899,13 +932,14 @@ Use bb run --help to show this help output.
:uberscript uberscript :uberscript uberscript
;; :readers core/data-readers ;; :readers core/data-readers
:reify-fn reify-fn :reify-fn reify-fn
:proxy-fn proxy-fn} :proxy-fn proxy-fn
:readers #(readers-fn (common/ctx) %)}
opts (addons/future opts) opts (addons/future opts)
sci-ctx (sci/init opts) sci-ctx (sci/init opts)
_ (ctx-store/reset-ctx! sci-ctx) _ (ctx-store/reset-ctx! sci-ctx)
_ (when-let [pods (:pods @common/bb-edn)] _ (when-let [pods (:pods @common/bb-edn)]
(when-let [pod-metadata (pods/load-pods-metadata (when-let [pod-metadata (pods/load-pods-metadata
pods {:download-only (download-only?)})] pods {:download-only (download-only?)})]
(vreset! pod-namespaces pod-metadata))) (vreset! pod-namespaces pod-metadata)))
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim)) preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
[expressions exit-code] [expressions exit-code]

View file

@ -0,0 +1 @@
{r/reverse reader/reversev}

View file

@ -0,0 +1 @@
{r/distinct reader/distinctv}

View file

@ -0,0 +1,7 @@
(ns reader)
(defn reversev [data]
(vec (reverse data)))
(defn distinctv [data]
(vec (distinct data)))

View file

@ -82,3 +82,8 @@
(.getResourceAsStream (clojure.lang.RT/baseLoader) \"foo.clj\") (.getResourceAsStream (clojure.lang.RT/baseLoader) \"foo.clj\")
(.getResources (clojure.lang.RT/baseLoader) \"foo.clj\")])")] (.getResources (clojure.lang.RT/baseLoader) \"foo.clj\")])")]
(is (= [true true true] (edn/read-string results))))) (is (= [true true true] (edn/read-string results)))))
(deftest reader-tag-test
(is (= [[3 2 1] [1 2 3]]
(bb nil "--classpath" "test-resources/babashka/src_for_classpath_test"
"(require 'reader) [#r/reverse [1 2 3] #r/distinct [1 1 2 3]]"))))