Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to comment on a specific line number on a PR on github

I am trying to write a small script that can comment on github PRs using eslint output.

The problem is eslint gives me the absolute line numbers for each error. But github API wants the line number relative to the diff.

From the github API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment

To comment on a specific line in a file, you will need to first determine the position in the diff. GitHub offers a application/vnd.github.v3.diff media type which you can use in a preceding request to view the pull request's diff. The diff needs to be interpreted to translate from the line in the file to a position in the diff. The position value is the number of lines down from the first "@@" hunk header in the file you would like to comment on.

The line just below the "@@" line is position 1, the next line is position 2, and so on. The position in the file's diff continues to increase through lines of whitespace and additional hunks until a new file is reached.

enter image description here

So if I want to add a comment on new line number 5 in the above image, then I would need to pass 12 to the API

My question is how can I easily map between the new line numbers which the eslint will give in it's error messages to the relative line numbers required by the github API

What I have tried so far

I am using parse-diff to convert the diff provided by github API into json object

[{
  "chunks": [{
    "content": "@@ -,OLD_TOTAL_LINES +NEW_STARTING_LINE_NUMBER,NEW_TOTAL_LINES @@",
    "changes": [
    {
      "type": STRING("normal"|"add"|"del"),
      "normal": BOOLEAN,
      "add": BOOLEAN,
      "del": BOOLEAN,
      "ln1": OLD_LINE_NUMBER,
      "ln2": NEW_LINE_NUMBER,
      "content": STRING,
      "oldStart": NUMBER,
      "oldLines": NUMBER,
      "newStart": NUMBER,
      "newLines": NUMBER
    }
  }]
}]

I am thinking of the following algorithm

  • make an array of new line numbers starting from NEW_STARTING_LINE_NUMBER to NEW_STARTING_LINE_NUMBER+NEW_TOTAL_LINESfor each file
  • subtract newStart from each number and make it another array relativeLineNumbers
  • traverse through the array and for each deleted line (type==='del') increment the corresponding remaining relativeLineNumbers
  • for another hunk (line having @@) decrement the corresponding remaining relativeLineNumbers
like image 926
Harry Avatar asked Jan 15 '17 14:01

Harry


People also ask

How do I comment out a line in GitHub?

Hover over the line of code where you'd like to add a comment, and click the blue comment icon. To add a comment on multiple lines, click and drag to select the range of lines, then click the blue comment icon. In the comment field, type your comment.

How do I add line numbers to a GitHub link?

You can link to a specific line in the Markdown file the same way you can in code. Append #L with the line number or numbers at the end of the url. For example, github.com/<organization>/<repository>/blob/<branch_name>/README.md? plain=1#L14 will highlight line 14 in the plain README.md file.

How do I reply to a comment in Git PR?

You can now quote comments in issues and pull requests by choosing Quote reply from the comment's options menu. This will paste quoted contents of the comment into the text field for the new comment. If part of a comment is selected, only that selection will be quoted. The keyboard shortcut for Quote reply is r .

How do I comment on a GitHub review?

To add review comments, click the + icon next to the line number. Type your review comment and then click Start Review. When you are finished adding review comments, from the Side Bar you can choose to either submit the comments, approve the changes, or request changes.


1 Answers

I have found a solution. I didn't put it here because it involves simple looping and nothing special. But anyway answering now to help others.

I have opened a pull request to create the similar situation as shown in question https://github.com/harryi3t/5134/pull/7/files

Diff Image

Using the Github API one can get the diff data.

diff --git a/test.js b/test.js
index 2aa9a08..066fc99 100644
--- a/test.js
+++ b/test.js
@@ -2,14 +2,7 @@

 var hello = require('./hello.js');

-var names = [
-  'harry',
-  'barry',
-  'garry',
-  'harry',
-  'barry',
-  'marry',
-];
+var names = ['harry', 'barry', 'garry', 'harry', 'barry', 'marry'];

 var names2 = [
   'harry',
@@ -23,9 +16,7 @@ var names2 = [
 // after this line new chunk will be created
 var names3 = [
   'harry',
-  'barry',
-  'garry',
   'harry',
   'barry',
-  'marry',
+  'marry', 'garry',
 ];

Now just pass this data to diff-parse module and do the computation.

var parsedFiles = parseDiff(data); // diff output
parsedFiles.forEach(
  function (file) {
    var relativeLine = 0;
    file.chunks.forEach(
      function (chunk, index) {
        if (index !== 0)  // relative line number should increment for each chunk
          relativeLine++; // except the first one (see rel-line 16 in the image)
        chunk.changes.forEach(
          function (change) {
            relativeLine++;
            console.log(
             change.type,
             change.ln1 ? change.ln1 : '-',
             change.ln2 ? change.ln2 : '-',
             change.ln ? change.ln : '-',
             relativeLine
           );
          }
        );
      }
    );
  }
);

This would print

type    (ln1) old line   (ln2) new line   (ln) added/deleted line    relative line
normal     2                  2                 -                       1
normal     3                  3                 -                       2
normal     4                  4                 -                       3
del        -                  -                 5                       4
del        -                  -                 6                       5
del        -                  -                 7                       6
del        -                  -                 8                       7
del        -                  -                 9                       8
del        -                  -                 10                      9
del        -                  -                 11                      10
del        -                  -                 12                      11
add        -                  -                 5                       12
normal     13                 6                 -                       13
normal     14                 7                 -                       14
normal     15                 8                 -                       15
normal     23                 16                -                       17
normal     24                 17                -                       18
normal     25                 18                -                       19
del        -                   -                26                      20
del        -                   -                27                      21
normal     28                 19                -                       22
normal     29                 20                -                       23
del        -                  -                 30                      24
add        -                  -                 21                      25
normal     31                 22                -                       26

Now you can use the relative line number to post a comment using github api.

For my purpose I only needed the relative line numbers for the newly added lines, but using the table above one can get it for deleted lines also.

Here's the link for the linting project in which I used this. https://github.com/harryi3t/lint-github-pr

like image 116
Harry Avatar answered Sep 28 '22 05:09

Harry