Skip to content

Instantly share code, notes, and snippets.

@pmonks
Last active August 9, 2021 20:40
Show Gist options
  • Save pmonks/982ce90dac11a4cefe45378c0db3d555 to your computer and use it in GitHub Desktop.
Save pmonks/982ce90dac11a4cefe45378c0db3d555 to your computer and use it in GitHub Desktop.
Get the namespaces for one or more Clojure deps
;/*********************************************************************
;* Copyright (c) 2021-01-12 Peter Monks
;*
;* This program and the accompanying materials are made
;* available under the terms of the Eclipse Public License 2.0
;* which is available at https://www.eclipse.org/legal/epl-2.0/
;*
;* SPDX-License-Identifier: EPL-2.0
;**********************************************************************/
; To start from the command line:
;
; clj -Sdeps '{:deps {org.clojure/tools.deps.alpha {:mvn/version "0.12.1003"} org.clojure/tools.namespace {:mvn/version "1.1.0"} find-deps/find-deps {:git/url "https://github.com/hagmonk/find-deps" :sha "9bf23a52cb0a8190c9c2c7ad1d796da802f8ce7a"}}}'
(require '[clojure.java.io :as io])
(require '[clojure.tools.deps.alpha :as tda])
(require '[clojure.tools.namespace.find :as tnsf])
(defn namespaces-for-deps!
"Determines the namespaces provided by the given dep(s). Both the argument and result are dep maps in tools.deps.alpha format e.g.
{http-kit/http-kit {:mvn/version \"2.5.0\"}
ring/ring {:mvn/version \"1.8.2\"}}
The result will add a :nses key to each dependency e.g.
{http-kit/http-kit {:mvn/version \"2.5.0\" :nses [org.httpkit.timer org.httpkit.client org.httpkit.encode org.httpkit.server org.httpkit.sni-client]}
ring/ring {:mvn/version \"1.8.2\" :nses []}}
Notes:
* Has the side effect of downloading each dependency's artifact(s), as well as (recursively) all artifacts they depend on.
* As currently written, only supports libraries hosted on Maven central, Clojars, and GitHub. I think this is easy to change, by accepting a full deps.edn map, instead of just the :deps map within it.
* As currently written, doesn't maintain the association between individual JAR files / directories within a dependency and namespace(s). This would be easy enough to do, but complicates the output and didn't seem necessary."
[deps]
(let [tda-deps {:mvn/repos {"central" {:url "https://repo1.maven.org/maven2/"}
"clojars" {:url "https://repo.clojars.org/"}}
:deps deps}
resolved-deps (select-keys (tda/resolve-deps tda-deps nil) (keys deps))]
(apply merge (map (fn [[dep attr]] {dep (assoc attr :nses (vec (tnsf/find-namespaces (map io/file (:paths attr)))))}) resolved-deps))))
; Example usages
(namespaces-for-deps! {'http-kit/http-kit {:mvn/version "2.5.0"}
'ring/ring {:mvn/version "1.8.2"}}) ; Note: ring/ring has no namespaces itself - it's a dependency placeholder for other ring dependencies
(namespaces-for-deps! {'seancorfield/depstar {:git/url "https://github.com/seancorfield/depstar" :sha "4a4207a17be496f6ac228775a7d968afd1f9164f"}})
; Use it in conjunction with the handy 'find-deps' library (https://github.com/hagmonk/find-deps)
(require '[find-deps.core :as fd])
(namespaces-for-deps! (:deps (fd/deps "http-kit" "ring")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment