initial commit
This commit is contained in:
commit
3c837f1abc
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
.DS_Store
|
||||
/target
|
||||
/classes
|
||||
/checkouts
|
||||
pom.xml
|
||||
pom.xml.asc
|
||||
*.jar
|
||||
*.class
|
||||
/.lein-*
|
||||
/.nrepl-port
|
||||
/*.project
|
||||
/*.classpath
|
||||
/.settings/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
/.idea/
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Gered King
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
11
README.md
Normal file
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# clj-metasearch
|
||||
|
||||
Helper functions for searching through Clojure namespaces for vars containing specific bits of metadata.
|
||||
|
||||
## Usage
|
||||
|
||||
FIXME
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the the MIT License. See LICENSE for more details.
|
8
project.clj
Normal file
8
project.clj
Normal file
|
@ -0,0 +1,8 @@
|
|||
(defproject clj-metasearch "0.1.0-SNAPSHOT"
|
||||
:description "Helper functions for searching through Clojure namespaces for vars containing specific bits of metadata."
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "MIT License"
|
||||
:url "http://opensource.org/licenses/MIT"}
|
||||
:dependencies [[org.clojure/clojure "1.5.1"]
|
||||
[org.clojure/java.classpath "0.2.2"]
|
||||
[org.clojure/tools.namespace "0.2.4"]])
|
71
src/clj_metasearch/core.clj
Normal file
71
src/clj_metasearch/core.clj
Normal file
|
@ -0,0 +1,71 @@
|
|||
(ns clj-metasearch.core
|
||||
(:import (java.io File)
|
||||
(java.util.jar JarFile))
|
||||
(:require [clojure.tools.namespace.find :refer [find-clojure-sources-in-dir find-namespaces-in-jarfile]]
|
||||
[clojure.tools.namespace.file :refer [read-file-ns-decl]]
|
||||
[clojure.java.classpath :refer [classpath jar-file?]]))
|
||||
|
||||
(defn- find-namespaces-in-dirs [classpath-files]
|
||||
(->> classpath-files
|
||||
(filter (fn [^File file]
|
||||
(.isDirectory file)))
|
||||
(map find-clojure-sources-in-dir)
|
||||
(apply concat)
|
||||
(map #(second (read-file-ns-decl %)))))
|
||||
|
||||
(defn- find-namespaces-in-jars [classpath-files]
|
||||
(->> classpath-files
|
||||
(filter jar-file?)
|
||||
(map #(new JarFile %))
|
||||
(map find-namespaces-in-jarfile)
|
||||
(apply concat)))
|
||||
|
||||
(defn- find-vars-in [namespace pred & [require-all-namespaces?]]
|
||||
(try
|
||||
(when require-all-namespaces?
|
||||
(require namespace))
|
||||
(->> (ns-interns namespace)
|
||||
(reduce
|
||||
(fn [matches [name var]]
|
||||
(let [metadata (meta var)]
|
||||
(if (pred metadata)
|
||||
(conj matches {:ns namespace
|
||||
:var var})
|
||||
matches)))
|
||||
[]))
|
||||
(catch Exception ex
|
||||
; some namespaces, such as clojure.core.reducers, cannot be loaded under Java 6 and when
|
||||
; we run this function on such a namespace we get an exception like:
|
||||
;
|
||||
; java.lang.Exception: No namespace: clojure.core.reducers found
|
||||
;
|
||||
; which kind of makes it hard to pick out only those cases.
|
||||
; also, the exact same type of exception will get thrown if we attempt to call
|
||||
; (ns-interns) on a namespace which has not been loaded (required/used) yet.
|
||||
;
|
||||
; so for now we'll just silently fail on any exception and return a blank list (what
|
||||
; else could we really do?)
|
||||
[])))
|
||||
|
||||
(defn find-namespaces
|
||||
"Searches for all Clojure namespaces currently on the classpath and returns only those
|
||||
for which pred returns true, or all Clojure namespaces if pred is not provided."
|
||||
[& [pred]]
|
||||
(let [classpath-files (classpath)
|
||||
dir-namespaces (find-namespaces-in-dirs classpath-files)
|
||||
jar-namespaces (find-namespaces-in-jars classpath-files)
|
||||
all-namespaces (distinct (concat dir-namespaces jar-namespaces))]
|
||||
(if pred
|
||||
(filter pred all-namespaces)
|
||||
all-namespaces)))
|
||||
|
||||
(defn find-vars
|
||||
"Finds vars in Clojure namespaces for which namespace-pred returns true that have metadata
|
||||
for which meta-pred returns true. If namespace-pred is not provided, all Clojure namespaces
|
||||
are checked. The returns vars will each be in a map where the :ns key is the namespace
|
||||
which the var was found in, and :var is the Clojure var itself (which you can get the value
|
||||
of by, e.g. using var-get)"
|
||||
[meta-pred & [namespace-pred]]
|
||||
(->> (find-namespaces namespace-pred)
|
||||
(map #(find-vars-in % meta-pred))
|
||||
(apply concat)))
|
Reference in a new issue