diff --git a/notebooks/index.clj b/notebooks/index.clj index cb41100c..4ce51759 100644 --- a/notebooks/index.clj +++ b/notebooks/index.clj @@ -91,6 +91,7 @@ #_[:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/x_instrument_test.clj")} "Instrument"]] [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/x_update_key_test.clj")} "Update key"]] [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/x_log_test.clj")} "Log"]] + [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/x_inspect_test.clj")} "Inspect"]] [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/y_graceful_stop_test.clj")} "Graceful stop"]] [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/y_multi_arity_service_test.clj")} "Multi arity service"]] [:li [:a {:href (clerk/doc-url "test/darkleaf/di/tutorial/z_multi_system_test.clj")} "Multi system"]] @@ -118,6 +119,7 @@ ;; ### `darkleaf.di.core` (view-doc #'di/start) (view-doc #'di/stop) +(view-doc #'di/inspect) (view-doc #'di/ref) (view-doc #'di/opt-ref) (view-doc #'di/template) diff --git a/src/darkleaf/di/core.clj b/src/darkleaf/di/core.clj index 6e55d8f2..204e7098 100644 --- a/src/darkleaf/di/core.clj +++ b/src/darkleaf/di/core.clj @@ -829,3 +829,42 @@ (p/demolish factory obj) (after-demolish! {:key key :object obj}) nil)))))) + + +(defn- inspect-middleware [] + (fn [registry] + (fn [key] + (let [factory (registry key) + declared-deps (p/dependencies factory) + info (into {} + (filter (fn [[k v]] (some? v))) + {:key key + :dependencies declared-deps})] + (reify p/Factory + (dependencies [_] + declared-deps) + (build [_ deps] + (into [info] + (comp + (mapcat val) + (distinct)) + deps)) + (demolish [_ obj])))))) + +(defn inspect + "Collects and returns a vector of keys along with their dependencies. + Useful for inspecting enabled components and services. + Evaluates all registries with middlewares applied. + + Expects the same arguments as `start` and returns a vector of keys with dependencies e.g.: + + ```clojure + [{:key `root :dependencies {`foo :required `bar :optional}} + {:key `foo} + {:key `bar}] + ```" + [key & middlewares] + (with-open [components (start key + middlewares + (inspect-middleware))] + @components)) 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..f8b69fd1 --- /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 + :or {b :default}}] + :ok) + +(t/deftest ok + (t/is (= [{:key `c :dependencies {`a :required `b :optional}} + {:key `a} + {:key `b :dependencies {`a :required}}] + (di/inspect `c))))