blob: 9870efc16428b26ea88e3504f80f6b1667e3ee41 (
plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
;; Copyright (c) Stephen C. Gilardi. All rights reserved.
;; The use and distribution terms for this software are covered by the
;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
;; which can be found in the file CPL.TXT 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.
;;
;; loader.clj
;;
;; scgilardi (gmail)
;; 5 April 2008
;;
;; load-system-resource adapted from Stuart Sierra's public domain
;; require.clj
(clojure/in-ns 'loader)
(clojure/refer 'clojure)
;; Private
(def
#^{:doc "True when an ensure-ns call has requested a reload of all of its
dependencies (:reload-all)"
:private true}
reloading-all false)
(def
#^{:doc "True when an ensure-ns call has requested that 'loaded' messages
be printed after each load (:verbose)"
:private true}
loading-verbosely false)
(defn- load-system-resource
"Sequentially read and evaluate forms from a resource within classpath"
[name]
(let [url (. ClassLoader (getSystemResource name))]
(when-not url
(throw (new Exception (str "'" name "' not found in classpath"))))
(if (= "file" (. url (getProtocol)))
(load-file (. url (getFile)))
(with-open reader (new java.io.BufferedReader
(new java.io.InputStreamReader
(. url (openStream))))
(load reader)))))
;; Public
(defn ensure-ns
"Ensures that a namespace is loaded. If it is not yet loaded, searches
for an implementation file whose name is the namespace name followed by
'.clj' and loads it. If no :from option is present, the search considers
only the classpath roots. Options may include one each of:
:from string
:reload boolean
:reload-all boolean
:verbose boolean
An argument to :from specifies a path to the implementation file's parent
directory. An absolute path (beginning with '/') specifies a directory in
the filesystem. A relative path specifies directories relative to each of
the classpath roots.
When :reload is true, the namespace will be reloaded if already loaded.
When :reload-all is true, all directly and indirectly required namespaces
are also reloaded.
When :verbose is true, a 'loaded' message is printed after each load."
[ns-sym & options]
(let [opts (apply hash-map options)
from (:from opts)
reload (:reload opts)
reload-all (:reload-all opts)
verbose (:verbose opts)]
(binding [reloading-all (or reloading-all reload-all)
loading-verbosely (or loading-verbosely verbose)]
(when (or (not (find-ns ns-sym)) reload reloading-all)
(let [resource (str from (when from \/) ns-sym ".clj")]
(if (= (first resource) \/)
(load-file resource)
(load-system-resource resource))
(when loading-verbosely
(println "loaded" resource))
(when-not (find-ns ns-sym)
(throw (new Exception (str "namespace '" ns-sym
"' not found in '"
resource "'")))))))))
(defn require
"Ensures that a namespace is loaded and then refers to it. Options may
include options for ensure-ns and/or filters for refer."
[ns-sym & options]
(apply ensure-ns ns-sym options)
(apply refer ns-sym options))
|