Save patch in comment
Render patch for code comments Signed-off-by: Jonas Franz <info@jonasfranz.software>
This commit is contained in:
parent
c7dffe69b9
commit
4d0abce30e
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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')) {
|
||||
|
|
|
@ -442,7 +442,13 @@ footer {
|
|||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
&.show-outdated {
|
||||
display: none !important;
|
||||
}
|
||||
&.hide-outdated {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue
Block a user