Browse Source

Almost done diff page

Unknown 11 years ago
parent
commit
dd6246877d
9 changed files with 83 additions and 210 deletions
  1. 0 137
      diff.txt
  2. 43 54
      models/git.go
  3. 17 8
      models/issue.go
  4. 2 1
      modules/base/template.go
  5. 12 0
      modules/base/tool.go
  6. 5 0
      public/css/gogs.css
  7. 1 6
      routers/repo/repo.go
  8. 3 3
      templates/repo/diff.tmpl
  9. 0 1
      web.go

+ 0 - 137
diff.txt

@@ -1,137 +0,0 @@
-commit c1a3d4fefbbbf332cd1cedda66e93bf40cc9713d
-Author: Unknown <joe2010xtmf@163.com>
-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))
- }

+ 43 - 54
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
-}*/

+ 17 - 8
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.

+ 2 - 1
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,
 }

+ 12 - 0
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"
+}

+ 5 - 0
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;

+ 1 - 6
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 {

+ 3 - 3
templates/repo/diff.tmpl

@@ -65,12 +65,12 @@
                     <tbody>
                         {{range .Sections}}
                         {{range .Lines}}
-                        <tr class="same-code nl-1 ol-1">
+                        <tr class="{{DiffLineTypeToStr .Type}}-code nl-1 ol-1">
                             <td class="lines-num lines-num-old">
-                                <span rel="L1"></span>
+                                <span rel="L1">{{if .LeftIdx}}{{.LeftIdx}}{{end}}</span>
                             </td>
                             <td class="lines-num lines-num-new">
-                                <span rel="L1"></span>
+                                <span rel="L1">{{if .RightIdx}}{{.RightIdx}}{{end}}</span>
                             </td>
                             <td class="lines-code">
                                 <pre>{{.Content}}</pre>

+ 0 - 1
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)