aboutsummaryrefslogtreecommitdiff
path: root/emacs/.emacs.d/lisp/my/my-org-jira.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/.emacs.d/lisp/my/my-org-jira.el')
-rw-r--r--emacs/.emacs.d/lisp/my/my-org-jira.el259
1 files changed, 178 insertions, 81 deletions
diff --git a/emacs/.emacs.d/lisp/my/my-org-jira.el b/emacs/.emacs.d/lisp/my/my-org-jira.el
index 7ff7738..9e2f821 100644
--- a/emacs/.emacs.d/lisp/my/my-org-jira.el
+++ b/emacs/.emacs.d/lisp/my/my-org-jira.el
@@ -28,97 +28,186 @@
(require 'org-jira)
+;;; override `org-jira-sdk-issue'
+(defclass org-jira-sdk-issue (org-jira-sdk-record)
+ ((affected-versions :type string :initarg :affected-versions)
+ (assignee :type (or null string) :initarg :assignee)
+ (components :type string :initarg :components)
+ (fix-versions :type string :initarg :fix-versions)
+ (labels :type string :initarg :labels)
+ (created :type string :initarg :created)
+ (description :type (or null string) :initarg :description)
+ (duedate :type (or null string) :initarg :duedate)
+ (headline :type string :initarg :headline)
+ (id :type string :initarg :id) ; TODO: Probably remove me
+ (issue-id :type string :initarg :issue-id :documentation "The common ID/key, such as EX-1.")
+ (issue-id-int :type string :initarg :issue-id-int :documentation "The internal Jira ID, such as 12345.")
+ (filename :type (or null string) :initarg :filename :documentation "The filename to write issue to.")
+ (priority :type (or null string) :initarg :priority)
+ (proj-key :type string :initarg :proj-key)
+ (related-issues :type string :initarg :related-issues)
+ (reporter :type (or null string) :initarg :reporter)
+ (resolution :type (or null string) :initarg :resolution)
+ (sprint :type (or null string) :initarg :sprint)
+ (start-date :type (or null string) :initarg :start-date)
+ (status :type string :initarg :status)
+ (summary :type string :initarg :summary)
+ (type :type string :initarg :type)
+ (type-id :type string :initarg :type-id)
+ (updated :type string :initarg :updated)
+ (data :initarg :data :documentation "The remote Jira data object (alist).")
+ (hydrate-fn :initform #'jiralib-get-issue :initarg :hydrate-fn))
+ "An issue on the end. ID of the form EX-1, or a numeric such as 10000.")
+
+
+;;; override `org-jira-sdk-from-data'
+(cl-defmethod org-jira-sdk-from-data ((rec org-jira-sdk-issue))
+ ;; (print rec)
+ (cl-flet ((path (keys) (org-jira-sdk-path (oref rec data) keys)))
+ (org-jira-sdk-issue
+ :affected-versions (mapconcat (lambda (c) (org-jira-sdk-path c '(name))) (path '(fields versions)) ", ")
+ :assignee (path '(fields assignee displayName))
+ :components (mapconcat (lambda (c) (org-jira-sdk-path c '(name))) (path '(fields components)) ", ")
+ :fix-versions (mapconcat (lambda (c) (org-jira-sdk-path c '(name))) (path '(fields fixVersions)) ", ")
+ :labels (mapconcat (lambda (c) (format "%s" c)) (mapcar #'identity (path '(fields labels))) ", ")
+ :created (path '(fields created)) ; confirm
+ :description (or (path '(fields description)) "")
+ :duedate (or (path '(fields sprint endDate)) (path '(fields duedate))) ; confirm
+ :filename (path '(fields project key))
+ :headline (path '(fields summary)) ; Duplicate of summary, maybe different.
+ :id (path '(key))
+ :issue-id (path '(key))
+ :issue-id-int (path '(id))
+ :priority (path '(fields priority name))
+ :proj-key (path '(fields project key))
+ :related-issues (mapconcat
+ (lambda (c)
+ ;; (print c)
+ (if (org-jira-sdk-path c '(inwardIssue))
+ (if (equal
+ (org-jira-sdk-path
+ c '(inwardIssue fields status name))
+ "Closed")
+ ""
+ (format "%s: %s %s"
+ (org-jira-sdk-path c '(type inward))
+ (org-jira-sdk-path c '(inwardIssue key))
+ (org-jira-sdk-path c '(inwardIssue fields summary))))
+ (if (equal
+ (org-jira-sdk-path
+ c '(outwardIssue fields status name))
+ "Closed")
+ ""
+ (format "%s: %s %s"
+ (org-jira-sdk-path c '(type outward))
+ (org-jira-sdk-path c '(outwardIssue key))
+ (org-jira-sdk-path c '(outwardIssue fields summary))))))
+ (path '(fields issuelinks)) "; ")
+ :reporter (path '(fields reporter displayName)) ; reporter could be an object of its own slot values
+ :resolution (path '(fields resolution name)) ; confirm
+ :sprint (path '(fields sprint name))
+ :start-date (path '(fields start-date)) ; confirm
+ :status (org-jira-decode (path '(fields status name)))
+ :summary (path '(fields summary))
+ :type (path '(fields issuetype name))
+ :type-id (path '(fields issuetype id))
+ :updated (path '(fields updated)) ; confirm
+ ;; TODO: Remove this
+ ;; :data (oref rec data)
+ )))
+
;; Override `org-jira--render-issue'
;; include issue-id in the headline
(defun my-org-jira--render-issue (Issue)
"Render single ISSUE."
;; (org-jira-log "Rendering issue from issue list")
;; (org-jira-log (org-jira-sdk-dump Issue))
+ ;; (print Issue)
(with-slots (filename proj-key issue-id summary status priority headline id) Issue
(let (p)
(with-current-buffer (org-jira--get-project-buffer Issue)
(org-jira-freeze-ui
- (org-jira-maybe-activate-mode)
- (org-jira--maybe-render-top-heading proj-key)
- (setq p (org-find-entry-with-id issue-id))
- (save-restriction
- (if (and p (>= p (point-min))
- (<= p (point-max)))
- (progn
- (goto-char p)
- (forward-thing 'whitespace)
- (org-jira-kill-line))
- (goto-char (point-max))
- (unless (looking-at "^")
- (insert "\n"))
- (insert "** "))
- (org-jira-insert
- (concat (org-jira-get-org-keyword-from-status status)
- " "
- (org-jira-get-org-priority-cookie-from-issue priority)
- issue-id " " headline))
- (save-excursion
- (unless (search-forward "\n" (point-max) 1)
- (insert "\n")))
- (org-narrow-to-subtree)
- (save-excursion
- (org-back-to-heading t)
- (org-set-tags-to (replace-regexp-in-string "-" "_" issue-id)))
- (mapc (lambda (entry)
- (let ((val (slot-value Issue entry)))
- (when (or (and val (not (string= val "")))
- (eq entry 'assignee)) ;; Always show assignee
- (org-jira-entry-put (point) (symbol-name entry) val))))
- '(assignee filename reporter type type-id priority labels resolution status components created updated sprint))
-
- (org-jira-entry-put (point) "ID" issue-id)
- (org-jira-entry-put (point) "CUSTOM_ID" issue-id)
-
- ;; Insert the duedate as a deadline if it exists
- (when org-jira-deadline-duedate-sync-p
- (let ((duedate (oref Issue duedate)))
- (when (> (length duedate) 0)
- (org-deadline nil duedate))))
-
- (mapc
- (lambda (heading-entry)
- (ensure-on-issue-id-with-filename issue-id filename
- (let* ((entry-heading
- (concat (symbol-name heading-entry)
- (format ": [[%s][%s]]"
- (concat jiralib-url "/browse/" issue-id) issue-id))))
- (setq p (org-find-exact-headline-in-buffer entry-heading))
- (if (and p (>= p (point-min))
- (<= p (point-max)))
- (progn
- (goto-char p)
- (org-narrow-to-subtree)
- (goto-char (point-min))
- (forward-line 1)
- (delete-region (point) (point-max)))
- (if (org-goto-first-child)
- (org-insert-heading)
- (goto-char (point-max))
- (org-insert-subheading t))
- (org-jira-insert entry-heading "\n"))
-
- ;; Insert 2 spaces of indentation so Jira markup won't cause org-markup
- (org-jira-insert
- (replace-regexp-in-string
- "^" " "
- (format "%s" (slot-value Issue heading-entry)))))))
- '(description))
-
- (when org-jira-download-comments
- (org-jira-update-comments-for-issue Issue)
-
- ;; FIXME: Re-enable when attachments are not erroring.
- ;;(org-jira-update-attachments-for-current-issue)
- )
-
- ;; only sync worklog clocks when the user sets it to be so.
- (when org-jira-worklog-sync-p
- (org-jira-update-worklogs-for-issue issue-id filename))))))))
+ (org-jira-maybe-activate-mode)
+ (org-jira--maybe-render-top-heading proj-key)
+ (setq p (org-find-entry-with-id issue-id))
+ (save-restriction
+ (if (and p (>= p (point-min))
+ (<= p (point-max)))
+ (progn
+ (goto-char p)
+ (forward-thing 'whitespace)
+ (org-jira-kill-line))
+ (goto-char (point-max))
+ (unless (looking-at "^")
+ (insert "\n"))
+ (insert "** "))
+ (org-jira-insert
+ (concat (org-jira-get-org-keyword-from-status status)
+ " "
+ (org-jira-get-org-priority-cookie-from-issue priority)
+ issue-id " " headline))
+ (save-excursion
+ (unless (search-forward "\n" (point-max) 1)
+ (insert "\n")))
+ (org-narrow-to-subtree)
+ (save-excursion
+ (org-back-to-heading t)
+ (org-set-tags-to (replace-regexp-in-string "-" "_" issue-id)))
+ (mapc (lambda (entry)
+ (let ((val (slot-value Issue entry)))
+ (when (or (and val (not (string= val "")))
+ (eq entry 'assignee)) ;; Always show assignee
+ (org-jira-entry-put (point) (symbol-name entry) val))))
+ '(assignee filename reporter type type-id priority affected-versions fix-versions labels resolution status components created updated sprint related-issues))
+
+ (org-jira-entry-put (point) "ID" issue-id)
+ (org-jira-entry-put (point) "CUSTOM_ID" issue-id)
+
+ ;; Insert the duedate as a deadline if it exists
+ (when org-jira-deadline-duedate-sync-p
+ (let ((duedate (oref Issue duedate)))
+ (when (> (length duedate) 0)
+ (org-deadline nil duedate))))
+
+ (mapc
+ (lambda (heading-entry)
+ (ensure-on-issue-id-with-filename issue-id filename
+ (let* ((entry-heading
+ (concat (symbol-name heading-entry)
+ (format ": [[%s][%s]]"
+ (concat jiralib-url "/browse/" issue-id) issue-id))))
+ (setq p (org-find-exact-headline-in-buffer entry-heading))
+ (if (and p (>= p (point-min))
+ (<= p (point-max)))
+ (progn
+ (goto-char p)
+ (org-narrow-to-subtree)
+ (goto-char (point-min))
+ (forward-line 1)
+ (delete-region (point) (point-max)))
+ (if (org-goto-first-child)
+ (org-insert-heading)
+ (goto-char (point-max))
+ (org-insert-subheading t))
+ (org-jira-insert entry-heading "\n"))
+
+ ;; Insert 2 spaces of indentation so Jira markup won't cause org-markup
+ (org-jira-insert
+ (replace-regexp-in-string
+ "^" " "
+ (format "%s" (slot-value Issue heading-entry)))))))
+ '(description))
+
+ (when org-jira-download-comments
+ (org-jira-update-comments-for-issue Issue)
+
+ ;; FIXME: Re-enable when attachments are not erroring.
+ ;;(org-jira-update-attachments-for-current-issue)
+ )
+
+ ;; only sync worklog clocks when the user sets it to be so.
+ (when org-jira-worklog-sync-p
+ (org-jira-update-worklogs-for-issue issue-id filename))))))))
;; Overload `org-jira-update-worklogs-from-org-clocks'.
(defun my-org-jira-update-worklogs-from-org-clocks ()
@@ -180,5 +269,13 @@
(interactive)
(kill-new (my-org-jira-comment-url-at-point)))
+(defun my-org-jira-url-p (url)
+ (string-match-p (format "^%s/browse/[^/]" jiralib-url) url))
+
+(defun my-org-jira-open-url (url)
+ (interactive "sJIRA issue url: ")
+ (when (string-match (format "^%s/browse/\\([^/]+\\)" jiralib-url) url)
+ (org-jira-get-issue (match-string 1 url))))
+
(provide 'my-org-jira)
;;; my-org-jira.el ends here