Mercurial > lasercutter
comparison src/clojure/contrib/find_namespaces.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:35cf337adfcf | 10:ef7dbbd6452c |
---|---|
1 ;;; find_namespaces.clj: search for ns declarations in dirs, JARs, or CLASSPATH | |
2 | |
3 ;; by Stuart Sierra, http://stuartsierra.com/ | |
4 ;; April 19, 2009 | |
5 | |
6 ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use | |
7 ;; and distribution terms for this software are covered by the Eclipse | |
8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
9 ;; which can be found in the file epl-v10.html at the root of this | |
10 ;; distribution. By using this software in any fashion, you are | |
11 ;; agreeing to be bound by the terms of this license. You must not | |
12 ;; remove this notice, or any other, from this software. | |
13 | |
14 | |
15 (ns | |
16 ^{:author "Stuart Sierra", | |
17 :doc "Search for ns declarations in dirs, JARs, or CLASSPATH"} | |
18 clojure.contrib.find-namespaces | |
19 (:require [clojure.contrib.classpath :as cp] | |
20 [clojure.contrib.jar :as jar]) | |
21 (import (java.io File FileReader BufferedReader PushbackReader | |
22 InputStreamReader) | |
23 (java.util.jar JarFile))) | |
24 | |
25 | |
26 ;;; Finding namespaces in a directory tree | |
27 | |
28 (defn clojure-source-file? | |
29 "Returns true if file is a normal file with a .clj extension." | |
30 [^File file] | |
31 (and (.isFile file) | |
32 (.endsWith (.getName file) ".clj"))) | |
33 | |
34 (defn find-clojure-sources-in-dir | |
35 "Searches recursively under dir for Clojure source files (.clj). | |
36 Returns a sequence of File objects, in breadth-first sort order." | |
37 [^File dir] | |
38 ;; Use sort by absolute path to get breadth-first search. | |
39 (sort-by #(.getAbsolutePath %) | |
40 (filter clojure-source-file? (file-seq dir)))) | |
41 | |
42 (defn comment? | |
43 "Returns true if form is a (comment ...)" | |
44 [form] | |
45 (and (list? form) (= 'comment (first form)))) | |
46 | |
47 (defn ns-decl? | |
48 "Returns true if form is a (ns ...) declaration." | |
49 [form] | |
50 (and (list? form) (= 'ns (first form)))) | |
51 | |
52 (defn read-ns-decl | |
53 "Attempts to read a (ns ...) declaration from rdr, and returns the | |
54 unevaluated form. Returns nil if read fails or if a ns declaration | |
55 cannot be found. The ns declaration must be the first Clojure form | |
56 in the file, except for (comment ...) forms." | |
57 [^PushbackReader rdr] | |
58 (try (let [form (read rdr)] | |
59 (cond | |
60 (ns-decl? form) form | |
61 (comment? form) (recur rdr) | |
62 :else nil)) | |
63 (catch Exception e nil))) | |
64 | |
65 (defn read-file-ns-decl | |
66 "Attempts to read a (ns ...) declaration from file, and returns the | |
67 unevaluated form. Returns nil if read fails, or if the first form | |
68 is not a ns declaration." | |
69 [^File file] | |
70 (with-open [rdr (PushbackReader. (BufferedReader. (FileReader. file)))] | |
71 (read-ns-decl rdr))) | |
72 | |
73 (defn find-ns-decls-in-dir | |
74 "Searches dir recursively for (ns ...) declarations in Clojure | |
75 source files; returns the unevaluated ns declarations." | |
76 [^File dir] | |
77 (filter identity (map read-file-ns-decl (find-clojure-sources-in-dir dir)))) | |
78 | |
79 (defn find-namespaces-in-dir | |
80 "Searches dir recursively for (ns ...) declarations in Clojure | |
81 source files; returns the symbol names of the declared namespaces." | |
82 [^File dir] | |
83 (map second (find-ns-decls-in-dir dir))) | |
84 | |
85 | |
86 ;;; Finding namespaces in JAR files | |
87 | |
88 (defn clojure-sources-in-jar | |
89 "Returns a sequence of filenames ending in .clj found in the JAR file." | |
90 [^JarFile jar-file] | |
91 (filter #(.endsWith % ".clj") (jar/filenames-in-jar jar-file))) | |
92 | |
93 (defn read-ns-decl-from-jarfile-entry | |
94 "Attempts to read a (ns ...) declaration from the named entry in the | |
95 JAR file, and returns the unevaluated form. Returns nil if the read | |
96 fails, or if the first form is not a ns declaration." | |
97 [^JarFile jarfile ^String entry-name] | |
98 (with-open [rdr (PushbackReader. | |
99 (BufferedReader. | |
100 (InputStreamReader. | |
101 (.getInputStream jarfile (.getEntry jarfile entry-name)))))] | |
102 (read-ns-decl rdr))) | |
103 | |
104 (defn find-ns-decls-in-jarfile | |
105 "Searches the JAR file for Clojure source files containing (ns ...) | |
106 declarations; returns the unevaluated ns declarations." | |
107 [^JarFile jarfile] | |
108 (filter identity | |
109 (map #(read-ns-decl-from-jarfile-entry jarfile %) | |
110 (clojure-sources-in-jar jarfile)))) | |
111 | |
112 (defn find-namespaces-in-jarfile | |
113 "Searches the JAR file for Clojure source files containing (ns ...) | |
114 declarations. Returns a sequence of the symbol names of the | |
115 declared namespaces." | |
116 [^JarFile jarfile] | |
117 (map second (find-ns-decls-in-jarfile jarfile))) | |
118 | |
119 | |
120 ;;; Finding namespaces anywhere on CLASSPATH | |
121 | |
122 (defn find-ns-decls-on-classpath | |
123 "Searches CLASSPATH (both directories and JAR files) for Clojure | |
124 source files containing (ns ...) declarations. Returns a sequence | |
125 of the unevaluated ns declaration forms." | |
126 [] | |
127 (concat | |
128 (mapcat find-ns-decls-in-dir (cp/classpath-directories)) | |
129 (mapcat find-ns-decls-in-jarfile (cp/classpath-jarfiles)))) | |
130 | |
131 (defn find-namespaces-on-classpath | |
132 "Searches CLASSPATH (both directories and JAR files) for Clojure | |
133 source files containing (ns ...) declarations. Returns a sequence | |
134 of the symbol names of the declared namespaces." | |
135 [] | |
136 (map second (find-ns-decls-on-classpath))) |