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 ohm | |
(:require [clojure.string :as string] | |
[clojure.java.io :refer [as-file]]) | |
(:import [java.io File])) | |
(defrecord Leaf [nss declares fns]) | |
(defn parse-value [value] | |
value) | |
(defn compare-value [v1 v2] | |
(compare (parse-value v1) (parse-value v2))) | |
(defn insert! [data item] | |
(if (nil? data) | |
(Leaf. [(:ns item)] [(:name item)] (sorted-set-by compare-value (:source item))) | |
(let [nss (conj (:nss data) (:ns item)) | |
declares (conj (:declares data) (:name item)) | |
fns (conj (:fns data) (:source item))] | |
(assoc data :nss nss :declares declares :fns fns)))) | |
(defn parse-ns-name [value] | |
(string/split value #"\.")) | |
(defn parse [base key namespace value] | |
(update-in base | |
(concat [key] (parse-ns-name namespace)) | |
#(insert! % value))) | |
;;;;;;;;;;;; | |
; Output | |
;;;;;;;;;;;; | |
(defn layout-data [data] | |
(if (not (instance? Leaf data)) | |
(list data) | |
(lazy-cat (map #(:source %) (:nss data)) ; ns | |
(map #(str "(declare " % ")") (:declares data)) ; declare | |
(:fns data)))) | |
(defn format-name [value] (string/replace value "-" "_")) | |
(defn write! [base-path data] | |
(let [keys (keys data) | |
leaves (filter #(instance? Leaf (data %)) keys) | |
nodes (filter #(not (instance? Leaf (data %))) keys) | |
base-file (as-file base-path)] | |
(dorun (map #(spit (str base-path File/separator (format-name %) ".clj") | |
(string/join "\n" (layout-data (data %)))) | |
leaves)) | |
(for [n nodes] | |
(let [new-path (str base-path File/separator (format-name n)) | |
new-file (as-file new-path)] | |
(if (not (.exists new-file)) (.mkdir new-file)) | |
(write! new-path (data n)))))) | |
; Usage | |
(def project (map->Leaf {:fns ["(defproject tester1 \"0.1.0-SNAPSHOT\" :dependencies [[org.clojure/clojure \"1.5.1\"]])"]})) | |
(def base {"src" {} | |
"test" {} | |
"project" project}) | |
(def ns1 {:name "tester1.core" :source "(ns tester1.core)"}) | |
(def ns2 {:name "tester1.server" :source "(ns tester1.server (:require [tester1.core :as c]))"}) | |
(def fn1 {:name "thing1" :source "(defn thing1 [] true)" :ns ns1}) | |
(def fn2 {:name "thing2" :source "(defn thing2 [] true)" :ns ns1}) | |
(def fn3 {:name "thing3" :source "(defn thing3 [] true)" :ns ns2}) | |
(def data [fn1 fn2 fn3]) | |
(def result | |
(reduce #(parse %1 "src" (:name (:ns %2)) %2) | |
base | |
data)) | |
;(write! "/Users/user1/Desktop/tester1" result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment