git.fiddlerwoaroof.com
graph.lisp
582a22c6
 (defpackage :co.fwoar.cl-git.graph
   (:use :cl :fwoar.cl-git)
   (:export ))
 (in-package :co.fwoar.cl-git.graph)
991d0162
 
 (defclass git-graph ()
   ((%repo :initarg :repo :reader repo)
    (%depth :initarg :depth :reader depth)
582a22c6
    (%stops :initarg :stops :reader stops :initform ())
991d0162
    (%branches :reader branches)
    (%node-cache :reader node-cache :initform (make-hash-table :test 'equal))
    (%edge-cache :reader edge-cache :initform (make-hash-table :test 'equal))))
 
 (defmethod initialize-instance :after ((object git-graph) &key)
582a22c6
   (setf
    (slot-value object '%branches)
    (fw.lu:alist-string-hash-table
     (funcall (data-lens:over
               (data-lens:<>1 (data-lens:applying #'cons)
                              (data-lens:transform-head
                               (serapeum:op (subseq _1 0
                                                    (min (length _1)
                                                         8))))
                              #'reverse))
              (fwoar.cl-git::branches (repo object))))))
991d0162
 
 (defun git-graph (repo)
   (fw.lu:new 'git-graph repo))
 
 (defun get-commit-parents (repository commit)
0b3ed859
   #+lispworks
   (declare (notinline mismatch serapeum:string-prefix-p))
582a22c6
   (when commit
     (co.fwoar.git:with-repository (repository)
       (alexandria:when-let*
           ((ref (fwoar.cl-git:ensure-ref commit))
            (direct-obj (fwoar.cl-git::extract-object
                         ref))
            (obj (etypecase direct-obj
                   (fwoar.cl-git::delta
                    (fwoar.cl-git::-extract-object-of-type
                     :commit
                     (fwoar.cl-git::trace-bases
                      (fwoar.cl-git::packed-ref-pack
                       ref)
                      direct-obj)
                     fwoar.cl-git::*git-repository*
                     :hash (fwoar.cl-git::ref-hash ref)))
                   (fwoar.cl-git::git-object
                    direct-obj)))
            (parents (fwoar.cl-git:component
                      :parents
                      obj)))
         (when parents
           parents)))))
991d0162
 
 (defmethod cl-dot:graph-object-node ((graph git-graph) (commit string))
582a22c6
   (alexandria:ensure-gethash
    commit
    (node-cache graph)
    (make-instance 'cl-dot:node
                   :attributes `(:label ,(gethash #1=(subseq commit 0 8)
                                                  (branches graph)
                                                  #1#)))))
991d0162
 
582a22c6
 (defmethod cl-dot:graph-object-points-to
     ((graph git-graph) (commit string))
   (unless (member commit (stops graph)
                   :test 'serapeum:string-prefix-p)
     (funcall (data-lens:<>1
               (data-lens:over (serapeum:op
                                 (setf (gethash (list commit _1)
                                                (edge-cache graph))
                                       t)
                                 _1))
               (data-lens:exclude (serapeum:op
                                    (gethash (list commit _1)
                                             (edge-cache graph))))
               (data-lens:over (serapeum:op (subseq _ 0 8))))
              (get-commit-parents (repo graph) commit))))