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.
|
// GetRawDiff dumps diff results of repository in given commit ID to io.Writer.
|
||||||
// TODO: move this function to gogits/git-module
|
// TODO: move this function to gogits/git-module
|
||||||
func GetRawDiff(repoPath, commitID string, diffType RawDiffType, writer io.Writer) error {
|
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)
|
repo, err := git.OpenRepository(repoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("OpenRepository: %v", err)
|
return fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
commit, err := repo.GetCommit(commitID)
|
commit, err := repo.GetCommit(endCommit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("GetCommit: %v", err)
|
return fmt.Errorf("GetCommit: %v", err)
|
||||||
}
|
}
|
||||||
|
fileArgs := make([]string, 0)
|
||||||
|
if len(file) > 0 {
|
||||||
|
fileArgs = append(fileArgs, "--", file)
|
||||||
|
}
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
switch diffType {
|
switch diffType {
|
||||||
case RawDiffNormal:
|
case RawDiffNormal:
|
||||||
if commit.ParentCount() == 0 {
|
if len(startCommit) != 0 {
|
||||||
cmd = exec.Command("git", "show", commitID)
|
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 {
|
} else {
|
||||||
c, _ := commit.Parent(0)
|
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:
|
case RawDiffPatch:
|
||||||
if commit.ParentCount() == 0 {
|
if len(startCommit) != 0 {
|
||||||
cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID)
|
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 {
|
} else {
|
||||||
c, _ := commit.Parent(0)
|
c, _ := commit.Parent(0)
|
||||||
query := fmt.Sprintf("%s...%s", commitID, c.ID.String())
|
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
|
||||||
cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", query)
|
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid diffType: %s", diffType)
|
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.Dir = repoPath
|
||||||
cmd.Stdout = writer
|
cmd.Stdout = writer
|
||||||
cmd.Stderr = stderr
|
cmd.Stderr = stderr
|
||||||
|
|
||||||
if err = cmd.Run(); err != nil {
|
if err = cmd.Run(); err != nil {
|
||||||
return fmt.Errorf("Run: %v - %s", err, stderr)
|
return fmt.Errorf("Run: %v - %s", err, stderr)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,13 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/git"
|
"code.gitea.io/git"
|
||||||
"code.gitea.io/gitea/modules/markup/markdown"
|
"code.gitea.io/gitea/modules/markup/markdown"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
"github.com/go-xorm/builder"
|
"github.com/go-xorm/builder"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
|
@ -111,6 +113,9 @@ type Comment struct {
|
||||||
Content string `xorm:"TEXT"`
|
Content string `xorm:"TEXT"`
|
||||||
RenderedContent string `xorm:"-"`
|
RenderedContent string `xorm:"-"`
|
||||||
|
|
||||||
|
// Path represents the 4 lines of code cemented by this comment
|
||||||
|
Patch string `xorm:"TEXT"`
|
||||||
|
|
||||||
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
|
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
|
||||||
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
|
||||||
|
|
||||||
|
|
@ -381,6 +386,53 @@ func (c *Comment) UnsignedLine() uint64 {
|
||||||
return uint64(c.Line)
|
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) {
|
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||||
var LabelID int64
|
var LabelID int64
|
||||||
if opts.Label != nil {
|
if opts.Label != nil {
|
||||||
|
|
@ -404,6 +456,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||||
NewTitle: opts.NewTitle,
|
NewTitle: opts.NewTitle,
|
||||||
TreePath: opts.TreePath,
|
TreePath: opts.TreePath,
|
||||||
ReviewID: opts.ReviewID,
|
ReviewID: opts.ReviewID,
|
||||||
|
Patch: opts.Patch,
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(comment); err != nil {
|
if _, err = e.Insert(comment); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -621,6 +674,7 @@ type CreateCommentOptions struct {
|
||||||
NewTitle string
|
NewTitle string
|
||||||
CommitID int64
|
CommitID int64
|
||||||
CommitSHA string
|
CommitSHA string
|
||||||
|
Patch string
|
||||||
LineNum int64
|
LineNum int64
|
||||||
TreePath string
|
TreePath string
|
||||||
ReviewID int64
|
ReviewID int64
|
||||||
|
|
@ -699,10 +753,20 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, content, tree
|
||||||
gitLine *= -1
|
gitLine *= -1
|
||||||
}
|
}
|
||||||
// FIXME validate treePath
|
// FIXME validate treePath
|
||||||
|
// Get latest commit referencing the commented line
|
||||||
commit, err := gitRepo.LineBlame(pr.HeadBranch, gitRepo.Path, treePath, uint(gitLine))
|
commit, err := gitRepo.LineBlame(pr.HeadBranch, gitRepo.Path, treePath, uint(gitLine))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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{
|
return CreateComment(&CreateCommentOptions{
|
||||||
Type: CommentTypeCode,
|
Type: CommentTypeCode,
|
||||||
Doer: doer,
|
Doer: doer,
|
||||||
|
|
@ -713,6 +777,7 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, content, tree
|
||||||
TreePath: treePath,
|
TreePath: treePath,
|
||||||
CommitSHA: commit.ID.String(),
|
CommitSHA: commit.ID.String(),
|
||||||
ReviewID: reviewID,
|
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(),
|
comment.RenderedContent = string(markdown.Render([]byte(comment.Content), issue.Repo.Link(),
|
||||||
issue.Repo.ComposeMetas()))
|
issue.Repo.ComposeMetas()))
|
||||||
|
|
||||||
if pathToLineToComment[comment.TreePath] == nil {
|
if pathToLineToComment[comment.TreePath] == nil {
|
||||||
pathToLineToComment[comment.TreePath] = make(map[int64][]*Comment)
|
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();
|
initU2FAuth();
|
||||||
initU2FRegister();
|
initU2FRegister();
|
||||||
initPullRequestReview();
|
initPullRequestReview();
|
||||||
|
|
||||||
// Repo clone url.
|
// Repo clone url.
|
||||||
if ($('#repo-clone-url').length > 0) {
|
if ($('#repo-clone-url').length > 0) {
|
||||||
switch (localStorage.getItem('repo-clone-protocol')) {
|
switch (localStorage.getItem('repo-clone-protocol')) {
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,13 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide {
|
.hide {
|
||||||
|
display: none;
|
||||||
|
&.show-outdated {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
}
|
||||||
|
&.hide-outdated {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.center {
|
.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
||||||
|
|
@ -273,126 +273,21 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
<code>{{$filename}}</code>
|
<code>{{$filename}}</code>
|
||||||
</div>
|
</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 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">
|
<div class="file-body file-code code-view code-diff code-diff-unified">
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{{template "repo/diff/section_unified" dict "file" $file "root" $}}
|
||||||
<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>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
||||||
<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if $invalid}} hide{{end}}">
|
<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if $invalid}} hide{{end}}">
|
||||||
<div class="ui comments">
|
<div class="ui comments">
|
||||||
{{range $comms}}
|
{{range $comms}}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user