type NoticeType int | type NoticeType int | ||||
const ( | const ( | ||||
NOTICE_REPOSITORY NoticeType = iota + 1 | |||||
NoticeRepository NoticeType = iota + 1 | |||||
) | ) | ||||
// Notice represents a system notice for admin. | // Notice represents a system notice for admin. | ||||
return err | return err | ||||
} | } | ||||
// CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY. | |||||
// CreateRepositoryNotice creates new system notice with type NoticeRepository. | |||||
func CreateRepositoryNotice(desc string) error { | func CreateRepositoryNotice(desc string) error { | ||||
return CreateNotice(NOTICE_REPOSITORY, desc) | |||||
return CreateNotice(NoticeRepository, desc) | |||||
} | } | ||||
// RemoveAllWithNotice removes all directories in given path and | // RemoveAllWithNotice removes all directories in given path and |
type DiffLineType uint8 | type DiffLineType uint8 | ||||
const ( | const ( | ||||
DIFF_LINE_PLAIN DiffLineType = iota + 1 | |||||
DIFF_LINE_ADD | |||||
DIFF_LINE_DEL | |||||
DiffLinePlain DiffLineType = iota + 1 | |||||
DiffLineAdd | |||||
DiffLineDel | |||||
DIFF_LINE_SECTION | DIFF_LINE_SECTION | ||||
) | ) | ||||
type DiffFileType uint8 | type DiffFileType uint8 | ||||
const ( | const ( | ||||
DIFF_FILE_ADD DiffFileType = iota + 1 | |||||
DIFF_FILE_CHANGE | |||||
DIFF_FILE_DEL | |||||
DiffFileAdd DiffFileType = iota + 1 | |||||
DiffFileChange | |||||
DiffFileDel | |||||
DIFF_FILE_RENAME | DIFF_FILE_RENAME | ||||
) | ) | ||||
// Reproduce signs which are cutted for inline diff before. | // Reproduce signs which are cutted for inline diff before. | ||||
switch lineType { | switch lineType { | ||||
case DIFF_LINE_ADD: | |||||
case DiffLineAdd: | |||||
buf.WriteByte('+') | buf.WriteByte('+') | ||||
case DIFF_LINE_DEL: | |||||
case DiffLineDel: | |||||
buf.WriteByte('-') | buf.WriteByte('-') | ||||
} | } | ||||
for i := range diffs { | for i := range diffs { | ||||
switch { | switch { | ||||
case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DIFF_LINE_ADD: | |||||
case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd: | |||||
buf.Write(addedCodePrefix) | buf.Write(addedCodePrefix) | ||||
buf.WriteString(html.EscapeString(diffs[i].Text)) | buf.WriteString(html.EscapeString(diffs[i].Text)) | ||||
buf.Write(codeTagSuffix) | buf.Write(codeTagSuffix) | ||||
case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == DIFF_LINE_DEL: | |||||
case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == DiffLineDel: | |||||
buf.Write(removedCodePrefix) | buf.Write(removedCodePrefix) | ||||
buf.WriteString(html.EscapeString(diffs[i].Text)) | buf.WriteString(html.EscapeString(diffs[i].Text)) | ||||
buf.Write(codeTagSuffix) | buf.Write(codeTagSuffix) | ||||
LOOP: | LOOP: | ||||
for _, diffLine := range diffSection.Lines { | for _, diffLine := range diffSection.Lines { | ||||
switch diffLine.Type { | switch diffLine.Type { | ||||
case DIFF_LINE_ADD: | |||||
case DiffLineAdd: | |||||
addCount++ | addCount++ | ||||
case DIFF_LINE_DEL: | |||||
case DiffLineDel: | |||||
delCount++ | delCount++ | ||||
default: | default: | ||||
if matchDiffLine != nil { | if matchDiffLine != nil { | ||||
} | } | ||||
switch lineType { | switch lineType { | ||||
case DIFF_LINE_DEL: | |||||
case DiffLineDel: | |||||
if diffLine.RightIdx == 0 && diffLine.LeftIdx == idx-difference { | if diffLine.RightIdx == 0 && diffLine.LeftIdx == idx-difference { | ||||
matchDiffLine = diffLine | matchDiffLine = diffLine | ||||
} | } | ||||
case DIFF_LINE_ADD: | |||||
case DiffLineAdd: | |||||
if diffLine.LeftIdx == 0 && diffLine.RightIdx == idx+difference { | if diffLine.LeftIdx == 0 && diffLine.RightIdx == idx+difference { | ||||
matchDiffLine = diffLine | matchDiffLine = diffLine | ||||
} | } | ||||
// try to find equivalent diff line. ignore, otherwise | // try to find equivalent diff line. ignore, otherwise | ||||
switch diffLine.Type { | switch diffLine.Type { | ||||
case DIFF_LINE_ADD: | |||||
compareDiffLine = diffSection.GetLine(DIFF_LINE_DEL, diffLine.RightIdx) | |||||
case DiffLineAdd: | |||||
compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx) | |||||
if compareDiffLine == nil { | if compareDiffLine == nil { | ||||
return template.HTML(html.EscapeString(diffLine.Content)) | return template.HTML(html.EscapeString(diffLine.Content)) | ||||
} | } | ||||
diff1 = compareDiffLine.Content | diff1 = compareDiffLine.Content | ||||
diff2 = diffLine.Content | diff2 = diffLine.Content | ||||
case DIFF_LINE_DEL: | |||||
compareDiffLine = diffSection.GetLine(DIFF_LINE_ADD, diffLine.LeftIdx) | |||||
case DiffLineDel: | |||||
compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx) | |||||
if compareDiffLine == nil { | if compareDiffLine == nil { | ||||
return template.HTML(html.EscapeString(diffLine.Content)) | return template.HTML(html.EscapeString(diffLine.Content)) | ||||
} | } | ||||
switch { | switch { | ||||
case line[0] == ' ': | case line[0] == ' ': | ||||
diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine} | |||||
diffLine := &DiffLine{Type: DiffLinePlain, Content: line, LeftIdx: leftLine, RightIdx: rightLine} | |||||
leftLine++ | leftLine++ | ||||
rightLine++ | rightLine++ | ||||
curSection.Lines = append(curSection.Lines, diffLine) | curSection.Lines = append(curSection.Lines, diffLine) | ||||
case line[0] == '+': | case line[0] == '+': | ||||
curFile.Addition++ | curFile.Addition++ | ||||
diff.TotalAddition++ | diff.TotalAddition++ | ||||
diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine} | |||||
diffLine := &DiffLine{Type: DiffLineAdd, Content: line, RightIdx: rightLine} | |||||
rightLine++ | rightLine++ | ||||
curSection.Lines = append(curSection.Lines, diffLine) | curSection.Lines = append(curSection.Lines, diffLine) | ||||
continue | continue | ||||
case line[0] == '-': | case line[0] == '-': | ||||
curFile.Deletion++ | curFile.Deletion++ | ||||
diff.TotalDeletion++ | diff.TotalDeletion++ | ||||
diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine} | |||||
diffLine := &DiffLine{Type: DiffLineDel, Content: line, LeftIdx: leftLine} | |||||
if leftLine > 0 { | if leftLine > 0 { | ||||
leftLine++ | leftLine++ | ||||
} | } | ||||
curFile = &DiffFile{ | curFile = &DiffFile{ | ||||
Name: a, | Name: a, | ||||
Index: len(diff.Files) + 1, | Index: len(diff.Files) + 1, | ||||
Type: DIFF_FILE_CHANGE, | |||||
Type: DiffFileChange, | |||||
Sections: make([]*DiffSection, 0, 10), | Sections: make([]*DiffSection, 0, 10), | ||||
} | } | ||||
diff.Files = append(diff.Files, curFile) | diff.Files = append(diff.Files, curFile) | ||||
switch { | switch { | ||||
case strings.HasPrefix(line, "new file"): | case strings.HasPrefix(line, "new file"): | ||||
curFile.Type = DIFF_FILE_ADD | |||||
curFile.Type = DiffFileAdd | |||||
curFile.IsCreated = true | curFile.IsCreated = true | ||||
case strings.HasPrefix(line, "deleted"): | case strings.HasPrefix(line, "deleted"): | ||||
curFile.Type = DIFF_FILE_DEL | |||||
curFile.Type = DiffFileDel | |||||
curFile.IsDeleted = true | curFile.IsDeleted = true | ||||
case strings.HasPrefix(line, "index"): | case strings.HasPrefix(line, "index"): | ||||
curFile.Type = DIFF_FILE_CHANGE | |||||
curFile.Type = DiffFileChange | |||||
case strings.HasPrefix(line, "similarity index 100%"): | case strings.HasPrefix(line, "similarity index 100%"): | ||||
curFile.Type = DIFF_FILE_RENAME | curFile.Type = DIFF_FILE_RENAME | ||||
curFile.IsRenamed = true | curFile.IsRenamed = true | ||||
type RawDiffType string | type RawDiffType string | ||||
const ( | const ( | ||||
RAW_DIFF_NORMAL RawDiffType = "diff" | |||||
RAW_DIFF_PATCH RawDiffType = "patch" | |||||
RawDiffNormal RawDiffType = "diff" | |||||
RawDiffPatch RawDiffType = "patch" | |||||
) | ) | ||||
// 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. | ||||
var cmd *exec.Cmd | var cmd *exec.Cmd | ||||
switch diffType { | switch diffType { | ||||
case RAW_DIFF_NORMAL: | |||||
case RawDiffNormal: | |||||
if commit.ParentCount() == 0 { | if commit.ParentCount() == 0 { | ||||
cmd = exec.Command("git", "show", commitID) | cmd = exec.Command("git", "show", commitID) | ||||
} else { | } else { | ||||
c, _ := commit.Parent(0) | c, _ := commit.Parent(0) | ||||
cmd = exec.Command("git", "diff", "-M", c.ID.String(), commitID) | cmd = exec.Command("git", "diff", "-M", c.ID.String(), commitID) | ||||
} | } | ||||
case RAW_DIFF_PATCH: | |||||
case RawDiffPatch: | |||||
if commit.ParentCount() == 0 { | if commit.ParentCount() == 0 { | ||||
cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID) | cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID) | ||||
} else { | } else { |
dmp.Diff{dmp.DiffInsert, "bar"}, | dmp.Diff{dmp.DiffInsert, "bar"}, | ||||
dmp.Diff{dmp.DiffDelete, " baz"}, | dmp.Diff{dmp.DiffDelete, " baz"}, | ||||
dmp.Diff{dmp.DiffEqual, " biz"}, | dmp.Diff{dmp.DiffEqual, " biz"}, | ||||
}, DIFF_LINE_ADD)) | |||||
}, DiffLineAdd)) | |||||
assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | ||||
dmp.Diff{dmp.DiffEqual, "foo "}, | dmp.Diff{dmp.DiffEqual, "foo "}, | ||||
dmp.Diff{dmp.DiffDelete, "bar"}, | dmp.Diff{dmp.DiffDelete, "bar"}, | ||||
dmp.Diff{dmp.DiffInsert, " baz"}, | dmp.Diff{dmp.DiffInsert, " baz"}, | ||||
dmp.Diff{dmp.DiffEqual, " biz"}, | dmp.Diff{dmp.DiffEqual, " biz"}, | ||||
}, DIFF_LINE_DEL)) | |||||
}, DiffLineDel)) | |||||
} | } |
} | } | ||||
switch filterMode { | switch filterMode { | ||||
case FM_ASSIGN: | |||||
case FilterModeAssign: | |||||
sess.And("is_assigned=?", true) | sess.And("is_assigned=?", true) | ||||
case FM_CREATE: | |||||
case FilterModeCreate: | |||||
sess.And("is_poster=?", true) | sess.And("is_poster=?", true) | ||||
default: | default: | ||||
return ius, nil | return ius, nil | ||||
// Filter modes. | // Filter modes. | ||||
const ( | const ( | ||||
FM_ALL = iota | |||||
FM_ASSIGN | |||||
FM_CREATE | |||||
FM_MENTION | |||||
FilterModeAll = iota | |||||
FilterModeAssign | |||||
FilterModeCreate | |||||
FilterModeMention | |||||
) | ) | ||||
func parseCountResult(results []map[string][]byte) int64 { | func parseCountResult(results []map[string][]byte) int64 { | ||||
} | } | ||||
switch opts.FilterMode { | switch opts.FilterMode { | ||||
case FM_ALL, FM_ASSIGN: | |||||
case FilterModeAll, FilterModeAssign: | |||||
stats.OpenCount, _ = countSession(opts). | stats.OpenCount, _ = countSession(opts). | ||||
And("is_closed = ?", false). | And("is_closed = ?", false). | ||||
Count(&Issue{}) | Count(&Issue{}) | ||||
stats.ClosedCount, _ = countSession(opts). | stats.ClosedCount, _ = countSession(opts). | ||||
And("is_closed = ?", true). | And("is_closed = ?", true). | ||||
Count(&Issue{}) | Count(&Issue{}) | ||||
case FM_CREATE: | |||||
case FilterModeCreate: | |||||
stats.OpenCount, _ = countSession(opts). | stats.OpenCount, _ = countSession(opts). | ||||
And("poster_id = ?", opts.UserID). | And("poster_id = ?", opts.UserID). | ||||
And("is_closed = ?", false). | And("is_closed = ?", false). | ||||
And("poster_id = ?", opts.UserID). | And("poster_id = ?", opts.UserID). | ||||
And("is_closed = ?", true). | And("is_closed = ?", true). | ||||
Count(&Issue{}) | Count(&Issue{}) | ||||
case FM_MENTION: | |||||
case FilterModeMention: | |||||
stats.OpenCount, _ = countSession(opts). | stats.OpenCount, _ = countSession(opts). | ||||
Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
And("issue_user.uid = ?", opts.UserID). | And("issue_user.uid = ?", opts.UserID). | ||||
closedCountSession := countSession(true, isPull, repoID, repoIDs) | closedCountSession := countSession(true, isPull, repoID, repoIDs) | ||||
switch filterMode { | switch filterMode { | ||||
case FM_ASSIGN: | |||||
case FilterModeAssign: | |||||
openCountSession.And("assignee_id = ?", uid) | openCountSession.And("assignee_id = ?", uid) | ||||
closedCountSession.And("assignee_id = ?", uid) | closedCountSession.And("assignee_id = ?", uid) | ||||
case FM_CREATE: | |||||
case FilterModeCreate: | |||||
openCountSession.And("poster_id = ?", uid) | openCountSession.And("poster_id = ?", uid) | ||||
closedCountSession.And("poster_id = ?", uid) | closedCountSession.And("poster_id = ?", uid) | ||||
} | } | ||||
closedCountSession := countSession(true, isPull, repoID) | closedCountSession := countSession(true, isPull, repoID) | ||||
switch filterMode { | switch filterMode { | ||||
case FM_ASSIGN: | |||||
case FilterModeAssign: | |||||
openCountSession.And("assignee_id = ?", uid) | openCountSession.And("assignee_id = ?", uid) | ||||
closedCountSession.And("assignee_id = ?", uid) | closedCountSession.And("assignee_id = ?", uid) | ||||
case FM_CREATE: | |||||
case FilterModeCreate: | |||||
openCountSession.And("poster_id = ?", uid) | openCountSession.And("poster_id = ?", uid) | ||||
closedCountSession.And("poster_id = ?", uid) | closedCountSession.And("poster_id = ?", uid) | ||||
} | } |
assigneeID = ctx.QueryInt64("assignee") | assigneeID = ctx.QueryInt64("assignee") | ||||
posterID int64 | posterID int64 | ||||
) | ) | ||||
filterMode := models.FM_ALL | |||||
filterMode := models.FilterModeAll | |||||
switch viewType { | switch viewType { | ||||
case "assigned": | case "assigned": | ||||
filterMode = models.FM_ASSIGN | |||||
filterMode = models.FilterModeAssign | |||||
assigneeID = ctx.User.ID | assigneeID = ctx.User.ID | ||||
case "created_by": | case "created_by": | ||||
filterMode = models.FM_CREATE | |||||
filterMode = models.FilterModeCreate | |||||
posterID = ctx.User.ID | posterID = ctx.User.ID | ||||
case "mentioned": | case "mentioned": | ||||
filterMode = models.FM_MENTION | |||||
filterMode = models.FilterModeMention | |||||
} | } | ||||
var uid int64 = -1 | var uid int64 = -1 | ||||
MilestoneID: milestoneID, | MilestoneID: milestoneID, | ||||
Page: pager.Current(), | Page: pager.Current(), | ||||
IsClosed: isShowClosed, | IsClosed: isShowClosed, | ||||
IsMention: filterMode == models.FM_MENTION, | |||||
IsMention: filterMode == models.FilterModeMention, | |||||
IsPull: isPullList, | IsPull: isPullList, | ||||
Labels: selectLabels, | Labels: selectLabels, | ||||
SortType: sortType, | SortType: sortType, |
var ( | var ( | ||||
viewType string | viewType string | ||||
sortType = ctx.Query("sort") | sortType = ctx.Query("sort") | ||||
filterMode = models.FM_ALL | |||||
filterMode = models.FilterModeAll | |||||
assigneeID int64 | assigneeID int64 | ||||
posterID int64 | posterID int64 | ||||
) | ) | ||||
switch viewType { | switch viewType { | ||||
case "assigned": | case "assigned": | ||||
filterMode = models.FM_ASSIGN | |||||
filterMode = models.FilterModeAssign | |||||
assigneeID = ctxUser.ID | assigneeID = ctxUser.ID | ||||
case "created_by": | case "created_by": | ||||
filterMode = models.FM_CREATE | |||||
filterMode = models.FilterModeCreate | |||||
posterID = ctxUser.ID | posterID = ctxUser.ID | ||||
} | } | ||||
} | } | ||||
allCount += repo.NumOpenIssues | allCount += repo.NumOpenIssues | ||||
} | } | ||||
if filterMode != models.FM_ALL { | |||||
if filterMode != models.FilterModeAll { | |||||
// Calculate repository issue count with filter mode. | // Calculate repository issue count with filter mode. | ||||
numOpen, numClosed := repo.IssueStats(ctxUser.ID, filterMode, isPullList) | numOpen, numClosed := repo.IssueStats(ctxUser.ID, filterMode, isPullList) | ||||
repo.NumOpenIssues, repo.NumClosedIssues = int(numOpen), int(numClosed) | repo.NumOpenIssues, repo.NumClosedIssues = int(numOpen), int(numClosed) |