Save patch in comment

Render patch for code comments

Signed-off-by: Jonas Franz <info@jonasfranz.software>
This commit is contained in:
Jonas Franz 2018-05-31 11:44:52 +02:00 committed by Jonas Franz
parent c7dffe69b9
commit 4d0abce30e
No known key found for this signature in database
GPG Key ID: 506AEEBE80BEDECD
6 changed files with 109 additions and 132 deletions

View File

@ -552,32 +552,46 @@ const (
// GetRawDiff dumps diff results of repository in given commit ID to io.Writer.
// TODO: move this function to gogits/git-module
func GetRawDiff(repoPath, commitID string, diffType RawDiffType, writer io.Writer) error {
return GetRawDiffForFile(repoPath, "", commitID, diffType, "", writer)
}
// GetRawDiffForFile dumps diff results of file in given commit ID to io.Writer.
// TODO: move this function to gogits/git-module
func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiffType, file string, writer io.Writer) error {
repo, err := git.OpenRepository(repoPath)
if err != nil {
return fmt.Errorf("OpenRepository: %v", err)
}
commit, err := repo.GetCommit(commitID)
commit, err := repo.GetCommit(endCommit)
if err != nil {
return fmt.Errorf("GetCommit: %v", err)
}
fileArgs := make([]string, 0)
if len(file) > 0 {
fileArgs = append(fileArgs, "--", file)
}
var cmd *exec.Cmd
switch diffType {
case RawDiffNormal:
if commit.ParentCount() == 0 {
cmd = exec.Command("git", "show", commitID)
if len(startCommit) != 0 {
cmd = exec.Command("git", append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
} else if commit.ParentCount() == 0 {
cmd = exec.Command("git", append([]string{"show", endCommit}, fileArgs...)...)
} else {
c, _ := commit.Parent(0)
cmd = exec.Command("git", "diff", "-M", c.ID.String(), commitID)
cmd = exec.Command("git", append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
}
case RawDiffPatch:
if commit.ParentCount() == 0 {
cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID)
if len(startCommit) != 0 {
query := fmt.Sprintf("%s...%s", endCommit, startCommit)
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
} else if commit.ParentCount() == 0 {
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
} else {
c, _ := commit.Parent(0)
query := fmt.Sprintf("%s...%s", commitID, c.ID.String())
cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", query)
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
}
default:
return fmt.Errorf("invalid diffType: %s", diffType)
@ -588,7 +602,6 @@ func GetRawDiff(repoPath, commitID string, diffType RawDiffType, writer io.Write
cmd.Dir = repoPath
cmd.Stdout = writer
cmd.Stderr = stderr
if err = cmd.Run(); err != nil {
return fmt.Errorf("Run: %v - %s", err, stderr)
}

View File

@ -5,11 +5,13 @@
package models
import (
"bytes"
"fmt"
"strings"
"code.gitea.io/git"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
"github.com/go-xorm/xorm"
@ -111,6 +113,9 @@ type Comment struct {
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
// Path represents the 4 lines of code cemented by this comment
Patch string `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
@ -381,6 +386,53 @@ func (c *Comment) UnsignedLine() uint64 {
return uint64(c.Line)
}
// AsDiff returns c.Patch as *Diff
func (c *Comment) AsDiff() (*Diff, error) {
diff, err := ParsePatch(setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(c.Patch))
if err != nil {
return nil, err
}
if len(diff.Files) == 0 {
return nil, fmt.Errorf("no file found for comment ID: %d", c.ID)
}
// Limit to 4 lines around comment line
for _, sec := range diff.Files[0].Sections {
var searchedLineIdx int
for lineIdx, line := range sec.Lines {
if c.Line < 0 && int64(line.LeftIdx) == c.Line {
searchedLineIdx = lineIdx
break
}
if c.Line > 0 && int64(line.RightIdx) == c.Line {
searchedLineIdx = lineIdx
break
}
}
if searchedLineIdx >= 3 {
first := searchedLineIdx-3
last := searchedLineIdx+1
sec.Lines = sec.Lines[first:last]
diff.Files[0].Sections = []*DiffSection{sec}
break
} else if searchedLineIdx > 0 {
sec.Lines = sec.Lines[:searchedLineIdx+1]
diff.Files[0].Sections = []*DiffSection{sec}
break
}
}
return diff, nil
}
// MustAsDiff executes AsDiff and logs the error instead of returning
func (c *Comment) MustAsDiff() *Diff {
diff, err := c.AsDiff()
if err != nil {
log.Warn( "MustAsDiff: %v", err)
}
return diff
}
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
var LabelID int64
if opts.Label != nil {
@ -404,6 +456,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
NewTitle: opts.NewTitle,
TreePath: opts.TreePath,
ReviewID: opts.ReviewID,
Patch: opts.Patch,
}
if _, err = e.Insert(comment); err != nil {
return nil, err
@ -621,6 +674,7 @@ type CreateCommentOptions struct {
NewTitle string
CommitID int64
CommitSHA string
Patch string
LineNum int64
TreePath string
ReviewID int64
@ -699,10 +753,20 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, content, tree
gitLine *= -1
}
// FIXME validate treePath
// Get latest commit referencing the commented line
commit, err := gitRepo.LineBlame(pr.HeadBranch, gitRepo.Path, treePath, uint(gitLine))
if err != nil {
return nil, err
}
headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
if err != nil {
return nil, err
}
patchBuf := new(bytes.Buffer)
if err := GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, RawDiffPatch, treePath, patchBuf); err != nil {
return nil, err
}
return CreateComment(&CreateCommentOptions{
Type: CommentTypeCode,
Doer: doer,
@ -713,6 +777,7 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, content, tree
TreePath: treePath,
CommitSHA: commit.ID.String(),
ReviewID: reviewID,
Patch: patchBuf.String(),
})
}
@ -974,7 +1039,6 @@ func fetchCodeCommentsByReview(e Engine, issue *Issue, currentUser *User, review
comment.RenderedContent = string(markdown.Render([]byte(comment.Content), issue.Repo.Link(),
issue.Repo.ComposeMetas()))
if pathToLineToComment[comment.TreePath] == nil {
pathToLineToComment[comment.TreePath] = make(map[int64][]*Comment)
}

File diff suppressed because one or more lines are too long

View File

@ -1854,7 +1854,6 @@ $(document).ready(function () {
initU2FAuth();
initU2FRegister();
initPullRequestReview();
// Repo clone url.
if ($('#repo-clone-url').length > 0) {
switch (localStorage.getItem('repo-clone-protocol')) {

View File

@ -442,7 +442,13 @@ footer {
}
.hide {
display: none;
&.show-outdated {
display: none !important;
}
&.hide-outdated {
display: none !important;
}
}
.center {
text-align: center;

View File

@ -273,126 +273,21 @@
{{end}}
<code>{{$filename}}</code>
</div>
{{$diff := ((index $comms 0).MustAsDiff)}}
{{if $diff}}
{{$file := (index $diff.Files 0)}}
<div id="code-preview-{{(index $comms 0).ID}}" class="ui table segment{{if $invalid}} hide{{end}}">
<div class="diff-file-box diff-box file-content tab-size-8">
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}">
<div class="file-body file-code code-view code-diff code-diff-unified">
<table>
<tbody>
<tr class="tag-code nl-0 ol-0">
<td colspan="2" class="lines-num">
</td>
<td class="lines-code lines-code-old">
<pre><code class="wrap language-json hljs">@@ <span class="hljs-number">-27</span>,<span class="hljs-number">5</span> +<span class="hljs-number">27</span>,<span class="hljs-number">5</span> @@</code></pre>
</td>
</tr>
<tr class="same-code nl-1 ol-1">
<td class="lines-num lines-num-old">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0L27">27</span>
</td>
<td class="lines-num lines-num-new">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0R27">27</span>
<a class="ui green button add-code-comment add-code-comment-right" data-path="vendor/vendor.json" data-side="right" data-idx="27">+</a>
</td>
<td class="lines-code ">
<pre><code class="wrap language-json hljs"> <span class="hljs-string">"revisionTime"</span>: <span class="hljs-string">"2016-08-23T15:25:51Z"</span></code></pre>
</td>
</tr>
<tr class="same-code nl-2 ol-2">
<td class="lines-num lines-num-old">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0L28">28</span>
</td>
<td class="lines-num lines-num-new">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0R28">28</span>
<a class="ui green button add-code-comment add-code-comment-right" data-path="vendor/vendor.json" data-side="right" data-idx="28">+</a>
</td>
<td class="lines-code ">
<pre><code class="wrap language-json hljs"> }</code></pre>
</td>
</tr>
<tr class="same-code nl-3 ol-3">
<td class="lines-num lines-num-old">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0L29">29</span>
</td>
<td class="lines-num lines-num-new">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0R29">29</span>
<a class="ui green button add-code-comment add-code-comment-right" data-path="vendor/vendor.json" data-side="right" data-idx="29">+</a>
</td>
<td class="lines-code ">
<pre><code class="wrap language-json hljs"> ],</code></pre>
</td>
</tr>
<tr class="del-code nl-4 ol-4">
<td class="lines-num lines-num-old">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0L30">30</span>
</td>
<td class="lines-num lines-num-new">
<span rel=""></span>
<a class="ui green button add-code-comment add-code-comment-left" data-path="vendor/vendor.json" data-side="left" data-idx="30">+</a>
</td>
<td class="lines-code lines-code-old">
<pre><code class="wrap language-json hljs">- <span class="hljs-string">"rootPath"</span>: <span class="hljs-string">"</span><span class="removed-code"><span class="hljs-string">github.com</span></span><span class="hljs-string">/JonasFranzDEV/drone-gitea-release"</span></code></pre>
</td>
</tr>
<tr class="add-code nl-5 ol-5">
<td class="lines-num lines-num-old">
<span rel=""></span>
</td>
<td class="lines-num lines-num-new">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0R30">30</span>
<a class="ui green button add-code-comment add-code-comment-right" data-path="vendor/vendor.json" data-side="right" data-idx="30">+</a>
</td>
<td class="lines-code ">
<pre><code class="wrap language-json hljs">+ <span class="hljs-string">"rootPath"</span>: <span class="hljs-string">"</span><span class="added-code"><span class="hljs-string">localhost:3000</span></span><span class="hljs-string">/JonasFranzDEV/drone-gitea-release"</span></code></pre>
</td>
</tr>
<tr class="same-code nl-6 ol-6">
<td class="lines-num lines-num-old">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0L31">31</span>
</td>
<td class="lines-num lines-num-new">
<span rel="diff-d9bff1704388955a5d24ad2abc8aea5a312994d0R31">31</span>
<a class="ui green button add-code-comment add-code-comment-right" data-path="vendor/vendor.json" data-side="right" data-idx="31">+</a>
</td>
<td class="lines-code ">
<pre><code class="wrap language-json hljs"> }</code></pre>
</td>
</tr>
{{template "repo/diff/section_unified" dict "file" $file "root" $}}
</tbody>
</table>
</div>
</div>
</div>
{{end}}
<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if $invalid}} hide{{end}}">
<div class="ui comments">
{{range $comms}}