Last active
August 29, 2015 14:26
-
-
Save Deraen/19b62045e74e547025de to your computer and use it in GitHub Desktop.
ClojureScript output file dependency graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Use case: | |
; We reload the files automatically in browser when they are changed. | |
; To load the files in correct order we need to know their dependencies. | |
(require '[cljs.build.api :refer :all] | |
'[cljs.analyzer.api :as ana-api] | |
'[clojure.java.io :as io] | |
'[cljs.util :as util]) | |
(def state (ana-api/empty-state)) | |
(defn rm [f] | |
(when (.exists f) | |
(when (.isDirectory f) | |
(doseq [n (seq (.list f))] | |
(rm (io/file f n)))) | |
(io/delete-file f))) | |
(rm (io/file "out")) | |
(build "samples/hello/src" {:compiler {:main "hello.core"}} state) | |
;; | |
;; Current version | |
;; | |
(def dep-graph | |
(let [cljs-nses (:cljs.compiler/compiled-cljs @state) | |
js-nses (reduce-kv (fn [xs k v] | |
(assoc xs (:file v) v)) | |
{} | |
(:js-dependency-index @state)) | |
all-nses (reduce-kv (fn [xs k v] | |
(reduce #(assoc %1 (str %2) (str k)) xs (:provides v))) | |
{} | |
(merge js-nses cljs-nses))] | |
(->> cljs-nses | |
(reduce-kv (fn [xs k v] | |
(assoc xs k (set (keep (comp all-nses str) (:requires v))))) | |
{})))) | |
; => | |
; {"/home/juho/Source/clojurescript/out/hello/foo/bar.js" #{}, | |
; "/home/juho/Source/clojurescript/out/hello/core.js" #{"/home/juho/Source/clojurescript/out/cljs/reader.js" "/home/juho/Source/clojurescript/out/hello/foo/bar.js"}, | |
; "/home/juho/Source/clojurescript/out/cljs/reader.js" #{"goog/string/stringbuffer.js" "goog/string/string.js"}} | |
(def b (let [m "/home/juho/Source/clojurescript/out/hello/core.js"] | |
(reverse (cons m (util/topo-sort m dep-graph))))) | |
; => | |
; ("goog/string/string.js" "goog/string/stringbuffer.js" "/home/juho/Source/clojurescript/out/hello/foo/bar.js" "/home/juho/Source/clojurescript/out/cljs/reader.js" "/home/juho/Source/clojurescript/out/hello/core.js") | |
;; | |
;; Using current Cljs api | |
;; | |
; Note: Google closure files wont change so their ordering isn't interesting. | |
; Note: What about foreign libs? They could be interesting. | |
(defn ns->path [x] | |
(.getPath (target-file-for-cljs-ns x))) | |
(def dep-graph-2 | |
(->> (ana-api/all-ns state) | |
(reduce (fn [acc n] | |
(let [p (ns->path n)] | |
(->> (cljs-ns-dependents state n) | |
(map ns->path) | |
(reduce (fn [acc x] | |
(update-in acc [x] (fnil conj #{}) p)) | |
(update-in acc [p] #(or % #{})))))) | |
{}))) | |
; => | |
; {"out/hello/foo/bar.js" #{}, | |
; "out/hello/core.js" ("out/cljs/reader.js" "out/hello/foo/bar.js"), | |
; "out/cljs/core.js" #{}, | |
; "out/cljs/reader.js" #{}, | |
; "out/cljs/user.js" #{}} | |
;; | |
;; Proposal: ns-dependencies | |
;; | |
(defn ns-dependencies | |
"Given a namespace as a symbol..." | |
([ns] (ns-dependencies env/*compiler* ns)) | |
([state ns] | |
(vals (:requires (ana-api/find-ns state ns))))) | |
(def dep-graph-3 | |
(let [all-ns (ana-api/all-ns state) | |
all-ns-set (set all-ns)] | |
(->> all-ns | |
(reduce (fn [acc n] | |
(assoc acc (ns->path n) (->> (ns-dependencies state n) | |
(keep all-ns-set) | |
(map ns->path) | |
(set)))) | |
{})))) | |
; => | |
; {"out/cljs/user.js" #{}, | |
; "out/cljs/core.js" #{}, | |
; "out/hello/foo/bar.js" #{}, | |
; "out/hello/core.js" #{"out/hello/foo/bar.js" "out/cljs/reader.js"}, | |
; "out/cljs/reader.js" #{}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment