Last active
December 17, 2015 18:49
-
-
Save Jared314/5655934 to your computer and use it in GitHub Desktop.
Storing a parse tree, or AST, in a git repository with Clojure and JGit
This file contains hidden or 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 gittree.core | |
(:require [clojure.java.io :refer [as-file]] | |
[instaparse.core :as insta] | |
[net.cgrand.enlive-html :as enlive] | |
[clojure.walk :as walk] | |
[clj-jgit.porcelain :as git]) | |
(:import [gittree TreeIterator]) | |
(:gen-class)) | |
(defn render [nodes] | |
(walk/postwalk #(if (and (map? %) (:tag %)) | |
(hash-map (:tag %) (:content %)) | |
%) nodes)) | |
(defn transform-data [data] | |
(enlive/at data | |
;[:S] enlive/unwrap | |
[:A] nil ;remove A nodes | |
)) | |
(def parse (insta/parser | |
"S = AB* | |
AB = A B | |
A = 'a'+ | |
B = 'b'+" | |
:output-format :enlive)) | |
(defn -main [& args] | |
(let [dir (as-file "/Users/user1/Desktop/testrepo") | |
text "aaaaabbbaaaabb" | |
g (if (.exists dir) | |
(git/load-repo dir) | |
(git/git-init dir)) | |
data (render (transform-data (parse text))) | |
itr (TreeIterator. (.getRepository g) data)] | |
(println text) | |
(println data) | |
(git/git-add g "." false itr) | |
(git/git-commit g "commit 1"))) |
This file contains hidden or 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
(defproject gittree "0.1.0-SNAPSHOT" | |
:description "FIXME: write description" | |
:url "http://example.com/FIXME" | |
:license {:name "Eclipse Public License" | |
:url "http://www.eclipse.org/legal/epl-v10.html"} | |
:dependencies [[org.clojure/clojure "1.5.1"] | |
[clj-jgit "0.3.9"] | |
[instaparse "1.2.2"] | |
[enlive "1.1.1"]] | |
:main gittree.core | |
:aot [gittree.TreeIterator]) |
This file contains hidden or 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 gittree.TreeIterator | |
(:import [org.eclipse.jgit.lib Repository FileMode] | |
[org.eclipse.jgit.treewalk WorkingTreeIterator WorkingTreeIterator$Entry WorkingTreeOptions] | |
[java.io ByteArrayInputStream]) | |
(:gen-class :extends org.eclipse.jgit.treewalk.WorkingTreeIterator | |
:init init2 | |
:post-init postinit | |
:state state | |
:constructors {[org.eclipse.jgit.lib.Repository Object] [org.eclipse.jgit.treewalk.WorkingTreeOptions] | |
[org.eclipse.jgit.lib.Repository Object org.eclipse.jgit.treewalk.WorkingTreeIterator] [org.eclipse.jgit.treewalk.WorkingTreeIterator]})) | |
(gen-interface :name gittree.IHasValue | |
:methods [[getValue [] Object]]) | |
(defn toEntry | |
([[k v]] (toEntry k v)) | |
([k v] | |
(let [node-name (if (keyword? k) (name k) (str k)) | |
node-mode (if (coll? v) FileMode/TREE FileMode/REGULAR_FILE) | |
node-modified 0 | |
node-value (if (string? v) (.getBytes v) (byte-array 0)) | |
node-length (count node-value)] | |
(proxy [WorkingTreeIterator$Entry gittree.IHasValue] [] | |
(getMode [] node-mode) | |
(getName [] node-name) | |
(getLength [] node-length) | |
(getLastModified [] node-modified) | |
(openInputStream [] (ByteArrayInputStream. node-value)) | |
(getValue [] v))))) | |
(defn -init2 | |
([^Repository repo data] | |
(let [options (-> repo (.getConfig) (.get WorkingTreeOptions/KEY))] | |
[[options] {:repo repo}])) | |
([^Repository repo data ^WorkingTreeIterator itr] | |
[[itr] {:repo repo}])) | |
(defn -postinit | |
([this repo data] (-postinit this repo data nil)) | |
([this repo data _] | |
(let [entries (if (map? data) (map toEntry data) (map-indexed toEntry data))] | |
(.initRootIterator this repo) | |
(.init this (into-array WorkingTreeIterator$Entry entries))))) | |
(defn -createSubtreeIterator [this reader idBuffer] | |
(let [repo (:repo (.state this))] | |
(gittree.TreeIterator. repo (.getValue (.current this)) this))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment