Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ machine api.github.com login yourlogin^github-review password MYTOKENGOESHERE
If you use GitHub Enterprise, you can use the `github-review-host` custom variable to
configure the endpoint of your GitHub Enterprise installation, this should look like `api.git.mycompany.com`.

- By default, `github-review` fetches only top level comments in a pull request.
You can set `github-review-view-comments-in-code-lines` to `t` to also fetch
comments made between code lines.

## Notice

*I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my
Expand Down
91 changes: 86 additions & 5 deletions github-review.el
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
:group 'github-review
:type 'string)

(defcustom github-review-view-comments-in-code-lines nil
"Flag to enable displaying comments in code lines."
:group 'github-review)

(defconst github-review-diffheader '(("Accept" . "application/vnd.github.v3.diff"))
"Header for requesting diffs from GitHub.")

Expand Down Expand Up @@ -119,8 +123,26 @@ return a deferred object"
nodes { author { login } bodyText state }
} }
}
}" .repo .owner .num))
(query-with-comments (format "query {
repository(name: \"%s\", owner: \"%s\") {
pullRequest(number: %s){
headRef { target{ oid } }
title
bodyText
comments(first:50) {
nodes { author { login } bodyText }
}
reviews(first: 50) {
nodes { author { login } bodyText state
comments(first: 50)
{ nodes { bodyText originalPosition } }}
} }
}
}" .repo .owner .num)))
(ghub-graphql query
(ghub-graphql (if github-review-view-comments-in-code-lines
query-with-comments
query)
'()
:auth 'github-review
:host (github-review-api-host pr-alist)
Expand Down Expand Up @@ -330,21 +352,74 @@ This function infers the PR name based on the current filename"

(defun github-review-to-comments (text)
"Convert TEXT, a string to a string where each line is prefixed by ~."
(s-join "\n" (-map (lambda (x) (concat "~ " x)) (s-split "\n" text))))
(s-join "\n" (-concat (list " ") (-map (lambda (x) (concat "~ " x)) (s-split "\n" text)))))

(defun github-review-format-top-level-comment (com)
"Format a top level COM objectto string."
(let-alist com
(format "@%s: %s" .author.login .bodyText)))
(format "Commented by @%s: %s" .author.login .bodyText)))

(defun github-review-format-review (review)
"Format a REVIEW object to string."
(let-alist review
(format "Reviewed by @%s[%s]: %s" .author.login .state .bodyText)))
(if (not (string-empty-p .bodyText))
(format "Reviewed by @%s[%s]: %s" .author.login .state .bodyText)
"")))

(defvar github-review-comment-pos nil
"Variable to count how many comments in code lines were added in the diff.
This is necessary to adjust the new comments to the correct position in the diff given that
Github API provides only the originalPosition in the query.")

(defun github-review-place-review-comments (gitdiff review)
(if (not (a-get-in review (list 'comments 'nodes)))
gitdiff
(let* ((at (a-get-in review (list 'author 'login)))
(body (a-get review 'bodyText))
(body-lines (split-string body "\n"))
(state (a-get review 'state))

(diffs (split-string gitdiff "\n"))
(comments (a-get-in review (list 'comments 'nodes)))
(default-shift-pos 5)
(diffs-new
(-reduce-from
(lambda (acc-diff comment)
(let* ((original-pos (a-get comment 'originalPosition))
(adjusted-pos (+ original-pos
default-shift-pos
(or github-review-comment-pos 0)))
(comment-lines (split-string (a-get comment 'bodyText) "\n"))
(diff-splitted (-split-at adjusted-pos acc-diff)))

(setq github-review-comment-pos (+ (or github-review-comment-pos 0)
(length comment-lines)
(length body-lines)))
(-concat
(-first-item diff-splitted)
(list ""
(format "~ Reviewed by @%s[%s]: %s" at state
(if (string-empty-p body)
(-first-item comment-lines)
(-first-item body-lines))))
(-map
(lambda (commentLine) (s-concat "~ " (s-trim-left commentLine)))
(-concat
(-drop 1 body-lines)
(if (string-empty-p body)
(-drop 1 comment-lines)
comment-lines)))
(-second-item diff-splitted))))
diffs
comments)))
(s-join
"\n"
diffs-new))))

(defun github-review-format-diff (gitdiff pr)
"Formats a GITDIFF and PR to save it for review."
(let-alist pr
(setq github-review-comment-pos nil)
Comment thread
wandersoncferreira marked this conversation as resolved.
Outdated
(concat
(github-review-to-comments .title)
"\n~"
Expand All @@ -366,7 +441,13 @@ This function infers the PR name based on the current filename"
#'github-review-to-comments
(-map #'github-review-format-review reviews)))
"\n"))
(a-get gitdiff 'message))))
(if github-review-view-comments-in-code-lines
(-reduce-from
(lambda (acc-gitdiff node)
(github-review-place-review-comments acc-gitdiff node))
(a-get gitdiff 'message)
.reviews.nodes)
(a-get gitdiff 'message)))))

;;;;;;;;;;;;;;;;;;;;;
;; User facing API ;;
Expand Down