)
var (
- Version = "0.1.0"
+ Version = "0.2.0"
sha1DigestRe = regexp.MustCompilePOSIX("([0-9a-f]{40,40})")
defaultLinks = []string{}
repo *git.Repository
+ notesTree *object.Tree
commentsTree *object.Tree
renderableSchemes = map[string]struct{}{
return lines
}
-func getCommentsRaw(what plumbing.Hash) []byte {
- if commentsTree == nil {
+func lineURLize(urlPrefix, line string) string {
+ cols := strings.Split(html.EscapeString(line), " ")
+ for i, col := range cols {
+ if u := urlParse(col); u != nil {
+ cols[i] = makeA(col, col)
+ continue
+ }
+ cols[i] = sha1DigestRe.ReplaceAllString(col, makeA(
+ urlPrefix+"/$1", "$1",
+ ))
+ }
+ return strings.Join(cols, " ")
+}
+
+func getNote(tree *object.Tree, what plumbing.Hash) []byte {
+ if tree == nil {
return nil
}
- entry, err := commentsTree.FindEntry(what.String())
- if err != nil {
+ var entry *object.TreeEntry
+ var err error
+ paths := make([]string, 3)
+ paths[0] = what.String()
+ paths[1] = paths[0][:2] + "/" + paths[0][2:]
+ paths[2] = paths[1][:4+1] + "/" + paths[1][4+1:]
+ for _, p := range paths {
+ entry, err = tree.FindEntry(p)
+ if err == nil {
+ break
+ }
+ }
+ if entry == nil {
return nil
}
blob, err := repo.BlobObject(entry.Hash)
makeErr(err)
}
- if cfg.CommentsNotesRef != "" {
- if notes, err := repo.Notes(); err == nil {
- var comments *plumbing.Reference
- notes.ForEach(func(ref *plumbing.Reference) error {
- if string(ref.Name()) == cfg.CommentsNotesRef {
- comments = ref
- }
- return nil
- })
- if comments != nil {
- if commentsCommit, err := repo.CommitObject(comments.Hash()); err == nil {
- commentsTree, _ = commentsCommit.Tree()
- }
+ if notes, err := repo.Notes(); err == nil {
+ var notesRef *plumbing.Reference
+ var commentsRef *plumbing.Reference
+ notes.ForEach(func(ref *plumbing.Reference) error {
+ switch string(ref.Name()) {
+ case "refs/notes/commits":
+ notesRef = ref
+ case cfg.CommentsNotesRef:
+ commentsRef = ref
+ }
+ return nil
+ })
+ if notesRef != nil {
+ if commentsCommit, err := repo.CommitObject(notesRef.Hash()); err == nil {
+ notesTree, _ = commentsCommit.Tree()
+ }
+ }
+ if commentsRef != nil {
+ if commentsCommit, err := repo.CommitObject(commentsRef.Hash()); err == nil {
+ commentsTree, _ = commentsCommit.Tree()
}
}
}
break
}
etagHash.Write(commit.Hash[:])
- commentsRaw := getCommentsRaw(commit.Hash)
+ commentsRaw := getNote(commentsTree, commit.Hash)
etagHash.Write(commentsRaw)
entries = append(entries, TableEntry{commit, commentsRaw})
}
}
etagHash.Write([]byte("ENTRY"))
etagHash.Write(commit.Hash[:])
- commentsRaw := getCommentsRaw(commit.Hash)
+ notesRaw := getNote(notesTree, commit.Hash)
+ etagHash.Write(notesRaw)
+ commentsRaw := getNote(commentsTree, commit.Hash)
etagHash.Write(commentsRaw)
checkETag(etagHash)
lines := msgSplit(commit.Message)
when, commit.Hash.String(), title,
)))
for _, line := range lines[2:] {
- line = html.EscapeString(line)
- cols := strings.Split(line, " ")
- for i, col := range cols {
- if u := urlParse(col); u != nil {
- cols[i] = makeA(col, col)
- continue
- }
- cols[i] = sha1DigestRe.ReplaceAllString(col, makeA(
- cfg.URLPrefix+"/$1", "$1",
- ))
- }
- line = strings.Join(cols, " ")
- out.Write([]byte(line + "\n"))
+ out.Write([]byte(lineURLize(cfg.URLPrefix, line) + "\n"))
}
out.Write([]byte("</pre>\n<hr/>\n"))
+ if len(notesRaw) > 0 {
+ out.Write([]byte("Note:<pre>\n" + string(notesRaw) + "\n</pre>\n<hr/>\n"))
+ }
if cfg.CommentsEmail != "" {
out.Write([]byte("[" + makeA(
"mailto:"+cfg.CommentsEmail+"?subject="+commit.Hash.String(),
for i, comment := range parseComments(commentsRaw) {
out.Write([]byte(fmt.Sprintf(
"<dt><a name=\"comment%d\"><a href=\"#comment%d\">comment %d</a>:"+
- "</dt>\n<dd><pre>\n%s\n</pre></dd>\n",
- i, i, i, html.EscapeString(comment),
+ "</dt>\n<dd><pre>\n",
+ i, i, i,
)))
+ lines = strings.Split(comment, "\n")
+ for _, line := range lines[:3] {
+ out.Write([]byte(line + "\n"))
+ }
+ for _, line := range lines[3:] {
+ out.Write([]byte(lineURLize(cfg.URLPrefix, line) + "\n"))
+ }
+ out.Write([]byte("</pre></dd>\n"))
}
out.Write([]byte("</dl>\n"))
} else {