From dd6246877d8dd2de5f71f51c58a90eb155785c34 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 26 Mar 2014 16:41:16 -0400 Subject: [PATCH] Almost done diff page --- diff.txt | 137 --------------------------------------- models/git.go | 97 ++++++++++++--------------- models/issue.go | 25 ++++--- modules/base/template.go | 3 +- modules/base/tool.go | 12 ++++ public/css/gogs.css | 5 ++ routers/repo/repo.go | 7 +- templates/repo/diff.tmpl | 6 +- web.go | 1 - 9 files changed, 83 insertions(+), 210 deletions(-) delete mode 100644 diff.txt diff --git a/diff.txt b/diff.txt deleted file mode 100644 index 7b2522f89..000000000 --- a/diff.txt +++ /dev/null @@ -1,137 +0,0 @@ -commit c1a3d4fefbbbf332cd1cedda66e93bf40cc9713d -Author: Unknown -Date: Tue Mar 25 21:37:18 2014 -0400 - - Add mail notify for creating issue - -diff --git a/gogs.go b/gogs.go -index b62580f..f5a328a 100644 ---- a/gogs.go -+++ b/gogs.go -@@ -19,7 +19,7 @@ import ( - // Test that go1.2 tag above is included in builds. main.go refers to this definition. - const go12tag = true - --const APP_VER = "0.1.7.0325" -+const APP_VER = "0.1.8.0325" - - func init() { - base.AppVer = APP_VER -diff --git a/models/issue.go b/models/issue.go -index 2bdd083..2de6568 100644 ---- a/models/issue.go -+++ b/models/issue.go -@@ -59,7 +59,6 @@ func CreateIssue(userId, repoId, milestoneId, assigneeId int64, name, labels, co - Content: content, - } - _, err = orm.Insert(issue) -- // TODO: newIssueAction - return issue, err - } - -diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go -index 92acd20..d0decbe 100644 ---- a/modules/mailer/mail.go -+++ b/modules/mailer/mail.go -@@ -6,6 +6,7 @@ package mailer - - import ( - "encoding/hex" -+ "errors" - "fmt" - - "github.com/gogits/gogs/models" -@@ -15,12 +16,17 @@ import ( - ) - - // Create New mail message use MailFrom and MailUser --func NewMailMessage(To []string, subject, body string) Message { -- msg := NewHtmlMessage(To, base.MailService.User, subject, body) -+func NewMailMessageFrom(To []string, from, subject, body string) Message { -+ msg := NewHtmlMessage(To, from, subject, body) - msg.User = base.MailService.User - return msg - } - -+// Create New mail message use MailFrom and MailUser -+func NewMailMessage(To []string, subject, body string) Message { -+ return NewMailMessageFrom(To, base.MailService.User, subject, body) -+} -+ - func GetMailTmplData(user *models.User) map[interface{}]interface{} { - data := make(map[interface{}]interface{}, 10) - data["AppName"] = base.AppName -@@ -84,3 +90,33 @@ func SendActiveMail(r *middleware.Render, user *models.User) { - - SendAsync(&msg) - } -+ -+// SendNotifyMail sends mail notification of all watchers. -+func SendNotifyMail(userId, repoId int64, userName, repoName, subject, content string) error { -+ watches, err := models.GetWatches(repoId) -+ if err != nil { -+ return errors.New("mail.NotifyWatchers(get watches): " + err.Error()) -+ } -+ -+ tos := make([]string, 0, len(watches)) -+ for i := range watches { -+ uid := watches[i].UserId -+ if userId == uid { -+ continue -+ } -+ u, err := models.GetUserById(uid) -+ if err != nil { -+ return errors.New("mail.NotifyWatchers(get user): " + err.Error()) -+ } -+ tos = append(tos, u.Email) -+ } -+ -+ if len(tos) == 0 { -+ return nil -+ } -+ -+ msg := NewMailMessageFrom(tos, userName, subject, content) -+ msg.Info = fmt.Sprintf("Subject: %s, send notify emails", subject) -+ SendAsync(&msg) -+ return nil -+} -diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go -index da63e01..63861d8 100644 ---- a/modules/mailer/mailer.go -+++ b/modules/mailer/mailer.go -@@ -33,7 +33,7 @@ func (m Message) Content() string { - } - - // create mail content -- content := "From: " + m.User + "<" + m.From + -+ content := "From: " + m.From + "<" + m.User + - ">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body - return content - } -diff --git a/routers/repo/issue.go b/routers/repo/issue.go -index fc5bb98..242593f 100644 ---- a/routers/repo/issue.go -+++ b/routers/repo/issue.go -@@ -13,6 +13,7 @@ import ( - "github.com/gogits/gogs/modules/auth" - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" -+ "github.com/gogits/gogs/modules/mailer" - "github.com/gogits/gogs/modules/middleware" - ) - -@@ -86,6 +87,14 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat - return - } - -+ // Mail watchers. -+ if base.Service.NotifyMail { -+ if err = mailer.SendNotifyMail(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.Name, ctx.Repo.Repository.Name, issue.Name, issue.Content); err != nil { -+ ctx.Handle(200, "issue.CreateIssue", err) -+ return -+ } -+ } -+ - log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id) - ctx.Redirect(fmt.Sprintf("/%s/%s/issues/%d", params["username"], params["reponame"], issue.Index)) - } diff --git a/models/git.go b/models/git.go index 00621776d..ac9525779 100644 --- a/models/git.go +++ b/models/git.go @@ -15,6 +15,8 @@ import ( "strings" "github.com/gogits/git" + + "github.com/gogits/gogs/modules/base" ) // RepoFile represents a file object in git repository. @@ -249,6 +251,10 @@ type DiffLine struct { Content string } +func (d DiffLine) GetType() int { + return d.Type +} + type DiffSection struct { Name string Lines []*DiffLine @@ -274,16 +280,20 @@ const DIFF_HEAD = "diff --git " func ParsePatch(reader io.Reader) (*Diff, error) { scanner := bufio.NewScanner(reader) - var curFile *DiffFile - curSection := &DiffSection{ - Lines: make([]*DiffLine, 0, 10), - } - //var leftLine, rightLine int + var ( + curFile *DiffFile + curSection = &DiffSection{ + Lines: make([]*DiffLine, 0, 10), + } + + leftLine, rightLine int + ) + diff := &Diff{Files: make([]*DiffFile, 0)} var i int for scanner.Scan() { line := scanner.Text() - fmt.Println(i, line) + // fmt.Println(i, line) if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") { continue } @@ -293,31 +303,37 @@ func ParsePatch(reader io.Reader) (*Diff, error) { continue } if line[0] == ' ' { - diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line} + diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine} + leftLine++ + rightLine++ curSection.Lines = append(curSection.Lines, diffLine) continue } else if line[0] == '@' { curSection = &DiffSection{} curFile.Sections = append(curFile.Sections, curSection) ss := strings.Split(line, "@@") - diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: "@@" + ss[len(ss)-2] + "@@"} + diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line} curSection.Lines = append(curSection.Lines, diffLine) - if len(ss[len(ss)-1]) > 0 { - diffLine = &DiffLine{Type: DIFF_LINE_PLAIN, Content: ss[len(ss)-1]} - curSection.Lines = append(curSection.Lines, diffLine) - } + // Parse line number. + ranges := strings.Split(ss[len(ss)-2][1:], " ") + leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int() + rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int() continue } else if line[0] == '+' { curFile.Addition++ diff.TotalAddition++ - diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line} + diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine} + rightLine++ curSection.Lines = append(curSection.Lines, diffLine) continue } else if line[0] == '-' { curFile.Deletion++ diff.TotalDeletion++ - diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line} + diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine} + if leftLine > 0 { + leftLine++ + } curSection.Lines = append(curSection.Lines, diffLine) continue } @@ -365,8 +381,20 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { return nil, err } + // First commit of repository. if commit.ParentCount() == 0 { - return &Diff{}, err + rd, wr := io.Pipe() + go func() { + cmd := exec.Command("git", "show", commitid) + cmd.Dir = repoPath + cmd.Stdout = wr + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + cmd.Run() + wr.Close() + }() + defer rd.Close() + return ParsePatch(rd) } rd, wr := io.Pipe() @@ -377,47 +405,8 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr cmd.Run() - //if err != nil { - // return nil, err - //} wr.Close() }() - defer rd.Close() - return ParsePatch(rd) } - -/*func GetDiff(repoPath, commitid string) (*Diff, error) { - stdout, _, err := com.ExecCmdDir(repoPath, "git", "show", commitid) - if err != nil { - return nil, err - } - - // Sperate parts by file. - startIndex := strings.Index(stdout, "diff --git ") + 12 - - // First part is commit information. - // Check if it's a merge. - mergeIndex := strings.Index(stdout[:startIndex], "merge") - if mergeIndex > -1 { - mergeCommit := strings.SplitN(strings.Split(stdout[:startIndex], "\n")[1], "", 3)[2] - return GetDiff(repoPath, mergeCommit) - } - - parts := strings.Split(stdout[startIndex:], "diff --git ") - diff := &Diff{NumFiles: len(parts)} - diff.Files = make([]*DiffFile, 0, diff.NumFiles) - for _, part := range parts { - infos := strings.SplitN(part, "\n", 6) - maxIndex := len(infos) - 1 - infos[maxIndex] = strings.TrimSuffix(strings.TrimSuffix(infos[maxIndex], "\n"), "\n\\ No newline at end of file") - - file := &DiffFile{ - Name: strings.TrimPrefix(strings.Split(infos[0], " ")[0], "a/"), - Content: strings.Split(infos[maxIndex], "\n"), - } - diff.Files = append(diff.Files, file) - } - return diff, nil -}*/ diff --git a/models/issue.go b/models/issue.go index 47ec4edd0..97e51a0c5 100644 --- a/models/issue.go +++ b/models/issue.go @@ -173,14 +173,23 @@ type Comment struct { // CreateComment creates comment of issue or commit. func CreateComment(userId, issueId, commitId, line int64, content string) error { - _, err := orm.Insert(&Comment{ - PosterId: userId, - IssueId: issueId, - CommitId: commitId, - Line: line, - Content: content, - }) - return err + sess := orm.NewSession() + defer sess.Close() + sess.Begin() + + if _, err := orm.Insert(&Comment{PosterId: userId, IssueId: issueId, + CommitId: commitId, Line: line, Content: content, + }); err != nil { + sess.Rollback() + return err + } + + rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?" + if _, err := sess.Exec(rawSql, issueId); err != nil { + sess.Rollback() + return err + } + return sess.Commit() } // GetIssueComments returns list of comment by given issue id. diff --git a/modules/base/template.go b/modules/base/template.go index e577bd7c3..dca76fafd 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -70,5 +70,6 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "SubStr": func(str string, start, length int) string { return str[start : start+length] }, - "DiffTypeToStr": DiffTypeToStr, + "DiffTypeToStr": DiffTypeToStr, + "DiffLineTypeToStr": DiffLineTypeToStr, } diff --git a/modules/base/tool.go b/modules/base/tool.go index 15d42fa75..6f4fbe836 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -552,3 +552,15 @@ func DiffTypeToStr(diffType int) string { return "unknown" } } + +func DiffLineTypeToStr(diffType int) string { + switch diffType { + case 2: + return "add" + case 3: + return "del" + case 4: + return "tag" + } + return "same" +} diff --git a/public/css/gogs.css b/public/css/gogs.css index 6d498e0e6..436067ed8 100755 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -980,6 +980,11 @@ html, body { padding: 20px; } +.diff-file-box .code-diff tbody tr.tag-code td, .diff-file-box .code-diff tbody tr.tag-code pre { + background-color: #E0E0E0 !important; + border-color: #ADADAD !important; +} + .diff-file-box .code-diff tbody tr.add-code td, .diff-file-box .code-diff tbody tr.add-code pre { background-color: #d1ffd6 !important; border-color: #b4e2b4 !important; diff --git a/routers/repo/repo.go b/routers/repo/repo.go index acf025a28..435587472 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -71,7 +71,6 @@ func Single(ctx *middleware.Context, params martini.Params) { // Branches. brs, err := models.GetBranches(params["username"], params["reponame"]) if err != nil { - //log.Error("repo.Single(GetBranches): %v", err) ctx.Handle(404, "repo.Single(GetBranches)", err) return } else if ctx.Repo.Repository.IsBare { @@ -79,14 +78,11 @@ func Single(ctx *middleware.Context, params martini.Params) { ctx.HTML(200, "repo/single") return } - ctx.Data["Branches"] = brs repoFile, err := models.GetTargetFile(params["username"], params["reponame"], params["branchname"], params["commitid"], treename) - if err != nil && err != models.ErrRepoFileNotExist { - //log.Error("repo.Single(GetTargetFile): %v", err) ctx.Handle(404, "repo.Single(GetTargetFile)", err) return } @@ -133,7 +129,6 @@ func Single(ctx *middleware.Context, params martini.Params) { files, err := models.GetReposFiles(params["username"], params["reponame"], params["branchname"], params["commitid"], treename) if err != nil { - //log.Error("repo.Single(GetReposFiles): %v", err) ctx.Handle(404, "repo.Single(GetReposFiles)", err) return } @@ -189,7 +184,7 @@ func Single(ctx *middleware.Context, params martini.Params) { } } - // Get latest commit according username and repo name + // Get latest commit according username and repo name. commit, err := models.GetCommit(params["username"], params["reponame"], params["branchname"], params["commitid"]) if err != nil { diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index ab13c4017..38f19b36f 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -65,12 +65,12 @@ {{range .Sections}} {{range .Lines}} - + - + {{if .LeftIdx}}{{.LeftIdx}}{{end}} - + {{if .RightIdx}}{{.RightIdx}}{{end}}
{{.Content}}
diff --git a/web.go b/web.go index 6bc55908b..3c7abc58c 100644 --- a/web.go +++ b/web.go @@ -159,7 +159,6 @@ func runWeb(*cli.Context) { r.Get("/commits/:branchname", repo.Commits) }, ignSignIn, middleware.RepoAssignment(true)) - // TODO: implement single commit page m.Get("/:username/:reponame/commit/:commitid/**", ignSignIn, middleware.RepoAssignment(true), repo.Diff) m.Get("/:username/:reponame/commit/:commitid", ignSignIn, middleware.RepoAssignment(true), repo.Diff)