diff --git a/packages/kmono-core/src/k16/kmono/core/graph.clj b/packages/kmono-core/src/k16/kmono/core/graph.clj index 203feb5..cca7780 100644 --- a/packages/kmono-core/src/k16/kmono/core/graph.clj +++ b/packages/kmono-core/src/k16/kmono/core/graph.clj @@ -34,21 +34,27 @@ (defn parallel-topo-sort {:malli/schema [:=> [:cat core.schema/?PackageMap] [:maybe ?ExecOrder]]} [packages] - (when (seq packages) - (when-let [ks (->> packages - (keep - (fn [[fqn package]] - (when (empty? (:depends-on package)) - fqn))) - seq - sort)] - (into [(vec ks)] - (parallel-topo-sort - (into {} - (map (fn [[fqn package]] - [fqn (assoc package - :depends-on (apply disj (:depends-on package) ks))])) - (apply dissoc packages ks))))))) + (let [stage + (into #{} + (comp + (filter (fn [[_ pkg]] + (empty? (:depends-on pkg)))) + (map first)) + packages) + + remaining + (reduce + (fn [packages [pkg-name pkg]] + (if-not (contains? stage pkg-name) + (let [deps (apply disj (:depends-on pkg) stage) + pkg (assoc pkg :depends-on deps)] + (assoc packages pkg-name pkg)) + packages)) + {} + packages)] + + (when (seq stage) + (into [(-> stage sort vec)] (parallel-topo-sort remaining))))) (defn query-dependents {:malli/schema [:=> [:cat core.schema/?PackageMap :symbol] [:set :symbol]]} diff --git a/packages/kmono-core/test/k16/kmono/core/graph_test.clj b/packages/kmono-core/test/k16/kmono/core/graph_test.clj index 18cd0d6..84242e1 100644 --- a/packages/kmono-core/test/k16/kmono/core/graph_test.clj +++ b/packages/kmono-core/test/k16/kmono/core/graph_test.clj @@ -46,7 +46,9 @@ packages (core.packages/resolve-packages *repo* config)] (is (= [['com.kepler16/b]] - (core.graph/parallel-topo-sort (dissoc packages 'com.kepler16/a)))))) + (core.graph/parallel-topo-sort + (core.graph/filter-by #(= 'com.kepler16/b (:fqn %)) + packages)))))) (deftest query-dependents-test (fs/create-dirs (fs/file *repo* "packages/c")) @@ -73,7 +75,7 @@ (is (match? {'com.kepler16/a {:dependents #{}}} (core.graph/filter-by #(= 'com.kepler16/a (:fqn %)) packages))) -(is (match? {'com.kepler16/b {:depends-on #{}}} + (is (match? {'com.kepler16/b {:depends-on #{}}} (core.graph/filter-by #(= 'com.kepler16/b (:fqn %)) packages))) (is (= ['com.kepler16/b 'com.kepler16/a]