Skip to content

Instantly share code, notes, and snippets.

@kirked
Last active July 23, 2024 12:55
Show Gist options
  • Save kirked/900ef28311dd15243bc29ea816ba2558 to your computer and use it in GitHub Desktop.
Save kirked/900ef28311dd15243bc29ea816ba2558 to your computer and use it in GitHub Desktop.
Make deps.edn from project.clj - babashka script
#!/usr/bin/env bb
(require '[babashka.fs :as fs])
(require '[clojure.pprint :refer [pprint] :as pprint])
(defn warn
[& args]
(binding [*out* *err*]
(apply println args)))
(defn debug
[it]
(binding [*out* *err*]
(println "DEBUG- it:" (pr-str it))))
(defn ensure-namespaced
[dep-sym]
(if (str/includes? (str dep-sym) "/")
dep-sym
(symbol (str dep-sym "/" dep-sym))))
(defn lein->deps
"Converts a single lein-formatted dep to deps.edn form."
[[dep version & rest]]
(let [ns-dep (ensure-namespaced dep)
opts {:mvn/version version}]
(if (even? (count rest))
[ns-dep (reduce #(assoc %1 (first %2) (second %2)) opts (partition 2 rest))]
(do
(warn "WARNING: extra data not converted for" ns-dep version "\nignored:" (pr-str rest))
[ns-dep opts]))))
(defn lein-to-deps
"Converts project.clj content to deps.edn form."
[proj-clj-content]
(some->> proj-clj-content
(drop-while #(not= :dependencies %))
(second)
(map lein->deps)
(reduce (fn [m [dep opts]] (assoc m dep opts)) {})))
(defn deps-aliases
[project-dir]
(let [extra-paths (cond-> []
(fs/exists? (str project-dir "/test"))
(conj "test")
(fs/exists? (str project-dir "/src/test"))
(conj "src/test")
(fs/exists? (str project-dir "/dev-resources"))
(conj "dev-resources")
:always
(pr-str))]
(format "\n :aliases
{:test {:extra-paths %s
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag \"v0.5.1\" :git/sha \"dfb30dd\"}}
:main-opts [\"-m\" \"cognitect.test-runner\"]
:exec-fn cognitect.test-runner.api/test}}" extra-paths)))
(defn write-deps-deps
[deps]
(let [dep-max-width (some->> deps
(keys)
(map (comp count str))
(apply max))
dep-width (let [base-width (-> dep-max-width
(or 0)
(max 59)
(+ 2))]
(if (odd? base-width) (dec base-width) base-width))
dep-format (str "%-" dep-width "s %s")
deps (into (sorted-map) deps)]
(print " {")
(let [[dep opts] (first deps)]
(println (format dep-format dep (pr-str opts))))
(doseq [[dep opts] (next deps)]
(println " " (format dep-format dep (pr-str opts))))
(println " }")))
(defn write-deps-edn
[target-path deps]
(binding [*print-namespace-maps* false
pprint/*print-miser-width* 10
pprint/*print-right-margin* 120]
(let [dir (fs/parent target-path)
pretty-content (with-out-str
(println
(str "{"
(if (fs/exists? (str dir "/resources"))
":paths [\"src\" \"resources\"]\n\n :deps"
":deps")))
(write-deps-deps deps)
(println (deps-aliases dir))
(println "}"))]
(spit target-path pretty-content)
(warn "created" target-path))))
(defn clean-reader-macros
[content]
(str/replace content #"#\".*?\"" "")) ;; remove regex literals
(defn main
[]
(if-let [proj-clj-path (first *command-line-args*)]
(if (fs/exists? proj-clj-path)
(let [target-file (str (or (fs/parent proj-clj-path) ".") "/deps.edn")]
(if (fs/exists? target-file)
(do
(warn target-file " already exists.")
(System/exit 1))
(do
(warn "processing" proj-clj-path)
(some->> proj-clj-path
(slurp)
(clean-reader-macros)
(edn/read-string)
(lein-to-deps)
(write-deps-edn target-file)))))
(do
(warn "file" proj-clj-path "does not exist")
(System/exit 1)))
(do
(warn "Usage: mk-deps {project.clj path}")))) ;
(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment