git.fiddlerwoaroof.com
sheeple-protos.lisp
0db897a4
 (in-package :jira-api)
 
 (defun ensure-parent (object parent &key (err-if-nil t))
   (when (and (not err-if-nil) (null object))
     (return-from ensure-parent object))
 
   (unless (sheeple:parentp parent object)
     (push parent (sheeple:object-parents object))
     (sheeple:shared-init object))
   object)
 
 (sheeple:defproto =status= () (name))
 (sheeple:defproto =person= () (displayname emailaddress))
 (sheeple:defproto =issue= () (fields key id self))
3460d29f
 (sheeple:defproto =fields= () (summary description reporter creator assignee status comment))
9cc3714b
 (sheeple:defproto =issues= () (issues))
0db897a4
 (sheeple:defmessage show (object &rest args))
 (sheeple:defmessage fields-labels (fields))
 (sheeple:defreply fields-labels ((fields =fields=))
   (sheeple:with-properties (labels) fields
     labels))
 
9fbca987
 (sheeple:defproto =comment= () (self id author body))
 
9cc3714b
 (sheeple:defmessage points (issue))
 (sheeple:defreply points ((issue =issue=))
   (sheeple:property-value (fields issue)
                           'customfield_10002))
 
 (sheeple:defreply sheeple:shared-init ((issues =issues=) &key)
   (map nil (op (ensure-parent _ =issue=))
        (issues issues)))
 
9fbca987
 (sheeple:defreply sheeple:shared-init :after ((comment =comment=) &key)
3460d29f
   (with-accessors ((author author)) comment
9fbca987
       (ensure-parent author =person= :err-if-nil nil)))
 
0db897a4
 (sheeple:defreply sheeple:shared-init :after ((issue =issue=) &key)
   (with-accessors ((fields fields)) issue
     (when fields
       (ensure-parent fields =fields=)
       (ensure-parent (status fields) =status=)
9cc3714b
       (ensure-parent (reporter fields) =person= :err-if-nil nil)
       (ensure-parent (creator fields) =person= :err-if-nil nil)
9fbca987
       (ensure-parent (assignee fields) =person= :err-if-nil nil)
3460d29f
       (sheeple:with-properties (comment) fields
9cc3714b
         (when comment
           (sheeple:with-properties (comments) comment
             (map 'nil (lambda (comment) (ensure-parent comment =comment=))
                  comments)))))))
0db897a4
 
 (sheeple:defreply show ((person =person=) &rest args)
   (declare (ignore args))
   (format nil "\"~a\" <~a>" (displayname person) (emailaddress person)))
 
 (sheeple:defreply show ((status =status=) &rest args)
   (declare (ignore args))
   (format nil "~a" (name status)))
 
0c0e0fb8
 (defun show-description (description)
   (pprint-logical-block (*standard-output* (mapcar (compose 'tokens 'trim-whitespace)
                                                  (lines description)))
     (pprint-indent :block 4 *standard-output*)
     (pprint-newline :mandatory *standard-output*)
     (loop
       (pprint-exit-if-list-exhausted)
       (let ((line (pprint-pop)))
         (pprint-logical-block (*standard-output* line)
           (loop
             (princ (pprint-pop) *standard-output*)
             (pprint-exit-if-list-exhausted)
             (princ #\space *standard-output*)
             (pprint-indent :block 3)
             (pprint-newline :fill *standard-output*)))
         (pprint-newline :mandatory *standard-output*)))))
 
9cc3714b
 (defun show-summary (summary &optional (stream *standard-output*))
   (pprint-logical-block (stream (funcall (compose 'tokens 'trim-whitespace) summary))
0c0e0fb8
     (pprint-indent :block 8 *standard-output*)
     (pprint-exit-if-list-exhausted)
9cc3714b
     (format stream "~4tSummary: ")
0c0e0fb8
     (loop
9cc3714b
       (princ (pprint-pop) stream)
0c0e0fb8
       (pprint-exit-if-list-exhausted)
9cc3714b
       (pprint-newline :fill stream)
       (princ #\space stream))))
0c0e0fb8
 
0db897a4
 (sheeple:defreply show ((issue =issue=) &rest args)
   (declare (ignorable args))
   (with-output-to-string (*standard-output*)
3460d29f
     (when-let ((fields (fields issue)))
0db897a4
       (with-accessors ((status status) (summary summary) (reporter reporter)
                                        (creator creator) (assignee assignee)
                                        (labels fields-labels)) fields
 
         (format t "~a (~a) <~a>~%"
                 (key issue)
                 (show status)
9fbca987
                 (princ-to-string (puri:merge-uris (format nil "/browse/~a" (key issue))
                                                   *hostname*)))
0db897a4
 
         (show-summary summary)
 
         (show-person reporter "Reporter")
         (show-person creator "Creator")
         (when assignee
           (show-person assignee "Assignee"))
 
         (when (< 0 (length labels))
           (show-labels labels))
 
         (when (description fields)
           (show-description (description fields))))
3460d29f
 
       ; The head of the arguments determines whether or not
       ; we show the comments
       (when (and (car args))
         (if-let ((comment (comment fields)))
           (sheeple:with-properties (comments) comment
             (loop for comment across comments
                   do (format t "~&~a:~% ~<   ~@;~{~{~a~^ ~:_~}~2%~}~:>~&"
                              (show (author comment))
                              (list (map 'list #'tokens
                                         (split-sequence #\newline
                                                         (body comment)))))))))
 
0db897a4
       (fresh-line))))
 
 (sheeple:defproto =project= () (name key issuetypes))
 
 (sheeple:defproto =issuetype= () (description name))
 
 (sheeple:defreply sheeple:shared-init :after ((project =project=) &key)
   (with-accessors ((issuetypes issuetypes)) project
     (when issuetypes
       (map nil
            (lambda (issuetype) (ensure-parent issuetype =issuetype=))
            issuetypes))))
 
 (sheeple:defreply show ((issuetype =issuetype=) &rest arg)
   (declare (ignore args))
   (with-output-to-string (*standard-output*)
     (pprint-logical-block (*standard-output* (tokens (description issuetype)))
       (pprint-indent :block 15 *standard-output*)
       (pprint-exit-if-list-exhausted)
       (format *standard-output* "~4t~10@a: " (name issuetype))
       (loop
         (princ (pprint-pop))
         (pprint-exit-if-list-exhausted)
         (pprint-newline :fill *standard-output*)
         (princ #\space)))))
 
 (sheeple:defreply show ((project =project=) &rest args)
   (declare (ignore args))
   (with-output-to-string (*standard-output*)
     (format t "~a: ~a~%~{~a~&~}" (key project) (name project)
             (map 'list #'show (issuetypes project)))))
 
 (deftype vector-of-objects () '(vector (or hash-table sheeple:object) *))
 
 (defun json2sheeple (json &optional parent)
   (labels
9cc3714b
       ((handle-parsed (parsed-json)
          (typecase parsed-json
            (vector-of-objects (map 'vector #'handle-parsed parsed-json))
            (hash-table
             (let ((result (sheeple:object)))
               (loop for json-prop being the hash-keys of parsed-json using (hash-value json-value)
                  do (setf (sheeple:property-value result
                                                   (intern (string-upcase json-prop) :jira-api))
                           (typecase json-value
                             (hash-table (handle-parsed json-value))
                             (vector-of-objects (map 'vector #'handle-parsed json-value))
                             (t json-value)))
                  finally (return result))))
            (t parsed-json))))
0db897a4
     (let* ((yason:*parse-json-arrays-as-vectors* t)
            (result (handle-parsed (yason:parse json))))
       (when parent
         (ensure-parent result parent))
       result)))