Created
April 17, 2020 09:54
-
-
Save setzer22/af1197b366f562408fae3e5aaa6a837a to your computer and use it in GitHub Desktop.
Clojure: Find out the namespaces that are not transitive dependencies of a namespace in your project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Meant to be run on a REPL, this small script will find all the namespaces that are not transitively required | |
;; by a parent ns. This may be useful if you need to extract a small application from a huge monolithic project. | |
;; This code has been adapted from https://github.com/hilverd/lein-ns-dep-graph and distributed under the same license. | |
;; Note that this only looks at the ns declarations, but has no way to detect dependencies that are dynamically built | |
;; (e.g. by requiring a symbol created from a string using a plain `require`). | |
(do | |
(import [java.io PushbackReader]) | |
(require '[clojure.java.io :as io]) | |
(require '[clojure.set :as set]) | |
(require '[clojure.edn :as edn]) | |
(require '[clojure.tools.namespace.file :as ns-file]) | |
(require '[clojure.tools.namespace.track :as ns-track]) | |
(require '[clojure.tools.namespace.find :as ns-find]) | |
(require '[clojure.tools.namespace.dependency :as ns-dep])) | |
(defn transitive-deps-of [source-paths, ns-parents] | |
(let [source-files (apply set/union | |
(map #(ns-find/find-sources-in-dir %) | |
(file-seq source-paths))) | |
tracker (ns-file/add-files {} source-files) | |
dep-graph (tracker ::ns-track/deps) | |
ns-names (set (map (comp second ns-file/read-file-ns-decl) | |
source-files)) | |
part-of-project? (partial contains? ns-names) | |
part-of-parents? #(or (empty? ns-parents) | |
(contains? ns-parents %) | |
(boolean (seq (set/intersection ns-parents (ns-dep/transitive-dependents dep-graph %))))) | |
nodes (->> (ns-dep/nodes dep-graph) | |
(filter part-of-project?) | |
(filter part-of-parents?))] | |
nodes)) | |
(let [source-paths (io/file "/path/to/my/project/src/main/clojure/")] | |
(set/difference | |
(set (transitive-deps-of source-paths #{'my.parent.ns})) | |
(set (transitive-deps-of source-paths #{})))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment