diff --git a/lisp/forge-commands.el b/lisp/forge-commands.el index 7ce29c70..d9f89e26 100644 --- a/lisp/forge-commands.el +++ b/lisp/forge-commands.el @@ -454,6 +454,20 @@ point is currently on." 'confirm) (mapconcat #'car value ",")))))) +(defun forge-edit-topic-review-requests (topic) + "Edit the review-requests of TOPIC." + (interactive (list (forge-read-pullreq "Request review for"))) + (let* ((repo (forge-get-repository topic)) + (value (closql--iref topic 'review-requests)) + (choices (mapcar #'cadr (oref repo assignees))) + (crm-separator ",")) + (forge--set-topic-review-requests + repo topic + (magit-completing-read-multiple* + "Request review from: " choices nil + 'confirm + (mapconcat #'car value ","))))) + ;;; Delete (defun forge-delete-comment (comment) diff --git a/lisp/forge-db.el b/lisp/forge-db.el index 262d7306..213a57e6 100644 --- a/lisp/forge-db.el +++ b/lisp/forge-db.el @@ -25,6 +25,8 @@ (require 'emacsql) (require 'emacsql-sqlite) +(defvar forge--db-table-schemata) + (declare-function forge-reset-database "forge") ;;; Options @@ -41,7 +43,7 @@ (defclass forge-database (closql-database) ((object-class :initform forge-repository))) -(defconst forge--db-version 2) +(defconst forge--db-version 3) (defvar forge--db-connection nil "The EmacSQL database connection.") @@ -54,6 +56,14 @@ (let* ((db forge--db-connection) (version (caar (emacsql db "PRAGMA user_version")))) (cond + ((and (= version 2) (= forge--db-version 3)) + (message "Upgrading Forge database from version 2 to 3...") + (let ((db forge--db-connection)) + (emacsql-with-transaction db + (emacsql db [:create-table pullreq-review-request $S1] + (cdr (assq 'pullreq-review-request forge--db-table-schemata))) + (emacsql db (format "PRAGMA user_version = %s" 3)))) + (message "Upgrading Forge database from version 2 to 3...done")) ((> version forge--db-version) (emacsql-close db) (user-error "BUG: forge-db-version is too low")) @@ -283,6 +293,13 @@ [pullreq] :references pullreq [id] :on-delete :cascade)) + (pullreq-review-request + [(pullreq :not-null) + (id :not-null)] + (:foreign-key + [pullreq] :references pullreq [id] + :on-delete :cascade)) + (revnote [(class :not-null) (id :not-null :primary-key) diff --git a/lisp/forge-github.el b/lisp/forge-github.el index 6e5ec7f2..b812d881 100644 --- a/lisp/forge-github.el +++ b/lisp/forge-github.el @@ -228,6 +228,9 @@ repositories. t))) (when bump (forge--set-id-slot repo pullreq 'assignees .assignees) + (forge--set-id-slot repo pullreq 'review-requests + (--map (cdr (cadr it)) + (car .reviewRequests))) (forge--set-id-slot repo pullreq 'labels .labels)) pullreq)))) @@ -504,6 +507,19 @@ repositories. `((assignees . ,remove))))) (forge-pull)) +(cl-defmethod forge--set-topic-review-requests + ((_repo forge-github-repository) topic reviewers) + (let ((value (mapcar #'car (closql--iref topic 'review-requests)))) + (when-let ((add (cl-set-difference reviewers value :test #'equal))) + (forge--ghub-post + topic "/repos/:owner/:repo/pulls/:number/requested_reviewers" + `((reviewers . ,add)))) + (when-let ((remove (cl-set-difference value reviewers :test #'equal))) + (forge--ghub-delete + topic "/repos/:owner/:repo/pulls/:number/requested_reviewers" + `((reviewers . ,remove))))) + (forge-pull)) + (cl-defmethod forge--topic-templates ((repo forge-github-repository) (_ (subclass forge-issue))) (when-let ((files (magit-revision-files (oref repo default-branch)))) diff --git a/lisp/forge-pullreq.el b/lisp/forge-pullreq.el index 7dd54d0e..12a60c47 100644 --- a/lisp/forge-pullreq.el +++ b/lisp/forge-pullreq.el @@ -62,7 +62,7 @@ (participants) (posts :closql-class forge-pullreq-post) (reactions) - (review-requests) + (review-requests :closql-table (pullreq-review-request assignee)) (reviews) (timeline) ;; We don't use these fields: diff --git a/lisp/forge-topic.el b/lisp/forge-topic.el index d807eb4a..0cab0eca 100644 --- a/lisp/forge-topic.el +++ b/lisp/forge-topic.el @@ -313,7 +313,8 @@ identifier." '(forge-insert-topic-title forge-insert-topic-state forge-insert-topic-labels - forge-insert-topic-assignees)) + forge-insert-topic-assignees + forge-insert-topic-review-requests)) (defvar forge-post-section-map (let ((map (make-sparse-keymap))) @@ -471,6 +472,24 @@ identifier." (insert (propertize "none" 'face 'magit-dimmed))) (insert ?\n))) +(defvar forge-topic-review-requests-section-map + (let ((map (make-sparse-keymap))) + (define-key map [remap magit-edit-thing] 'forge-edit-topic-review-requests) + map)) + +(cl-defun forge-insert-topic-review-requests + (&optional (topic forge-buffer-topic)) + (when (and (forge-github-repository-p (forge-get-repository topic)) + (forge-pullreq-p topic)) + (magit-insert-section (topic-review-requests) + (insert (format "%-11s" "Review-Requests: ")) + (if-let ((review-requests (closql--iref topic 'review-requests))) + (insert (mapconcat (pcase-lambda (`(,login ,name)) + (format "%s (@%s)" name login)) + review-requests ", ")) + (insert (propertize "none" 'face 'magit-dimmed))) + (insert ?\n)))) + (defun forge--fontify-markdown (text) (with-temp-buffer (delay-mode-hooks