├── LICENSE ├── README.md ├── deps.edn └── src └── com └── stuarthalloway ├── reflector.clj └── reflector ├── coerce.clj └── pom.clj /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License -v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF 5 | THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and 12 | documentation distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | 16 | i) changes to the Program, and 17 | 18 | ii) additions to the Program; 19 | 20 | where such changes and/or additions to the Program originate from and 21 | are distributed by that particular Contributor. A Contribution 22 | 'originates' from a Contributor if it was added to the Program by such 23 | Contributor itself or anyone acting on such Contributor's 24 | behalf. Contributions do not include additions to the Program which: 25 | (i) are separate modules of software distributed in conjunction with 26 | the Program under their own license agreement, and (ii) are not 27 | derivative works of the Program. 28 | 29 | "Contributor" means any person or entity that distributes the Program. 30 | 31 | "Licensed Patents " mean patent claims licensable by a Contributor 32 | which are necessarily infringed by the use or sale of its Contribution 33 | alone or when combined with the Program. 34 | 35 | "Program" means the Contributions distributed in accordance with this 36 | Agreement. 37 | 38 | "Recipient" means anyone who receives the Program under this 39 | Agreement, including all Contributors. 40 | 41 | 2. GRANT OF RIGHTS 42 | 43 | a) Subject to the terms of this Agreement, each Contributor hereby 44 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 45 | license to reproduce, prepare derivative works of, publicly display, 46 | publicly perform, distribute and sublicense the Contribution of such 47 | Contributor, if any, and such derivative works, in source code and 48 | object code form. 49 | 50 | b) Subject to the terms of this Agreement, each Contributor hereby 51 | grants Recipient a non-exclusive, worldwide, royalty-free patent 52 | license under Licensed Patents to make, use, sell, offer to sell, 53 | import and otherwise transfer the Contribution of such Contributor, if 54 | any, in source code and object code form. This patent license shall 55 | apply to the combination of the Contribution and the Program if, at 56 | the time the Contribution is added by the Contributor, such addition 57 | of the Contribution causes such combination to be covered by the 58 | Licensed Patents. The patent license shall not apply to any other 59 | combinations which include the Contribution. No hardware per se is 60 | licensed hereunder. 61 | 62 | c) Recipient understands that although each Contributor grants the 63 | licenses to its Contributions set forth herein, no assurances are 64 | provided by any Contributor that the Program does not infringe the 65 | patent or other intellectual property rights of any other entity. Each 66 | Contributor disclaims any liability to Recipient for claims brought by 67 | any other entity based on infringement of intellectual property rights 68 | or otherwise. As a condition to exercising the rights and licenses 69 | granted hereunder, each Recipient hereby assumes sole responsibility 70 | to secure any other intellectual property rights needed, if any. For 71 | example, if a third party patent license is required to allow 72 | Recipient to distribute the Program, it is Recipient's responsibility 73 | to acquire that license before distributing the Program. 74 | 75 | d) Each Contributor represents that to its knowledge it has sufficient 76 | copyright rights in its Contribution, if any, to grant the copyright 77 | license set forth in this Agreement. 78 | 79 | 3. REQUIREMENTS 80 | 81 | A Contributor may choose to distribute the Program in object code form 82 | under its own license agreement, provided that: 83 | 84 | a) it complies with the terms and conditions of this Agreement; and 85 | 86 | b) its license agreement: 87 | 88 | i) effectively disclaims on behalf of all Contributors all warranties 89 | and conditions, express and implied, including warranties or 90 | conditions of title and non-infringement, and implied warranties or 91 | conditions of merchantability and fitness for a particular purpose; 92 | 93 | ii) effectively excludes on behalf of all Contributors all liability 94 | for damages, including direct, indirect, special, incidental and 95 | consequential damages, such as lost profits; 96 | 97 | iii) states that any provisions which differ from this Agreement are 98 | offered by that Contributor alone and not by any other party; and 99 | 100 | iv) states that source code for the Program is available from such 101 | Contributor, and informs licensees how to obtain it in a reasonable 102 | manner on or through a medium customarily used for software exchange. 103 | 104 | When the Program is made available in source code form: 105 | 106 | a) it must be made available under this Agreement; and 107 | 108 | b) a copy of this Agreement must be included with each copy of the 109 | Program. 110 | 111 | Contributors may not remove or alter any copyright notices contained 112 | within the Program. 113 | 114 | Each Contributor must identify itself as the originator of its 115 | Contribution, if any, in a manner that reasonably allows subsequent 116 | Recipients to identify the originator of the Contribution. 117 | 118 | 4. COMMERCIAL DISTRIBUTION 119 | 120 | Commercial distributors of software may accept certain 121 | responsibilities with respect to end users, business partners and the 122 | like. While this license is intended to facilitate the commercial use 123 | of the Program, the Contributor who includes the Program in a 124 | commercial product offering should do so in a manner which does not 125 | create potential liability for other Contributors. Therefore, if a 126 | Contributor includes the Program in a commercial product offering, 127 | such Contributor ("Commercial Contributor") hereby agrees to defend 128 | and indemnify every other Contributor ("Indemnified Contributor") 129 | against any losses, damages and costs (collectively "Losses") arising 130 | from claims, lawsuits and other legal actions brought by a third party 131 | against the Indemnified Contributor to the extent caused by the acts 132 | or omissions of such Commercial Contributor in connection with its 133 | distribution of the Program in a commercial product offering. The 134 | obligations in this section do not apply to any claims or Losses 135 | relating to any actual or alleged intellectual property 136 | infringement. In order to qualify, an Indemnified Contributor must: a) 137 | promptly notify the Commercial Contributor in writing of such claim, 138 | and b) allow the Commercial Contributor to control, and cooperate with 139 | the Commercial Contributor in, the defense and any related settlement 140 | negotiations. The Indemnified Contributor may participate in any such 141 | claim at its own expense. 142 | 143 | For example, a Contributor might include the Program in a commercial 144 | product offering, Product X. That Contributor is then a Commercial 145 | Contributor. If that Commercial Contributor then makes performance 146 | claims, or offers warranties related to Product X, those performance 147 | claims and warranties are such Commercial Contributor's responsibility 148 | alone. Under this section, the Commercial Contributor would have to 149 | defend claims against the other Contributors related to those 150 | performance claims and warranties, and if a court requires any other 151 | Contributor to pay any damages as a result, the Commercial Contributor 152 | must pay those damages. 153 | 154 | 5. NO WARRANTY 155 | 156 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS 157 | PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 158 | KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 159 | WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY 160 | OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely 161 | responsible for determining the appropriateness of using and 162 | distributing the Program and assumes all risks associated with its 163 | exercise of rights under this Agreement , including but not limited to 164 | the risks and costs of program errors, compliance with applicable 165 | laws, damage to or loss of data, programs or equipment, and 166 | unavailability or interruption of operations. 167 | 168 | 6. DISCLAIMER OF LIABILITY 169 | 170 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR 171 | ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, 172 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING 173 | WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 174 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 175 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR 176 | DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 177 | HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 178 | 179 | 7. GENERAL 180 | 181 | If any provision of this Agreement is invalid or unenforceable under 182 | applicable law, it shall not affect the validity or enforceability of 183 | the remainder of the terms of this Agreement, and without further 184 | action by the parties hereto, such provision shall be reformed to the 185 | minimum extent necessary to make such provision valid and enforceable. 186 | 187 | If Recipient institutes patent litigation against any entity 188 | (including a cross-claim or counterclaim in a lawsuit) alleging that 189 | the Program itself (excluding combinations of the Program with other 190 | software or hardware) infringes such Recipient's patent(s), then such 191 | Recipient's rights granted under Section 2(b) shall terminate as of 192 | the date such litigation is filed. 193 | 194 | All Recipient's rights under this Agreement shall terminate if it 195 | fails to comply with any of the material terms or conditions of this 196 | Agreement and does not cure such failure in a reasonable period of 197 | time after becoming aware of such noncompliance. If all Recipient's 198 | rights under this Agreement terminate, Recipient agrees to cease use 199 | and distribution of the Program as soon as reasonably 200 | practicable. However, Recipient's obligations under this Agreement and 201 | any licenses granted by Recipient relating to the Program shall 202 | continue and survive. 203 | 204 | Everyone is permitted to copy and distribute copies of this Agreement, 205 | but in order to avoid inconsistency the Agreement is copyrighted and 206 | may only be modified in the following manner. The Agreement Steward 207 | reserves the right to publish new versions (including revisions) of 208 | this Agreement from time to time. No one other than the Agreement 209 | Steward has the right to modify this Agreement. The Eclipse Foundation 210 | is the initial Agreement Steward. The Eclipse Foundation may assign 211 | the responsibility to serve as the Agreement Steward to a suitable 212 | separate entity. Each new version of the Agreement will be given a 213 | distinguishing version number. The Program (including Contributions) 214 | may always be distributed subject to the version of the Agreement 215 | under which it was received. In addition, after a new version of the 216 | Agreement is published, Contributor may elect to distribute the 217 | Program (including its Contributions) under the new version. Except as 218 | expressly stated in Sections 2(a) and 2(b) above, Recipient receives 219 | no rights or licenses to the intellectual property of any Contributor 220 | under this Agreement, whether expressly, by implication, estoppel or 221 | otherwise. All rights in the Program not expressly granted under this 222 | Agreement are reserved. 223 | 224 | This Agreement is governed by the laws of the State of New York and 225 | the intellectual property laws of the United States of America. No 226 | party to this Agreement will bring a legal action under this Agreement 227 | more than one year after the cause of action arose. Each party waives 228 | its rights to a jury trial in any resulting litigation. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reflector 2 | 3 | Sample app showing bespoke use of [datafy and 4 | nav](http://corfield.org/blog/2018/12/03/datafy-nav/). 5 | 6 | # Trying it 7 | 8 | Add this code to a running REPL that can do something useful with 9 | datafy and nav, 10 | e.g. [REBL](https://github.com/cognitect-labs/REBL-distro). You can 11 | add the code as a [git 12 | dep](https://clojure.org/guides/deps_and_cli#_using_git_libraries) or 13 | simply evaluate the namespaces. 14 | 15 | Then evaluate 16 | 17 | (com.stuarthalloway.reflector/on (find-ns 'clojure.core)) 18 | 19 | # What it Can Do 20 | 21 | Given a Clojure namespace, navigate quickly to 22 | 23 | * source code for a var 24 | * ClojureDocs for a var 25 | * origin SCM repository 26 | * code license 27 | * classpath resource the code was loaded from 28 | 29 | # Contributing 30 | 31 | Start with this code and make something better. 32 | 33 | # License 34 | 35 | EPL same as Clojure. 36 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src"] 2 | :deps {org.clojure/clojure {:mvn/version "1.10.0-RC5"}} 3 | :aliases 4 | {:dev {}}} 5 | -------------------------------------------------------------------------------- /src/com/stuarthalloway/reflector.clj: -------------------------------------------------------------------------------- 1 | ;; Copyright (c) Stuart Halloway 2 | ;; The use and distribution terms for this software are covered by the 3 | ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 4 | ;; which can be found in the file epl-v10.html at the root of this distribution. 5 | ;; By using this software in any fashion, you are agreeing to be bound by 6 | ;; the terms of this license. 7 | ;; You must not remove this notice, or any other, from this software. 8 | 9 | (ns com.stuarthalloway.reflector 10 | (:require 11 | [clojure.java.io :as io] 12 | [clojure.datafy :as dfy] 13 | [clojure.repl :as repl] 14 | [clojure.string :as str] 15 | [clojure.xml :as xml] 16 | [com.stuarthalloway.reflector.pom :as pom]) 17 | (:import 18 | [clojure.lang Namespace] 19 | [java.net URL])) 20 | 21 | (defprotocol Reflect 22 | (-reflect [_] "Impl detail, do not call")) 23 | 24 | (defn whence-ns? 25 | "Given a Clojure namespace, returns a map telling where its clj, cljc, 26 | and class file representation are visible on the classpath" 27 | [ns] 28 | (let [n (-> ns 29 | str 30 | (str/replace "." "/") 31 | (str/replace "-" "_"))] 32 | {:basename n 33 | :clj (io/resource (str n ".clj")) 34 | :cljc (io/resource (str n ".cljc")) 35 | :class (io/resource (str n "__init.class")) })) 36 | 37 | (defn- with-var-nav 38 | "Var navigation that returns vars as a map with possible keys 39 | 40 | :source 41 | :doc 42 | :clojuredocs" 43 | [v] 44 | (with-meta 45 | v 46 | {'clojure.core.protocols/nav 47 | (fn [_ k v] 48 | (if (var? v) 49 | (let [sym (.toSymbol v) 50 | ns (namespace sym) 51 | n (name sym)] 52 | (cond-> {:source (repl/source-fn sym) 53 | :doc (with-out-str (@#'clojure.repl/print-doc (meta v)))} 54 | 55 | (str/starts-with? ns "clojure") 56 | (assoc :clojuredocs (URL. (str "https://clojuredocs.org/" (namespace sym) "/" (name sym)))))) 57 | v))})) 58 | 59 | (extend-protocol Reflect 60 | Object 61 | (-reflect [_]) 62 | 63 | nil 64 | (-reflect [_] nil) 65 | 66 | clojure.lang.Namespace 67 | (-reflect 68 | [n] 69 | (let [resources (whence-ns? n) 70 | sum #(some-> % pom/guess-pom xml/parse pom/summary) 71 | pom (or (some-> resources :clj sum) 72 | (some-> resources :class sum))] 73 | (with-meta 74 | (cond-> (dfy/datafy n) 75 | resources (assoc :resources resources) 76 | pom (assoc :pom pom)) 77 | {'clojure.core.protocols/nav 78 | (fn [_ k v] 79 | (case k 80 | :publics (with-var-nav v) 81 | :interns (with-var-nav v) 82 | v))})))) 83 | 84 | (defn on 85 | "Reflect on x, maybe adding useful nav. Intended only for e.g. REBL 86 | browsing. There is no API contract here. I will change this." 87 | [x] 88 | (-reflect x)) 89 | 90 | -------------------------------------------------------------------------------- /src/com/stuarthalloway/reflector/coerce.clj: -------------------------------------------------------------------------------- 1 | ;; Copyright (c) Stuart Halloway 2 | ;; The use and distribution terms for this software are covered by the 3 | ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 4 | ;; which can be found in the file epl-v10.html at the root of this distribution. 5 | ;; By using this software in any fashion, you are agreeing to be bound by 6 | ;; the terms of this license. 7 | ;; You must not remove this notice, or any other, from this software. 8 | 9 | (ns com.stuarthalloway.reflector.coerce 10 | (:require [clojure.string :as str]) 11 | (:import 12 | [java.io File] 13 | [java.net URL])) 14 | 15 | (defn urlify 16 | [s] 17 | (if (string? s) 18 | (if (str/starts-with? s "http") 19 | (try 20 | (URL. s) 21 | (catch Throwable _ 22 | s)) 23 | s) 24 | s)) 25 | 26 | -------------------------------------------------------------------------------- /src/com/stuarthalloway/reflector/pom.clj: -------------------------------------------------------------------------------- 1 | ;; Copyright (c) Stuart Halloway 2 | ;; The use and distribution terms for this software are covered by the 3 | ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 4 | ;; which can be found in the file epl-v10.html at the root of this distribution. 5 | ;; By using this software in any fashion, you are agreeing to be bound by 6 | ;; the terms of this license. 7 | ;; You must not remove this notice, or any other, from this software. 8 | 9 | (ns com.stuarthalloway.reflector.pom 10 | (:require 11 | [clojure.java.io :as io] 12 | [clojure.string :as str] 13 | [clojure.xml :as xml] 14 | [clojure.zip :as zip] 15 | [com.stuarthalloway.reflector.coerce :as coerce]) 16 | (:import 17 | [java.io File] 18 | [java.net URL])) 19 | 20 | (defn guess-pom 21 | "Given a URL, try to guess the associated pom." 22 | [url] 23 | (when (instance? URL url) 24 | (some-> (.getFile url) 25 | (str/replace #"^file:" "") 26 | (str/replace #"!.*" "") 27 | (str/replace #".jar$" ".pom") 28 | (as-> maybe-pom 29 | (when-let [pom-file (and (str/ends-with? maybe-pom ".pom") 30 | (io/file maybe-pom))] 31 | (when (.exists pom-file) 32 | pom-file)))))) 33 | 34 | (defn pom-contents 35 | [url] 36 | (when-let [^File pom (guess-pom url)] 37 | (when (.exists pom) 38 | (slurp pom)))) 39 | 40 | (def extractors 41 | (let [content (comp coerce/urlify first :content zip/node) 42 | child-content (fn [node ks] 43 | (reduce 44 | (fn [m {:keys [tag] :as node}] 45 | (if (ks tag) 46 | (assoc m tag (-> node :content first coerce/urlify)) 47 | m)) 48 | {} 49 | (:content node))) 50 | children-content (fn [keyset] 51 | (fn [node] 52 | (mapv #(child-content % keyset) (zip/children node))))] 53 | {:url content 54 | :description content 55 | :developers (children-content #{:name :email}) 56 | :licenses (children-content #{:name :url :distribution}) 57 | :scm #(child-content (zip/node %) #{:connection :developerConnection :url :tag}) 58 | :dependencies (children-content #{:groupId :artifactId :version :scope})})) 59 | 60 | (defn summary 61 | [xml] 62 | (let [zip (zip/xml-zip xml)] 63 | (reduce 64 | (fn [m zipper] 65 | (let [{:keys [tag] :as node} (zip/node zipper)] 66 | (if-let [extractor (extractors tag)] 67 | (assoc m tag (extractor zipper)) 68 | m))) 69 | {} 70 | (->> (zip/down zip) 71 | (iterate zip/right) 72 | (take-while identity))))) 73 | --------------------------------------------------------------------------------