|
8 | 8 |
|
9 | 9 | (defn update-types-recur [ctx tp-sym sym]
|
10 | 10 | (swap! ctx update-in [:tps tp-sym] (fn [x] (conj (or x #{}) sym)))
|
11 |
| - (doseq [tp-sym' (get-in @ctx [:syms tp-sym :isa])] |
| 11 | + (doseq [tp-sym' (get-in @ctx [:symbols tp-sym :isa])] |
12 | 12 | (update-types-recur ctx tp-sym' sym)))
|
13 | 13 |
|
14 | 14 | (declare read-ns)
|
15 | 15 |
|
16 | 16 | (defn pretty-path [pth]
|
17 | 17 | (->> pth
|
18 | 18 | (mapv (fn [x] (if (keyword? x) (subs (str x) 1) (str x))))
|
19 |
| - (str/join "." ))) |
| 19 | + (str/join "->" ))) |
20 | 20 |
|
21 |
| -(defn load-ns [ctx nmsps] |
| 21 | +(defn eval-resource [ctx ns-str ns-name nmsps k resource] |
| 22 | + (-> (clojure.walk/postwalk |
| 23 | + (fn [x] |
| 24 | + (if (symbol? x) |
| 25 | + (if (namespace x) |
| 26 | + (do (when-not (get-in @ctx [:symbols x]) |
| 27 | + (swap! ctx update :errors conj (format "Could not resolve symbol '%s in %s/%s" x ns-name k))) |
| 28 | + x) |
| 29 | + (do (when-not (get nmsps x) |
| 30 | + (swap! ctx update :errors conj (format "Could not resolve local symbol '%s in %s/%s" x ns-name k))) |
| 31 | + (symbol ns-str (name x)))) |
| 32 | + x)) |
| 33 | + resource) |
| 34 | + (assoc ;;TODO :zen/ns ns-name |
| 35 | + :zen/name (symbol (name ns-name) (name k))))) |
| 36 | + |
| 37 | +(defn load-tag [ctx nmsps k v] |
| 38 | + (let [ns-name (get nmsps 'ns) |
| 39 | + ns-str (name ns-name) |
| 40 | + res (eval-resource ctx ns-str ns-name nmsps k v)] |
| 41 | + (swap! ctx (fn [ctx] (update-in ctx [:tags k] (fn [x] (when x (println "WARN: reload tag" (:zen/name res))) res)))))) |
| 42 | + |
| 43 | + |
| 44 | +(defn load-symbol [ctx nmsps k v] |
22 | 45 | (let [ns-name (get nmsps 'ns)
|
23 |
| - ns-str (name ns-name)] |
| 46 | + ns-str (name ns-name) |
| 47 | + sym (symbol ns-str (name k)) |
| 48 | + res (eval-resource ctx ns-str ns-name nmsps k v)] |
| 49 | + (swap! ctx (fn [ctx] (update-in ctx [:symbols sym] (fn [x] (when x (println "WARN: reload" (:zen/name res))) res)))) |
| 50 | + (doseq [tg (:zen/tags res)] |
| 51 | + (swap! ctx update-in [:tags-index tg] (fn [x] (conj (or x #{}) sym)))) |
| 52 | + res)) |
| 53 | + |
| 54 | +(defn validate-resource [ctx res] |
| 55 | + (let [tags (get res :zen/tags) |
| 56 | + tags-reg (get @ctx :tags) |
| 57 | + schemas (->> tags |
| 58 | + (mapv (fn [tag] (get-in tags-reg [tag :schema]))) |
| 59 | + (filter identity) |
| 60 | + (into #{}))] |
| 61 | + (when-not (empty? schemas) |
| 62 | + (println "validate with" schemas) |
| 63 | + (let [{errs :errors} (zen.validation/validate ctx schemas res)] |
| 64 | + (when-not (empty? errs) |
| 65 | + (doseq [err errs] |
| 66 | + (swap! ctx update :errors |
| 67 | + conj (format "Validation: %s '%s' in %s by %s" |
| 68 | + (get res :zen/name) |
| 69 | + (:message err) |
| 70 | + (pretty-path (:path err)) |
| 71 | + (pretty-path (:schema err)))))))))) |
| 72 | + |
| 73 | +(defn load-ns [ctx nmsps] |
| 74 | + (let [ns-name (get nmsps 'ns)] |
24 | 75 | (when-not (get-in ctx [:ns ns-name])
|
25 | 76 | (swap! ctx (fn [ctx] (assoc-in ctx [:ns ns-name] nmsps)))
|
26 | 77 | (doseq [imp (get nmsps 'import)]
|
27 | 78 | (read-ns ctx imp))
|
28 | 79 | (->>
|
29 | 80 | (dissoc nmsps ['ns 'import])
|
30 | 81 | (mapv (fn [[k v]]
|
31 |
| - (when (and (symbol? k) (map? v)) |
32 |
| - (let [sym (symbol ns-str (name k)) |
33 |
| - res (-> (clojure.walk/postwalk |
34 |
| - (fn [x] |
35 |
| - (if (and (symbol? x) (not (contains? #{'types} x))) |
36 |
| - (if (namespace x) |
37 |
| - (do (when-not (get-in @ctx [:syms x]) |
38 |
| - (swap! ctx update :errors conj (format "Could not resolve symbol '%s in %s/%s" x ns-name k))) |
39 |
| - x) |
40 |
| - (do (when-not (get nmsps x) |
41 |
| - (swap! ctx update :errors conj (format "Could not resolve local symbol '%s in %s/%s" x ns-name k))) |
42 |
| - (symbol ns-str (name x)))) |
43 |
| - x)) |
44 |
| - (dissoc v 'tags 'types)) |
45 |
| - (assoc 'ns ns-name |
46 |
| - 'name (symbol (name ns-name) (name k)) |
47 |
| - 'types (get 'types v)))] |
48 |
| - (swap! ctx (fn [ctx] (assoc-in ctx [:syms sym] res))) |
49 |
| - (when-let [tps (get v 'types)] |
50 |
| - (assert (or (set? tps) (symbol? tps)) (format "types should be a set of symbols or symbol in %s/%s" ns-name k)) |
51 |
| - (doseq [tp-sym (if (symbol? tps) [tps] tps)] |
52 |
| - (update-types-recur ctx tp-sym sym))) |
53 |
| - res)))) |
54 |
| - (mapv (fn [res] |
55 |
| - (when-let [tps (and res (get res 'types))] |
56 |
| - (let [tps (if (symbol? tps) #{tps} tps)] |
57 |
| - (let [{errs :errors} (zen.validation/validate ctx tps (dissoc res 'types 'ns 'name 'tags))] |
58 |
| - (when-not (empty? errs) |
59 |
| - (doseq [err errs] |
60 |
| - (swap! ctx update :errors |
61 |
| - conj (format "Validation: %s '%s' in %s by %s" |
62 |
| - (get res 'name) |
63 |
| - (:message err) |
64 |
| - (pretty-path (:path err)) |
65 |
| - (pretty-path (:schema err))))))))))))))) |
| 82 | + (cond (keyword? k) (load-tag ctx nmsps k v) |
| 83 | + (and (symbol? k) (map? v)) (load-symbol ctx nmsps k v) |
| 84 | + :else nil))) |
| 85 | + (mapv (fn [res] (validate-resource ctx res))))))) |
66 | 86 |
|
67 | 87 | (defn read-ns [ctx nm]
|
68 | 88 | (let [pth (str (str/replace (str nm) #"\." "/") ".edn")]
|
|
72 | 92 | (swap! ctx update :errors conj (format "Could not load ns '%s" nm)))))
|
73 | 93 |
|
74 | 94 | (defn get-symbol [ctx nm]
|
75 |
| - (when-let [res (get-in @ctx [:syms nm])] |
| 95 | + (when-let [res (get-in @ctx [:symbols nm])] |
76 | 96 | (assoc res 'name nm)))
|
77 | 97 |
|
78 | 98 | (defn new-context [& [opts]]
|
|
0 commit comments