Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
file 53 lines (49 sloc) 2.073 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
;; Copyright (c) Stuart Sierra, 2012. All rights reserved. The use and
;; distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution. By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license. You must not
;; remove this notice, or any other, from this software.

(ns ^{:author "Stuart Sierra"
      :doc "Force reloading namespaces on demand or through a
dependency tracker"}
  clojure.tools.namespace.reload
  (:require [clojure.tools.namespace.track :as track]))

(defn remove-lib
  "Remove lib's namespace and remove lib from the set of loaded libs."
  [lib]
  (remove-ns lib)
  (dosync (alter @#'clojure.core/*loaded-libs* disj lib)))

(defn track-reload-one
  "Executes the next pending unload/reload operation in the dependency
tracker. Returns the updated dependency tracker. If reloading caused
an error, it is captured as ::error and the namespace which caused
the error is ::error-ns."
  [tracker]
  (let [{unload ::track/unload, load ::track/load} tracker]
    (cond
      (seq unload)
        (let [n (first unload)]
          (remove-lib n)
          (update-in tracker [::track/unload] rest))
      (seq load)
        (let [n (first load)]
          (try (require n :reload)
               (update-in tracker [::track/load] rest)
               (catch Throwable t
                 (assoc tracker
                   ::error t ::error-ns n ::track/unload load))))
      :else
        tracker)))

(defn track-reload
  "Executes all pending unload/reload operations on dependency tracker
until either an error is encountered or there are no more pending
operations."
  [tracker]
  (loop [tracker (dissoc tracker ::error ::error-ns)]
    (let [{error ::error, unload ::track/unload, load ::track/load} tracker]
      (if (and (not error)
               (or (seq load) (seq unload)))
        (recur (track-reload-one tracker))
        tracker))))
Something went wrong with that request. Please try again.