From 080272157879c4db8ad21057795d14b5f66fbbae Mon Sep 17 00:00:00 2001 From: Mikhail Kuzmin Date: Sun, 27 Oct 2024 22:45:34 +0400 Subject: [PATCH 1/2] inspect middleware --- src/darkleaf/di/core.clj | 16 +++++++++++++++ test/darkleaf/di/tutorial/x_inspect_test.clj | 21 ++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 test/darkleaf/di/tutorial/x_inspect_test.clj diff --git a/src/darkleaf/di/core.clj b/src/darkleaf/di/core.clj index d0c01265..7a3b8358 100644 --- a/src/darkleaf/di/core.clj +++ b/src/darkleaf/di/core.clj @@ -826,3 +826,19 @@ (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])))))) + 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..7b377be4 --- /dev/null +++ b/test/darkleaf/di/tutorial/x_inspect_test.clj @@ -0,0 +1,21 @@ +(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)))) From 96ac2a69e7266b9c621bb5fc151c277577b36d6d Mon Sep 17 00:00:00 2001 From: Mikhail Kuzmin Date: Sun, 27 Oct 2024 22:48:13 +0400 Subject: [PATCH 2/2] graphviz --- src/darkleaf/di/core.clj | 49 ++++++++++++++++++++ test/darkleaf/di/tutorial/x_inspect_test.clj | 5 ++ 2 files changed, 54 insertions(+) diff --git a/src/darkleaf/di/core.clj b/src/darkleaf/di/core.clj index 7a3b8358..461bd4dd 100644 --- a/src/darkleaf/di/core.clj +++ b/src/darkleaf/di/core.clj @@ -842,3 +842,52 @@ 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 index 7b377be4..afb18bef 100644 --- a/test/darkleaf/di/tutorial/x_inspect_test.clj +++ b/test/darkleaf/di/tutorial/x_inspect_test.clj @@ -19,3 +19,8 @@ {:key `a :deps nil} {:key `b :deps [`a]}] @info)))) + + +(comment + (di/render-graphviz `c nil) + ,,,)