aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web/repo/view.go
diff options
context:
space:
mode:
authorNick <nick.guenther@polymtl.ca>2023-03-15 17:51:39 -0400
committerGitHub <noreply@github.com>2023-03-15 16:51:39 -0500
commit6aef9e0a2f7df03893f00a657749b29e11ed839e (patch)
tree76478e021554897ca804e39c1d37e53ef0d06574 /routers/web/repo/view.go
parent19cbd5c3d9893647d85f7fc5b873059d1d6d436d (diff)
downloadgitea-6aef9e0a2f7df03893f00a657749b29e11ed839e.tar.gz
gitea-6aef9e0a2f7df03893f00a657749b29e11ed839e.zip
Replace `repo.namedBlob` by `git.TreeEntry`. (#22898)
`namedBlob` turned out to be a poor imitation of a `TreeEntry`. Using the latter directly shortens this code. This partially undoes https://github.com/go-gitea/gitea/pull/23152/, which I found a merge conflict with, and also expands the test it added to cover the subtle README-in-a-subfolder case.
Diffstat (limited to 'routers/web/repo/view.go')
-rw-r--r--routers/web/repo/view.go82
1 files changed, 38 insertions, 44 deletions
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 8663e11382..4d49ab6359 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -50,12 +50,6 @@ const (
tplMigrating base.TplName = "repo/migrate/migrating"
)
-type namedBlob struct {
- name string
- isSymlink bool
- blob *git.Blob
-}
-
// locate a README for a tree in one of the supported paths.
//
// entries is passed to reduce calls to ListEntries(), so
@@ -64,14 +58,14 @@ type namedBlob struct {
// entries == ctx.Repo.Commit.SubTree(ctx.Repo.TreePath).ListEntries()
//
// FIXME: There has to be a more efficient way of doing this
-func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*namedBlob, error) {
+func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (string, *git.TreeEntry, error) {
// Create a list of extensions in priority order
// 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md
// 2. Txt files - e.g. README.txt
// 3. No extension - e.g. README
exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority
extCount := len(exts)
- readmeFiles := make([]*namedBlob, extCount+1)
+ readmeFiles := make([]*git.TreeEntry, extCount+1)
docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/)
for _, entry := range entries {
@@ -98,28 +92,21 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
}
if i, ok := util.IsReadmeFileExtension(entry.Name(), exts...); ok {
log.Debug("Potential readme file: %s", entry.Name())
- if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) {
- name := entry.Name()
- isSymlink := entry.IsLink()
- target := entry
- if isSymlink {
- var err error
- target, err = entry.FollowLinks()
+ if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].Name(), entry.Blob().Name()) {
+ if entry.IsLink() {
+ target, err := entry.FollowLinks()
if err != nil && !git.IsErrBadLink(err) {
- return nil, err
- }
- }
- if target != nil && (target.IsExecutable() || target.IsRegular()) {
- readmeFiles[i] = &namedBlob{
- name,
- isSymlink,
- target.Blob(),
+ return "", nil, err
+ } else if target != nil && (target.IsExecutable() || target.IsRegular()) {
+ readmeFiles[i] = entry
}
+ } else {
+ readmeFiles[i] = entry
}
}
}
}
- var readmeFile *namedBlob
+ var readmeFile *git.TreeEntry
for _, f := range readmeFiles {
if f != nil {
readmeFile = f
@@ -140,20 +127,20 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
var err error
childEntries, err := subTree.ListEntries()
if err != nil {
- return nil, err
+ return "", nil, err
}
- readmeFile, err = findReadmeFileInEntries(ctx, childEntries)
+
+ subfolder, readmeFile, err := findReadmeFileInEntries(ctx, childEntries)
if err != nil && !git.IsErrNotExist(err) {
- return nil, err
+ return "", nil, err
}
if readmeFile != nil {
- readmeFile.name = subTreeEntry.Name() + "/" + readmeFile.name
- break
+ return path.Join(subTreeEntry.Name(), subfolder), readmeFile, nil
}
}
}
- return readmeFile, nil
+ return "", readmeFile, nil
}
func renderDirectory(ctx *context.Context, treeLink string) {
@@ -177,16 +164,13 @@ func renderDirectory(ctx *context.Context, treeLink string) {
return
}
- readmeFile, err := findReadmeFileInEntries(ctx, entries)
+ subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries)
if err != nil {
ctx.ServerError("findReadmeFileInEntries", err)
return
}
- if readmeFile == nil {
- return
- }
- renderReadmeFile(ctx, readmeFile, fmt.Sprintf("%s/%s", treeLink, readmeFile.name))
+ renderReadmeFile(ctx, subfolder, readmeFile, treeLink)
}
// localizedExtensions prepends the provided language code with and without a
@@ -270,13 +254,23 @@ func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileIn
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
}
-func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelink string) {
+func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry, readmeTreelink string) {
+ target := readmeFile
+ if readmeFile != nil && readmeFile.IsLink() {
+ target, _ = readmeFile.FollowLinks()
+ }
+ if target == nil {
+ // if findReadmeFile() failed and/or gave us a broken symlink (which it shouldn't)
+ // simply skip rendering the README
+ return
+ }
+
ctx.Data["RawFileLink"] = ""
ctx.Data["ReadmeInList"] = true
ctx.Data["ReadmeExist"] = true
- ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
+ ctx.Data["FileIsSymlink"] = readmeFile.IsLink()
- buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, readmeFile.blob)
+ buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, target.Blob())
if err != nil {
ctx.ServerError("getFileReader", err)
return
@@ -284,11 +278,11 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
defer dataRc.Close()
ctx.Data["FileIsText"] = fInfo.isTextFile
- ctx.Data["FileName"] = readmeFile.name
+ ctx.Data["FileName"] = path.Join(subfolder, readmeFile.Name())
ctx.Data["IsLFSFile"] = fInfo.isLFSFile
if fInfo.isLFSFile {
- filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
+ filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.Name()))
ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.Link(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
}
@@ -306,19 +300,19 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
- if markupType := markup.Type(readmeFile.name); markupType != "" {
+ if markupType := markup.Type(readmeFile.Name()); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
- 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).
- URLPrefix: path.Dir(readmeTreelink),
+ 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).
+ URLPrefix: path.Join(readmeTreelink, subfolder),
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
GitRepo: ctx.Repo.GitRepo,
}, rd)
if err != nil {
- log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.name, ctx.Repo.Repository, err)
+ log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
buf := &bytes.Buffer{}
ctx.Data["EscapeStatus"], _ = charset.EscapeControlStringReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = buf.String()