git.fiddlerwoaroof.com
porcelain.lisp
991d0162
 (in-package :fwoar.cl-git)
 
 (defvar *git-repository* nil
   "The git repository path for porcelain commands to operate on.")
 (defvar *git-encoding* :utf-8
   "The encoding to use when parsing git objects")
 
e623be68
 (defun git:in-repository (root)
   (setf *git-repository*
         (truename root)))
 
ad9b8a82
 (defun git:show-repository ()
   *git-repository*)
 
821ddf96
 (defun in-git-package (symbol)
   (intern (symbol-name symbol)
           :git))
 
0b3ed859
 (defmacro git:git (&rest commands)
   `(uiop:nest ,@(reverse
0c24c8f9
                  (mapcar (serapeum:op
                            (typecase _1
                              (string `(identity ,_1))
                              (list (case (in-git-package (car _1))
                                      (git::unwrap `(uiop:nest (car)
                                                               (mapcar ,@(cdr _1))))
                                      (t (cons (in-git-package (car _1)) 
                                               (cdr _1)))))))
0b3ed859
                          commands))))
 
821ddf96
 (defun git::<<= (fun &rest args)
   (apply #'mapcan fun args))
 
0c24c8f9
 (defun git::map (fun &rest args)
   (apply #'mapcar fun args))
 
e623be68
 (defun git:show (object)
   (babel:octets-to-string
bc7ccfbd
    (coerce (extract-object-next (object (repository *git-repository*)
                                         object))
0b3ed859
            '(vector serapeum:octet))
e623be68
    :encoding *git-encoding*))
 
5cb25684
 (defun git:contents (object)
   (git:show object))
 
 (defstruct (tree-entry (:type vector))
   te-name te-mode te-id)
 
 (defun git:tree (commit)
   (cadr (fw.lu:v-assoc "tree"
                        (nth-value 1 (parse-commit commit))
                        :test 'equal)))
 
 (defun git::filter-tree (name-pattern tree)
   #+lispworks
   (declare (notinline serapeum:string-prefix-p))
   (let* ((lines (fwoar.string-utils:split #\newline tree))
          (columns (map 'list
                        (serapeum:op
                          (coerce (fwoar.string-utils:split #\tab _)
                                  'simple-vector))
                        lines)))
     (remove-if-not (serapeum:op
821ddf96
                      (cl-ppcre:scan name-pattern _ ))
5cb25684
                    columns
                    :key #'tree-entry-te-name)))
 
821ddf96
 (defun git:branch (&optional (branch :master))
0b3ed859
   #+lispworks
   (declare (notinline serapeum:assocadr))
e623be68
   (let ((branches (branches (repository *git-repository*))))
821ddf96
     (nth-value 0 (serapeum:assocadr (etypecase branch
                                       (string branch)
                                       (keyword (string-downcase branch)))
                                     branches
e623be68
                                     :test 'equal))))
 
 (defun git:branches ()
   (branches (repository *git-repository*)))
 
 (defun git:commit-parents (commit)
   (map 'list #'cadr
        (remove-if-not (serapeum:op
                         (string= "parent" _))
                       (nth-value 1
                                  (fwoar.cl-git::parse-commit
                                   (git:show commit)))
                       :key #'car)))