diff --git a/src/darkleaf/di/core.clj b/src/darkleaf/di/core.clj index d0c01265..461bd4dd 100644 --- a/src/darkleaf/di/core.clj +++ b/src/darkleaf/di/core.clj @@ -826,3 +826,68 @@ (p/demolish factory obj) (after-demolish! {:key key :object obj}) nil)))))) + +(defn inspect [] + (fn [registry] + (fn [key] + (let [factory (registry key)] + (reify p/Factory + (dependencies [_] + (p/dependencies factory)) + (build [_ deps] + (into [{:key key :deps (keys deps)}] + (comp + (mapcat val) + (distinct)) + deps)) + (demolish [_ obj])))))) + + +(defn- graphviz-id [x] + (str "\"" x "\"")) + +(defn render-graphviz [root middlewares] + (let [system (start root middlewares (inspect)) + components @system] + + (with-out-str + (println "digraph {") + (println "rankdir=LR;") + #_(println "splines=ortho;") + #_(println "concentrate=true;") + + (println "node [shape=box color=gray style=rounded];") + (println "edge [color=gray arrowhead=empty];") + + #_ + (println (graphviz-id (-> components first :key)) + (str "[color=magenta];")) + + (doseq [{:keys [key deps]} components] + (print "{") + (doseq [token (interpose "," (map graphviz-id deps))] + (print token)) + (println "}" "->" (graphviz-id key))) + + #_ + (doseq [[cluster keys] (->> components + (map :key) + (group-by try-namespace)) + :when (and (some? cluster) + (not (str/starts-with? cluster "env")) + (not (str/starts-with? cluster "darkleaf.di.core")))] + (println "subgraph" (graphviz-id cluster) "{") + (println " " (str "label=" (graphviz-id cluster) ";")) + (println " " "cluster=true;") + (println " " "labeljust=l;") + (println " " "color=gray;") + (println " " "style=dashed;") + + (doseq [key keys] + (println " " (graphviz-id key) + (str "[" + "label=" (graphviz-id (name key)) ;; keywords must start with : + "];"))) + (println "}")) + + (println "}")))) diff --git a/test/darkleaf/di/tutorial/x_inspect_test.clj b/test/darkleaf/di/tutorial/x_inspect_test.clj new file mode 100644 index 00000000..afb18bef --- /dev/null +++ b/test/darkleaf/di/tutorial/x_inspect_test.clj @@ -0,0 +1,26 @@ +(ns darkleaf.di.tutorial.x-inspect-test + (:require + [clojure.test :as t] + [darkleaf.di.core :as di])) + +(defn a [] + :ok) + +(defn b [{a `a}] + :ok) + +(defn c [{a `a + b `b}] + :ok) + +(t/deftest ok + (with-open [info (di/start `c (di/inspect))] + (t/is (= [{:key `c :deps [`a `b]} + {:key `a :deps nil} + {:key `b :deps [`a]}] + @info)))) + + +(comment + (di/render-graphviz `c nil) + ,,,)