Skip to content

Commit 947604d

Browse files
committed
Replace repo.namedBlob by git.TreeEntry.
`namedBlob` turned out to be a poor imitation of a `TreeEntry`. Using the latter directly shorten this code.
1 parent 79af6e3 commit 947604d

File tree

5 files changed

+72
-49
lines changed

5 files changed

+72
-49
lines changed

routers/web/repo/view.go

+38-44
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ const (
5050
tplMigrating base.TplName = "repo/migrate/migrating"
5151
)
5252

53-
type namedBlob struct {
54-
name string
55-
isSymlink bool
56-
blob *git.Blob
57-
}
58-
5953
// locate a README for a tree in one of the supported paths.
6054
//
6155
// entries is passed to reduce calls to ListEntries(), so
@@ -64,14 +58,14 @@ type namedBlob struct {
6458
// entries == ctx.Repo.Commit.SubTree(ctx.Repo.TreePath).ListEntries()
6559
//
6660
// FIXME: There has to be a more efficient way of doing this
67-
func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*namedBlob, error) {
61+
func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (string, *git.TreeEntry, error) {
6862
// Create a list of extensions in priority order
6963
// 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md
7064
// 2. Txt files - e.g. README.txt
7165
// 3. No extension - e.g. README
7266
exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority
7367
extCount := len(exts)
74-
readmeFiles := make([]*namedBlob, extCount+1)
68+
readmeFiles := make([]*git.TreeEntry, extCount+1)
7569

7670
docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/)
7771
for _, entry := range entries {
@@ -98,28 +92,21 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
9892
}
9993
if i, ok := util.IsReadmeFileExtension(entry.Name(), exts...); ok {
10094
log.Debug("Potential readme file: %s", entry.Name())
101-
if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) {
102-
name := entry.Name()
103-
isSymlink := entry.IsLink()
104-
target := entry
105-
if isSymlink {
106-
var err error
107-
target, err = entry.FollowLinks()
95+
if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].Name(), entry.Blob().Name()) {
96+
if entry.IsLink() {
97+
target, err := entry.FollowLinks()
10898
if err != nil && !git.IsErrBadLink(err) {
109-
return nil, err
110-
}
111-
}
112-
if target != nil && (target.IsExecutable() || target.IsRegular()) {
113-
readmeFiles[i] = &namedBlob{
114-
name,
115-
isSymlink,
116-
target.Blob(),
99+
return "", nil, err
100+
} else if target != nil && (target.IsExecutable() || target.IsRegular()) {
101+
readmeFiles[i] = entry
117102
}
103+
} else {
104+
readmeFiles[i] = entry
118105
}
119106
}
120107
}
121108
}
122-
var readmeFile *namedBlob
109+
var readmeFile *git.TreeEntry
123110
for _, f := range readmeFiles {
124111
if f != nil {
125112
readmeFile = f
@@ -140,20 +127,20 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
140127
var err error
141128
childEntries, err := subTree.ListEntries()
142129
if err != nil {
143-
return nil, err
130+
return "", nil, err
144131
}
145-
readmeFile, err = findReadmeFileInEntries(ctx, childEntries)
132+
133+
subfolder, readmeFile, err := findReadmeFileInEntries(ctx, childEntries)
146134
if err != nil && !git.IsErrNotExist(err) {
147-
return nil, err
135+
return "", nil, err
148136
}
149137
if readmeFile != nil {
150-
readmeFile.name = subTreeEntry.Name() + "/" + readmeFile.name
151-
break
138+
return path.Join(subTreeEntry.Name(), subfolder), readmeFile, nil
152139
}
153140
}
154141
}
155142

156-
return readmeFile, nil
143+
return "", readmeFile, nil
157144
}
158145

159146
func renderDirectory(ctx *context.Context, treeLink string) {
@@ -177,16 +164,13 @@ func renderDirectory(ctx *context.Context, treeLink string) {
177164
return
178165
}
179166

180-
readmeFile, err := findReadmeFileInEntries(ctx, entries)
167+
subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries)
181168
if err != nil {
182169
ctx.ServerError("findReadmeFileInEntries", err)
183170
return
184171
}
185-
if readmeFile == nil {
186-
return
187-
}
188172

189-
renderReadmeFile(ctx, readmeFile, fmt.Sprintf("%s/%s", treeLink, readmeFile.name))
173+
renderReadmeFile(ctx, subfolder, readmeFile, treeLink)
190174
}
191175

192176
// localizedExtensions prepends the provided language code with and without a
@@ -270,25 +254,35 @@ func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileIn
270254
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
271255
}
272256

273-
func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelink string) {
257+
func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry, readmeTreelink string) {
258+
target := readmeFile
259+
if readmeFile != nil && readmeFile.IsLink() {
260+
target, _ = readmeFile.FollowLinks()
261+
}
262+
if target == nil {
263+
// if findReadmeFile() failed and/or gave us a broken symlink (which it shouldn't)
264+
// simply skip rendering the README
265+
return
266+
}
267+
274268
ctx.Data["RawFileLink"] = ""
275269
ctx.Data["ReadmeInList"] = true
276270
ctx.Data["ReadmeExist"] = true
277-
ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
271+
ctx.Data["FileIsSymlink"] = readmeFile.IsLink()
278272

279-
buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, readmeFile.blob)
273+
buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, target.Blob())
280274
if err != nil {
281275
ctx.ServerError("getFileReader", err)
282276
return
283277
}
284278
defer dataRc.Close()
285279

286280
ctx.Data["FileIsText"] = fInfo.isTextFile
287-
ctx.Data["FileName"] = readmeFile.name
281+
ctx.Data["FileName"] = path.Join(subfolder, readmeFile.Name())
288282
ctx.Data["IsLFSFile"] = fInfo.isLFSFile
289283

290284
if fInfo.isLFSFile {
291-
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
285+
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.Name()))
292286
ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.Link(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
293287
}
294288

@@ -306,19 +300,19 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
306300

307301
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
308302

309-
if markupType := markup.Type(readmeFile.name); markupType != "" {
303+
if markupType := markup.Type(readmeFile.Name()); markupType != "" {
310304
ctx.Data["IsMarkup"] = true
311305
ctx.Data["MarkupType"] = markupType
312306

313307
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
314308
Ctx: ctx,
315-
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.name), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
316-
URLPrefix: path.Dir(readmeTreelink),
309+
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.Name()), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
310+
URLPrefix: path.Join(readmeTreelink, subfolder),
317311
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
318312
GitRepo: ctx.Repo.GitRepo,
319313
}, rd)
320314
if err != nil {
321-
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.name, ctx.Repo.Repository, err)
315+
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
322316
buf := &bytes.Buffer{}
323317
ctx.Data["EscapeStatus"], _ = charset.EscapeControlStringReader(rd, buf, ctx.Locale)
324318
ctx.Data["FileContent"] = buf.String()

tests/gitea-repositories-meta/user2/repo1.git/objects/46/49299398e4d39a5c09eb4f534df6f1e1eb87cc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
x��QJ�0E��*f>���I@D��_�!n`�L^�m�hS�� ����^�e]�
2+
�3wu�n�zr�,��]�.6ԋ���C��$u�Mr����
3+
1za�I\����� 㘺�(>�T6x����:�����Oײ|�u9~l"�i$c�� ��kZ[���S�
4+
S��������C;���Ev�M�!�#G�30�ǘ���y�]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
4649299398e4d39a5c09eb4f534df6f1e1eb87cc

tests/integration/repo_test.go

+29-5
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ func TestViewRepoDirectoryReadme(t *testing.T) {
362362
missing("symlink-loop", "/user2/readme-test/src/branch/symlink-loop/")
363363
}
364364

365-
func TestMarkDownImage(t *testing.T) {
365+
func TestMarkDownReadmeImage(t *testing.T) {
366366
defer tests.PrepareTestEnv(t)()
367367

368368
session := loginUser(t, "user2")
@@ -371,13 +371,37 @@ func TestMarkDownImage(t *testing.T) {
371371
resp := session.MakeRequest(t, req, http.StatusOK)
372372

373373
htmlDoc := NewHTMLParser(t, resp.Body)
374-
_, exists := htmlDoc.doc.Find(`img[src="/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg"]`).Attr("src")
375-
assert.True(t, exists, "Repo home page markdown image link check failed")
374+
src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src")
375+
assert.True(t, exists, "Image not found in README")
376+
assert.Equal(t, src, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg")
376377

377378
req = NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check/README.md")
378379
resp = session.MakeRequest(t, req, http.StatusOK)
379380

380381
htmlDoc = NewHTMLParser(t, resp.Body)
381-
_, exists = htmlDoc.doc.Find(`img[src="/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg"]`).Attr("src")
382-
assert.True(t, exists, "Repo src page markdown image link check failed")
382+
src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src")
383+
assert.Equal(t, src, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg")
384+
}
385+
386+
func TestMarkDownReadmeImageSubfolder(t *testing.T) {
387+
defer tests.PrepareTestEnv(t)()
388+
389+
session := loginUser(t, "user2")
390+
391+
// this branch has the README in the special docs/README.md location
392+
req := NewRequest(t, "GET", "/user2/repo1/src/branch/sub-home-md-img-check")
393+
resp := session.MakeRequest(t, req, http.StatusOK)
394+
395+
htmlDoc := NewHTMLParser(t, resp.Body)
396+
src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src")
397+
assert.True(t, exists, "Image not found in README")
398+
assert.Equal(t, src, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg")
399+
400+
req = NewRequest(t, "GET", "/user2/repo1/src/branch/sub-home-md-img-check/docs/README.md")
401+
resp = session.MakeRequest(t, req, http.StatusOK)
402+
403+
htmlDoc = NewHTMLParser(t, resp.Body)
404+
src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src")
405+
assert.True(t, exists, "Image not found in markdown file")
406+
assert.Equal(t, src, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg")
383407
}

0 commit comments

Comments
 (0)