Compare commits

...

4 commits

3 changed files with 61 additions and 15 deletions

View file

@ -82,6 +82,28 @@ Returns a list of pull request objects on success, nil on failure."
(message "Error fetching pull requests: %s" error-thrown)))))
result))
(defun ghpr--get-pr (repo-name pr-number)
"Retrieve a single pull request by PR-NUMBER in REPO-NAME.
Returns a parsed PR object on success, nil on failure."
(let ((token (ghpr--get-token))
(url (format "https://api.github.com/repos/%s/pulls/%s" repo-name pr-number))
(result nil))
(when token
(request url
:type "GET"
:headers `(("Accept" . "application/vnd.github+json")
("Authorization" . ,(format "Bearer %s" token))
("X-GitHub-Api-Version" . "2022-11-28"))
:parser 'json-read
:sync t
:success (cl-function
(lambda (&key data &allow-other-keys)
(setq result (ghpr--parse-api-pr data))))
:error (cl-function
(lambda (&key error-thrown &allow-other-keys)
(message "Error fetching PR: %s" error-thrown)))))
result))
(defun ghpr--get-diff-content (repo-name pr-number)
"Retrieve the diff contents for PR-NUMBER in REPO-NAME."
(let ((token (ghpr--get-token))

View file

@ -68,14 +68,14 @@
("^\\(> \\)$" (0 'ghpr-review-misc-line t)))
"Font lock keywords for ghpr-review-mode.")
(defvar-local ghpr--review-diff-content nil
"Buffer-local variable storing the diff content for the current PR.")
(defvar-local ghpr--review-base-content nil
"Stores the base starting content, including diff, for the current PR.")
(defvar-local ghpr--review-pr-metadata nil
"Buffer-local variable storing the PR metadata for the current PR.")
"Stores the PR metadata for the current PR.")
(defvar-local ghpr--review-repo-name nil
"Buffer-local variable storing the repository name for the current PR.")
"Stores the repository name for the current PR.")
(defvar ghpr-review-mode-map
(let ((map (make-sparse-keymap))
@ -111,7 +111,7 @@
"Return a string of the title, body, and patch content separated by newlines."
(let* ((body (or (alist-get 'body pr) ""))
(content-parts (list (ghpr--pr-summary pr))))
(when (not (string-empty-p body))
(when (and body (not (string-empty-p body)))
(push body content-parts))
(when diff-content
(push diff-content content-parts))
@ -122,11 +122,11 @@
(erase-buffer)
(let* ((number (alist-get 'number pr))
(diff-content (ghpr--get-diff-content repo-name number))
(contents (ghpr--open-pr/collect-contents pr diff-content)))
(setq ghpr--review-diff-content diff-content)
(contents (ghpr--prefix-lines (ghpr--open-pr/collect-contents pr diff-content))))
(setq ghpr--review-base-content contents)
(setq ghpr--review-pr-metadata pr)
(setq ghpr--review-repo-name repo-name)
(insert (ghpr--prefix-lines contents))))
(insert contents)))
(defun ghpr--open-pr (pr repo-name)
"Open a new buffer containing the body of the PR."
@ -339,6 +339,14 @@ Returns an alist with comment, file-path, commit-sha, and diff-position, or nil
(commit-sha . ,(alist-get 'commit-sha context))
(diff-position . ,(alist-get 'diff-position context)))))))
(defun ghpr--validate-base-content-unchanged ()
"Validate that all base content (lines with > or < prefixes) remains unchanged.
Returns t if validation passes, nil otherwise."
(let* ((current-lines (split-string (buffer-string) "\n"))
(base-lines (split-string ghpr--review-base-content "\n"))
(current-base-lines (seq-filter #'ghpr--special-line-p current-lines)))
(equal current-base-lines base-lines)))
(defun ghpr--collect-review-comments ()
"Collect all inline review comments from the current buffer.
Returns an alist of comments with their associated diff lines and GitHub API context.
@ -367,6 +375,9 @@ Collects review body and inline comments from current buffer."
(error "No PR metadata found in buffer"))
(unless ghpr--review-repo-name
(error "No repository name found in buffer"))
;; TODO: needs better usability. maybe highlight which lines were broken/missing and restore.
(unless (ghpr--validate-base-content-unchanged)
(error "Base content has been modified. Please restore the original diff content before submitting"))
(let* ((body (ghpr--collect-review-body))
(inline-comments (ghpr--collect-review-comments))
@ -382,13 +393,17 @@ Collects review body and inline comments from current buffer."
(or (not body) (string-empty-p (string-trim body))))
(error "Review body is required for %s events" event))
(unless (ghpr--create-review ghpr--review-repo-name
pr-number
commit-sha
(or body "")
event
api-comments)
(message "Failed to submit review"))))
(when (yes-or-no-p (format "Submit review (%s)? " event))
(if (ghpr--create-review ghpr--review-repo-name
pr-number
commit-sha
(or body "")
event
api-comments)
(progn
(message "Review submitted successfully")
(kill-buffer (current-buffer)))
(message "Failed to submit review")))))
(defun ghpr-review-comment ()
"Submit review comments with COMMENT event."

View file

@ -54,6 +54,15 @@
(let ((pr (cdr (assoc selected-item pr-items))))
(ghpr--open-pr pr repo-name))))))))
(defun ghpr-open-pr (pr-number)
"Open a specific pull request by PR-NUMBER."
(interactive "nPR number: ")
(let* ((repo-name (ghpr--get-repo-name))
(pr (when repo-name (ghpr--get-pr repo-name pr-number))))
(if pr
(ghpr--open-pr pr repo-name)
(message "Could not open PR #%d" pr-number))))
(provide 'ghpr)
;;; ghpr.el ends here