Last active
October 6, 2022 20:46
-
-
Save simon-brooke/2185e7da258de24b1466f4d1b5c2b103 to your computer and use it in GitHub Desktop.
Convert leiningen project.clj into clojure.cli deps.edn
This file contains 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
(ns migrate | |
" | |
## Leiningen to deps.edn migration tool | |
I'm as yet unpersuaded of the merits of `deps.edn` vis-a-vis leiningen. | |
Leiningen puts all the metadata about your project and how to build it | |
in one place in a clear, well understood and easily-extensible format. | |
The `deps.edn` format intentionally does not. | |
Worse, `clojure.cli` uses a subtly but significantly different algorithm | |
for resolving dependencies from that used by leiningen, meaning that | |
projects using `deps.edn` do not play nice with leiningen projects. | |
Worse yet, `clojure.cli` does not provide a standardised means of providing | |
metadata other than dependencies and paths. This means that the | |
standardised build automation which makes leiningen projects so easy to | |
hack on is lost, as each project gets its own idiosyncratic build | |
scripting using a maze of twisty little build tools, all different. | |
However, be that as it may, to use projects which are built directly | |
from git repositories, it's presently easier to use `deps.edn`, so I found | |
it useful to have a migration tool. | |
Public domain. No warranty, if it breaks you get to keep all the parts." | |
(:require [clojure.pprint :refer [pprint]] | |
[clojure.java.io :refer [writer]]) | |
(:import [java.io FileNotFoundException])) | |
(defn transform-dependencies | |
"Transform the vector of pairs format used by leiningen into the map | |
format used by `deps.edn`. Be wary printing the results of this. There's | |
some REALLY WEIRD SHIT between the Clojure reader and printer | |
here, which does not do what you expect!" | |
[project] | |
(into {} | |
(map #(vector (first %) {:mvn/version (second %)}) | |
(:dependencies project)))) | |
(defn transform-paths | |
"It appears that `deps.edn` wants resource paths included on the paths value." | |
[project] | |
(concat (:source-paths project) (:resource-paths project))) | |
(defn transform | |
[project deps] | |
(let [projectmap (apply hash-map (rest project))] | |
(merge-with deps | |
(assoc {} | |
:deps (transform-dependencies projectmap) | |
:paths (transform-paths projectmap))))) | |
(defn leiningen->deps | |
"Read leiningen project file (defaults to `project.clj`), write a `deps.edn` file" | |
([] (leiningen->deps "project.clj")) | |
([filename] (leiningen->deps filename "deps.edn")) | |
([infile outfile] | |
(let [deps (transform (read-string (slurp infile)) | |
(try (read-string (slurp outfile)) | |
(catch FileNotFoundException _ {})))] | |
;; thanks to @puredanger for this hint! | |
(binding [*print-namespace-maps* false] | |
(pprint deps (writer outfile))) | |
deps))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment