From 71817230d1273907b7e895fb22b69e9ba877f48e Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 9 Apr 2024 22:38:00 +0200 Subject: [PATCH] wip to detect cycles --- src/ydn/core.clj | 74 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/ydn/core.clj b/src/ydn/core.clj index 1768cb0..8a73251 100644 --- a/src/ydn/core.clj +++ b/src/ydn/core.clj @@ -5,8 +5,11 @@ [clojure.walk :refer [prewalk]]) (:refer-clojure :exclude [read read-string])) +(def keyword-re-str + ":ref([.][^/\\s}]*/|/)[^/.\\s}]*") + (def keyword-re - #":ref([.][^/\s]*/|/)[^/.\s]*$") + (re-pattern (str "^" keyword-re-str "$"))) (defn ref-kw "returns nil if the string does not matches a valid ref keyword format." @@ -35,11 +38,16 @@ (name-or-str (get-in! edn (key-to-path s))))) +(def interpolation-re + (re-pattern + (str "\\$\\{(" keyword-re-str ")\\}"))) + (defn apply-interpolation [s edn] - (string/replace s #"\$\{([^}]*)\}" (fn [m] - (or (to-ref edn (second m)) - (first m))))) + (string/replace s + interpolation-re + (fn [m] (or (to-ref edn (second m)) + (first m))))) (defn root-namespace [kw] (some-> kw namespace (string/split #"[.]") first)) @@ -72,6 +80,64 @@ (take ydn-fix-point-limit (iterate apply-self-refs edn)) [::error]))) +(defn extract-refs + [s] + (let [matcher (re-matcher interpolation-re s)] + (->> (repeatedly #(re-find matcher)) + (take-while some?) + (mapv (comp key-to-path second))))) + +(comment + (extract-refs "${:ref.pg/scheme}://${:ref.pg/domain}:${:ref.pg/port}") + (extract-refs "${:ref.pg/scheme}") + ) + +(defn path-to-kw + [p] + (if (> (count p) 1) + (keyword (string/join "." (mapv name (pop p))) + (name (last p))) + (keyword (name (last p))) + )) + +(defn rec-deps-list + [prefix-path edn] + (assert (vector? prefix-path)) + (apply concat + (for [[k v] edn] + (cond + (keyword? v) (when-let [kw (ref-kw (str v))] + [{(path-to-kw (conj prefix-path k)) + (keyword (string/replace kw #"^:ref[./]" "")) + }]) + (string? v) (let [targets (extract-refs v)] + (for [target targets] + {(path-to-kw (conj prefix-path k)) + (path-to-kw target)})) + (map? v) (apply concat (rec-deps-list (conj prefix-path k) v)) + :else nil)))) + +(defn deps-list + [edn] + (assert (map? edn) "the edn config should be an hash-map") + (into {} + (rec-deps-list [] edn))) + +(comment + (deps-list {:x :ref/y + :y :ref/x + :foo {:bar :ref/x} + :z "${:ref/x} & ${:ref/y}"}) + + ) + +(defn detect-cycles + [g] + :TODO + ) + + + (defn read-string-with-conf [{:keys [ydn-fix-point-limit] :as _conf} & args] (fix-apply-self-refs