Use accurate line numbers for the commit message

We used a magic number matching the most common use-case, we now compute
the offset based on the way Gerrit generates the COMMIT_MSG.

Change-Id: Ieb5e5e199beb122336cf3a7568d0313049aa0f57
diff --git a/lint/lint.go b/lint/lint.go
index 9d8a208..709fad3 100644
--- a/lint/lint.go
+++ b/lint/lint.go
@@ -148,11 +148,9 @@
 var issueRegexp = regexp.MustCompile("(?i)issue [0-9]{3,}")
 var footerRegexp = regexp.MustCompile("^[A-Za-z0-9-]+:")
 
-func (l *linter) checkMessage(commitmsg []string) {
+func (l *linter) checkMessage(commitmsg []string, offset int) {
 	warn := func(line int, message string) {
-		// Gerrit includes some extra header lines before the commit message.
-		// TODO(mdempsky): Is it always exactly six lines?
-		l.comment("/COMMIT_MSG", line+6, "warning", message)
+		l.comment("/COMMIT_MSG", line+offset, "warning", message)
 	}
 
 	lengthWarning := false
@@ -249,7 +247,15 @@
 	if err != nil {
 		return err
 	}
-	linter.checkMessage(commitmsg)
+	// Gerrit always adds 1 line per parent and 4 lines for authorship as header,
+	// and 1 blank line as separator; let's compute the offset.
+	// See https://gerrit.googlesource.com/gerrit/+/master/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java
+	parents, err := git.Line("show", "-s", "--pretty=tformat:%P", rev)
+	if err != nil {
+		return err
+	}
+	parentCount := len(strings.Split(parents, " "))
+	linter.checkMessage(commitmsg, parentCount+5)
 
 	if err = gerrit.Post(ref, linter.review()); err != nil {
 		return err
diff --git a/lint/lint_test.go b/lint/lint_test.go
index 857c0ed..76f0dce 100644
--- a/lint/lint_test.go
+++ b/lint/lint_test.go
@@ -52,7 +52,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    7,
+					Line:    1,
 					Message: "[warning] Commit message lines should be 72 characters or fewer.",
 				},
 			},
@@ -66,7 +66,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    8,
+					Line:    2,
 					Message: "[warning] Subject line and body should be separated by a blank line.",
 				},
 			},
@@ -81,7 +81,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    9,
+					Line:    3,
 					Message: "[warning] Please use 'Bug: issue NNNN' and place it just above the Change-Id line.",
 				},
 			},
@@ -94,7 +94,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    7,
+					Line:    1,
 					Message: "[warning] Please use 'Bug: issue NNNN' and place it just above the Change-Id line.",
 				},
 			},
@@ -108,7 +108,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    9,
+					Line:    3,
 					Message: "[warning] Footer fields should be in Title-Case.",
 				},
 			},
@@ -130,7 +130,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    9,
+					Line:    3,
 					Message: "[warning] Footer lines should be separated from message body by a blank line.",
 				},
 			},
@@ -145,7 +145,7 @@
 			},
 			warnings: []gerrit.Comment{
 				gerrit.Comment{
-					Line:    9,
+					Line:    3,
 					Message: "[warning] Footer lines should form a single paragraph (i.e. must not be separated by blank lines.)",
 				},
 			},
@@ -154,7 +154,7 @@
 
 	for _, test := range tests {
 		linter := newLinter("fakeref")
-		linter.checkMessage(test.message)
+		linter.checkMessage(test.message, 0)
 		checkEqual(t, test.warnings, linter.comments["/COMMIT_MSG"])
 	}
 }