Skip to content

Instantly share code, notes, and snippets.

@codeasone
Last active November 11, 2020 14:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeasone/06f23dc9f1849c85d0b82329a64d3481 to your computer and use it in GitHub Desktop.
Save codeasone/06f23dc9f1849c85d0b82329a64d3481 to your computer and use it in GitHub Desktop.
Maintaining order of namespace :require forms via pre-commit hook

Adapted from: https://github.com/babashka/pod-babashka-parcera/blob/master/examples/sort_requires.clj

./script/format.bb

#!/usr/bin/env bb
(require '[babashka.pods :as pods])
(pods/load-pod "pod-babashka-parcera")
(require '[pod.babashka.parcera :as parcera])

(defn sort-ns [node]
  (if (seq? node)
    (if (and (= :list (first node))
             (= '(:keyword ":require") (second node)))
      (let [children (nnext node)
            first-whitespace (some #(when (= :whitespace (first %)) %) children)
            children (remove #(= :whitespace (first %)) children)
            loc (meta (first children))
            start (-> loc :parcera.core/start :column)
            whitespace (str (apply str "\n" (repeat start " ")))
            children (sort-by (comp str parcera/code) children)
            children (butlast (interleave children (repeat (list :whitespace whitespace))))]
        (cons :list (cons '(:keyword ":require") (cons first-whitespace children))))
      (cons (first node) (map sort-ns (rest node))))
    node))

(defn format-file
  [filename]
  (let [parsed (parcera/ast (slurp filename))
        processed (parcera/code (sort-ns parsed))]
    (spit filename processed)
    ))

(when-let [[& files] *command-line-args*]
  (doseq [file files]
    (prn "Processing: " file)
    (format-file file)))

.git/hooks/pre-commit

#!/bin/sh
# https://github.com/magit/magit/issues/3419#issuecomment-380255939
unset GIT_LITERAL_PATHSPECS
FILES=$(git diff --cached --name-only --diff-filter=ACMR "*.clj" "*.cljc" "*.cljs" | sed 's| |\\ |g')
[ -z "$FILES" ] && exit 0

# Prettify all selected files
echo "$FILES" | xargs ./script/format.bb

# Add back the modified/prettified files to staging
echo "$FILES" | xargs git add

exit 0

.git/hooks/post-commit

#!/bin/sh
# https://github.com/magit/magit/issues/3419#issuecomment-380255939
unset GIT_LITERAL_PATHSPECS
git update-index -g
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment