Skip to content

Instantly share code, notes, and snippets.

@crisptrutski
Created May 24, 2014 00:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crisptrutski/edf29f36a8c89e282c42 to your computer and use it in GitHub Desktop.
Save crisptrutski/edf29f36a8c89e282c42 to your computer and use it in GitHub Desktop.
Change project.clj version using sjacket + clojure.walk
(defn form->operation
"Given sjacket nodes for a form, return name of the operation.
Assumes operation is a literal."
[nodes]
(->> nodes
(filter #(= :symbol (:tag %))) first :content
(filter #(= :name (:tag %))) first :content
first))
(defn replace-string
"Replace first string node in form with given node"
[[head & tail] replacement]
(when head
(if (= :string (:tag head))
(cons replacement tail)
(cons head (replace-string tail replacement)))))
(defn replace-version
"Given sjacket nodes for defproject form, replace the version"
[version-node nodes]
(if (and (coll? nodes)
(= "(" (first (filter string? nodes)))
(= "defproject" (form->operation nodes)))
;; note, we stringify here again, in case of nested defprojects (worth considering?)
(map sj/str-pt (replace-string nodes version-node))
nodes))
(defn change-version
"Given a project.clj string, replace the version"
[project-str new-version]
(let [tree (p/parser project-str)
string (str "\"" new-version "\"")
mapper (partial replace-version string)]
(sj/str-pt (w/prewalk mapper tree))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment