Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Add reload-observer
Browse files Browse the repository at this point in the history
  • Loading branch information
Stuart Sierra committed Sep 18, 2010
1 parent 1397ae4 commit 81bcdab
Showing 1 changed file with 43 additions and 14 deletions.
57 changes: 43 additions & 14 deletions src/main/clojure/lazytest/loader.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
(ns lazytest.loader
"Loading namespaces and managing dependencies."
(:use [lazytest.dependency :only (graph depend)]
(:use [lazytest.dependency :only (graph depend dependents remove-key)]
[lazytest.nsdeps :only (deps-from-ns-decl)]
[lazytest.reload :only (reload)]
[clojure.contrib.find-namespaces :only (find-clojure-sources-in-dir
read-file-ns-decl)]
[clojure.set :only (union)]
[clojure.java.io :only (file)]))

(defn find-sources
Expand All @@ -12,20 +14,47 @@
(every? (fn [d] (instance? java.io.File d)) dirs)]}
(mapcat find-clojure-sources-in-dir dirs))

(defn namespace-and-deps-for-file [f]
(let [decl (read-file-ns-decl f)]
(when decl
[(second decl)
(deps-from-ns-decl decl)])))

(defn newer-sources [dirs timestamp]
(filter #(> (.lastModified %) timestamp) (find-sources dirs)))

(defn newer-namespaces [dirs timestamp]
(remove nil? (map namespace-and-deps-for-file (newer-sources dirs timestamp))))
(defn newer-namespace-decls [dirs timestamp]
(remove nil? (map read-file-ns-decl (newer-sources dirs timestamp))))

(defn add-to-dep-graph [dep-graph namespace-decls]
(reduce (fn [g decl]
(let [nn (second decl)
deps (deps-from-ns-decl decl)]
(if (seq deps)
(apply depend g nn deps)
g)))
dep-graph namespace-decls))

(defn remove-from-dep-graph [dep-graph new-decls]
(apply remove-key dep-graph (map second new-decls)))

(defn update-dependency-graph [dep-graph new-decls]
(-> dep-graph
(remove-from-dep-graph new-decls)
(add-to-dep-graph new-decls)))

(defn affected-namespaces [changed-namespaces old-dependency-graph]
(apply union (set changed-namespaces) (map #(dependents old-dependency-graph %)
changed-namespaces)))

(defn dep-graph [names-and-deps]
(reduce (fn [g [n deps]] (if (seq deps)
(apply depend g n deps)
g))
(graph) names-and-deps))
(defn reload-observer [dirs initial-timestamp]
"Returns a no-arg function which, when called, returns a set of
namespaces that need to be reloaded, based on file modification
timestamps and the graph of namespace dependencies."
{:pre [(integer? initial-timestamp)
(every? (fn [f] (instance? java.io.File f)) dirs)]}
(let [timestamp (atom initial-timestamp)
dependency-graph (atom (graph))]
(fn []
(let [then @timestamp
now (System/currentTimeMillis)
new-decls (newer-namespace-decls dirs then)
new-names (map second new-decls)
affected-names (affected-namespaces new-names @dependency-graph)]
(reset! timestamp now)
(swap! dependency-graph update-dependency-graph new-decls)
affected-names))))

0 comments on commit 81bcdab

Please sign in to comment.