git.fiddlerwoaroof.com
tree.lisp
4cc1ee49
 (in-package :fwoar.cl-git)
 
 (defclass git-tree (git-object)
   ((%entries :initarg :entries :reader entries)))
 
 (defun git-tree (entries)
   (fw.lu:new 'git-tree entries))
 
489818ad
 (defclass tree-entry (git-object)
216c17e7
   ((%repo :initarg :repo :reader repository)
    (%mode :initarg :mode :reader te-mode)
489818ad
    (%name :initarg :name :reader te-name)))
4cc1ee49
 
216c17e7
 (defun tree-entry (repo name mode hash)
   (fw.lu:new 'tree-entry repo name mode hash))
4cc1ee49
 
 (defmethod print-object ((o tree-entry) s)
   (if *print-readably*
       (format s "#.(~s ~s ~s ~s)"
               'tree-entry
               (te-name o)
               (te-mode o)
b7739814
               (hash o))
4cc1ee49
       (print-unreadable-object (o s :type t :identity t)
         (format s "(~a: ~a)"
                 (te-name o)
c66be8cf
                 (subseq (hash o) 0 8)))))
4cc1ee49
 
 (defun parse-tree-entry (data)
   (values-list (partition 0 data :with-offset 20)))
 
216c17e7
 (defun format-tree-entry (repo entry)
4cc1ee49
   (destructuring-bind (info sha) (partition 0 entry)
216c17e7
     (destructuring-bind (mode name)
         (partition #\space
                    (babel:octets-to-string info :encoding *git-encoding*))
       (tree-entry repo name mode (elt (->sha-string sha) 0)))))
4cc1ee49
 
216c17e7
 (defun tree-entries (repo data &optional accum)
4cc1ee49
   (if (<= (length data) 0)
       (nreverse accum)
       (multiple-value-bind (next rest) (parse-tree-entry data)
41ea4583
         (tree-entries repo
                       rest
216c17e7
                       (list* (format-tree-entry repo next)
4cc1ee49
                              accum)))))
 
 (defmethod -extract-object-of-type ((type (eql :tree)) s repository &key)
216c17e7
   (git-tree (tree-entries repository s)))
4cc1ee49
 
 (defmethod component ((component (eql :entries)) (object git-tree))
   (entries object))
 (defmethod component ((component string) (object git-tree))
216c17e7
   (car (remove component (entries object)
                :test-not #'equal
                :key 'te-name)))
4cc1ee49
 (defmethod component ((component pathname) (object git-tree))
   (remove-if-not (lambda (it)
                    (pathname-match-p it component))
                  (entries object)
                  :key 'te-name))
 
 (defmethod component ((component (eql :name)) (object tree-entry))
   (te-name object))
 (defmethod component ((component (eql :mode)) (object tree-entry))
   (te-mode object))
216c17e7
 (defmethod component ((component (eql :ref)) (object tree-entry))
   (ref (repository object)
b7739814
        (hash object)))