diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 4be4f2a6c..db163410c 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -562,15 +562,16 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines;
// When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines.
// To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header.
+ // Trailing EOL is only considered if the file has content.
// This NumLines is only used for the display on the UI: "xxx lines"
- hasTrailingEOL := bytes.HasSuffix(buf, []byte{'\n'})
- ctx.Data["HasTrailingEOL"] = hasTrailingEOL
- ctx.Data["HasTrailingEOLSet"] = true
if len(buf) == 0 {
ctx.Data["NumLines"] = 0
} else {
+ hasNoTrailingEOL := !bytes.HasSuffix(buf, []byte{'\n'})
+ ctx.Data["HasNoTrailingEOL"] = hasNoTrailingEOL
+
numLines := bytes.Count(buf, []byte{'\n'})
- if !hasTrailingEOL {
+ if hasNoTrailingEOL {
numLines++
}
ctx.Data["NumLines"] = numLines
diff --git a/templates/repo/file_info.tmpl b/templates/repo/file_info.tmpl
index 9cf4d28f4..6ae7c15a2 100644
--- a/templates/repo/file_info.tmpl
+++ b/templates/repo/file_info.tmpl
@@ -9,7 +9,7 @@
{{.NumLines}} {{ctx.Locale.TrN .NumLines "repo.line" "repo.lines"}}
{{end}}
- {{if and .HasTrailingEOLSet (not .HasTrailingEOL)}}
+ {{if .HasNoTrailingEOL}}
{{ctx.Locale.Tr "repo.no_eol.text"}}
diff --git a/tests/integration/repo_view_test.go b/tests/integration/repo_view_test.go
index b653d7f59..cc4084e21 100644
--- a/tests/integration/repo_view_test.go
+++ b/tests/integration/repo_view_test.go
@@ -179,43 +179,47 @@ func TestRepoViewFileLines(t *testing.T) {
TreePath: "test-4",
ContentReader: strings.NewReader("Really two\nlines\n"),
},
+ {
+ Operation: "create",
+ TreePath: "empty",
+ ContentReader: strings.NewReader(""),
+ },
+ {
+ Operation: "create",
+ TreePath: "seemingly-empty",
+ ContentReader: strings.NewReader("\n"),
+ },
})
defer f()
- t.Run("No EOL", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-1")
+ testEOL := func(t *testing.T, filename string, hasEOL bool) {
+ t.Helper()
+ req := NewRequestf(t, "GET", "%s/src/branch/main/%s", repo.Link(), filename)
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
fileInfo := htmlDoc.Find(".file-info").Text()
- assert.Contains(t, fileInfo, "No EOL")
+ if hasEOL {
+ assert.NotContains(t, fileInfo, "No EOL")
+ } else {
+ assert.Contains(t, fileInfo, "No EOL")
+ }
+ }
- req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-3")
- resp = MakeRequest(t, req, http.StatusOK)
- htmlDoc = NewHTMLParser(t, resp.Body)
+ t.Run("No EOL", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
- fileInfo = htmlDoc.Find(".file-info").Text()
- assert.Contains(t, fileInfo, "No EOL")
+ testEOL(t, "test-1", false)
+ testEOL(t, "test-3", false)
})
t.Run("With EOL", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-2")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- fileInfo := htmlDoc.Find(".file-info").Text()
- assert.NotContains(t, fileInfo, "No EOL")
-
- req = NewRequest(t, "GET", repo.Link()+"/src/branch/main/test-4")
- resp = MakeRequest(t, req, http.StatusOK)
- htmlDoc = NewHTMLParser(t, resp.Body)
-
- fileInfo = htmlDoc.Find(".file-info").Text()
- assert.NotContains(t, fileInfo, "No EOL")
+ testEOL(t, "test-2", true)
+ testEOL(t, "test-4", true)
+ testEOL(t, "empty", true)
+ testEOL(t, "seemingly-empty", true)
})
})
}