add support for suppressing/throwing exceptions as namespaces are searched

This commit is contained in:
Gered 2014-04-09 08:52:57 -04:00
parent 0f194b64cf
commit a38c0e840b

View file

@ -1,6 +1,7 @@
(ns clj-metasearch.core (ns clj-metasearch.core
(:import (java.io File) (:import (java.io File)
(java.util.jar JarFile)) (java.util.jar JarFile)
(clojure.lang Compiler$CompilerException))
(:require [clojure.tools.namespace.find :refer [find-clojure-sources-in-dir find-namespaces-in-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.tools.namespace.file :refer [read-file-ns-decl]]
[clojure.java.classpath :refer [classpath jar-file?]])) [clojure.java.classpath :refer [classpath jar-file?]]))
@ -20,7 +21,10 @@
(map find-namespaces-in-jarfile) (map find-namespaces-in-jarfile)
(apply concat))) (apply concat)))
(defn- find-vars-in [namespace pred & [require-all-namespaces?]] (defn- namespace-not-found-exception? [^Exception ex]
(not (nil? (re-matches #"^(?:java\.lang\.Exception\: No namespace\: )(.*?)(?: found)$" (.toString ex)))))
(defn- find-vars-in [namespace pred {:keys [require-all-namespaces? throw-exceptions? throw-compiler-exceptions?]}]
(try (try
(when require-all-namespaces? (when require-all-namespaces?
(require namespace)) (require namespace))
@ -33,19 +37,14 @@
:var var}) :var var})
matches))) matches)))
[])) []))
(catch Compiler$CompilerException ex
(if (or throw-exceptions? throw-compiler-exceptions?)
(throw ex)
[]))
(catch Exception ex (catch Exception ex
; some namespaces, such as clojure.core.reducers, cannot be loaded under Java 6 and when (if throw-exceptions?
; we run this function on such a namespace we get an exception like: (throw ex)
; []))))
; 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 (defn find-namespaces
"Searches for all Clojure namespaces currently on the classpath and returns only those "Searches for all Clojure namespaces currently on the classpath and returns only those
@ -73,7 +72,7 @@
A sequence of maps will be returned, where each map holds information about a var that was A sequence of maps will be returned, where each map holds information about a var that was
found. The :ns key is the namespace which the var was found in, and :var is the Clojure var found. 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)" itself (which you can get the value of by, e.g. using var-get)"
[meta-pred & {:keys [namespace-pred require-all-namespaces?]}] [meta-pred & {:keys [namespace-pred] :as options}]
(->> (find-namespaces namespace-pred) (->> (find-namespaces namespace-pred)
(map #(find-vars-in % meta-pred require-all-namespaces?)) (map #(find-vars-in % meta-pred options))
(apply concat))) (apply concat)))