From 20fd138b70a92fa3dc8a8a44e95fa2be57da092f Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sat, 25 Mar 2023 01:05:54 +1100 Subject: Unify the three modes into one (view mode) Also, now one can press return at any header to go to the respective object. For example, in step view, one can jump to the revision view by pressing return at the revision header on top --- buildbot-view.el | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 141 insertions(+), 4 deletions(-) (limited to 'buildbot-view.el') diff --git a/buildbot-view.el b/buildbot-view.el index 846c0df..7d1b677 100644 --- a/buildbot-view.el +++ b/buildbot-view.el @@ -2,6 +2,13 @@ (require 'buildbot-utils) (defvar buildbot-view-header-regex "^\\[.*\\]$") +;; 'revision, 'build, 'step, or 'log +(defvar-local buildbot-view-type nil) +(defvar-local buildbot-view-data nil) +;; (defvar-local buildbot-view-revision-id nil) +;; (defvar-local buildbot-view-revision-info nil) +;; (defvar-local buildbot-view-build nil) +;; (defvar-local buildbot-view-step nil) (define-derived-mode buildbot-view-mode special-mode "Buildbot view" "Buildbot view, a base mode") @@ -33,7 +40,7 @@ (alist-get 'comments revision-info) (buildbot-view-format-build-stats (alist-get 'build-stats revision-info))) - 'revision-id (alist-get 'revision revision-info))) + 'revision-id (alist-get 'revision revision-info) 'type 'revision)) (defun buildbot-view-format-build-stats (stats) (format "Build stats: Success - %d | Failure - %d | Pending - %d" @@ -50,7 +57,7 @@ (mapcar (lambda (test) (alist-get 'test_name test)) (alist-get 'failed_tests build)) "\n")) - 'build build)) + 'build build 'type 'build)) (defun buildbot-view-format-step (step) (propertize @@ -58,12 +65,142 @@ (alist-get 'number step) (alist-get 'name step) (alist-get 'state_string step)) - 'step step)) + 'step step 'type 'step)) (defun buildbot-view-format-log (log) (propertize (format "\n[%s]\n" (alist-get 'name log)) - 'log log)) + 'log log 'type 'log)) + +(defun buildbot-revision-format (revision-info builds) + (concat + (buildbot-view-format-revision-info revision-info) + "\n" + (string-join + (mapcar 'buildbot-view-format-build builds) + "\n"))) + +(defun buildbot-revision-get-info (change) + (list (cons 'revision (alist-get 'revision change)) + (cons 'author (alist-get 'author change)) + (cons 'created-at (buildbot-format-epoch-time + (alist-get 'created_at + (alist-get 'sourcestamp change)))) + (cons 'comments (alist-get 'comments change)) + (cons 'build-stats (buildbot-revision-get-build-stats + (alist-get 'builds change))))) + +(defun buildbot-revision-get-build-stats (builds) + (let ((results '((success . 0) + (failure . 0) + (pending . 0))) + status) + (seq-do + (lambda (build) + (setq status (buildbot-build-status build)) + (setf (alist-get status results) + (1+ (alist-get status results)))) + builds) + results)) + +(defun buildbot-build-format (revision-info build steps) + (concat + (buildbot-view-format-revision-info revision-info) + "\n" + (buildbot-view-format-build build) + "\n" + (string-join + (mapcar 'buildbot-view-format-step steps) + "\n"))) + +(defun buildbot-step-format (revision-info build step logs) + (concat + (buildbot-view-format-revision-info revision-info) + "\n" + (buildbot-view-format-build build) + "\n" + (buildbot-view-format-step step) + (string-join + (mapcar 'buildbot-view-format-log logs) + "\n"))) + +(defun buildbot-view-buffer-name (type data) + (pcase type + ('revision (format "*buildbot revision %s" + (alist-get 'revision-id data))) + ('build (format "*buildbot build %d" + (alist-get 'id (alist-get 'build data)))) + ('step (format "*buildbot step %d" + (alist-get 'stepid (alist-get 'step data)))))) + +(defun buildbot-view-load (type data) + (let ((buffer-name (buildbot-view-buffer-name type data))) + (with-current-buffer (get-buffer-create buffer-name) + (buildbot-view-mode) + (setq buildbot-view-type type + buildbot-view-data data) + (buildbot-view-update)) + (switch-to-buffer buffer-name))) + +(defun buildbot-view-reload () + (interactive) + (buildbot-view-update)) +(define-key buildbot-view-mode-map "g" 'buildbot-view-reload) + +(defun buildbot-view-revision-open (revision-id) + (interactive "sRevision (commit hash): ") + (buildbot-view-load 'revision `((revision-id . ,revision-id)))) + +(defun buildbot-view-update () + (unless (derived-mode-p 'buildbot-view-mode) + (error "Not in buildbot view mode")) + (let ((inhibit-read-only t)) + (erase-buffer) + (pcase buildbot-view-type + ('revision + (let ((change + (buildbot-get-change-by-revision + (alist-get 'revision-id buildbot-view-data)))) + (setf (alist-get 'revision-info buildbot-view-data) + (buildbot-revision-get-info change)) + (insert (buildbot-revision-format + (alist-get 'revision-info buildbot-view-data) + (alist-get 'builds change))))) + ('build + (insert (buildbot-build-format + (alist-get 'revision-info buildbot-view-data) + (alist-get 'build buildbot-view-data) + (buildbot-get-steps-by-buildid + (alist-get 'id + (alist-get 'build buildbot-view-data)))))) + ('step + (insert (buildbot-step-format + (alist-get 'revision-info buildbot-view-data) + (alist-get 'build buildbot-view-data) + (alist-get 'step buildbot-view-data) + (buildbot-get-logs-by-stepid + (alist-get 'stepid + (alist-get 'step buildbot-view-data))))))) + (goto-char (point-min)))) + +(defun buildbot-view-open-thing-at-point () + (interactive) + (let ((data (copy-tree buildbot-view-data))) + (pcase (get-text-property (point) 'type) + ('revision + (setf (alist-get 'revision-id data) + (get-text-property (point) 'revision-id)) + (buildbot-view-load 'revision data)) + ('build + (setf (alist-get 'build data) + (get-text-property (point) 'build)) + (buildbot-view-load 'build data)) + ('step + (setf (alist-get 'step data) + (get-text-property (point) 'step)) + (buildbot-view-load 'step data))))) +(define-key buildbot-view-mode-map (kbd "") + 'buildbot-view-open-thing-at-point) (provide 'buildbot-view) -- cgit v1.2.3