Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render READMEs in docs/ .gitea or .github from root #10361

Merged
merged 9 commits into from
Feb 21, 2020
Prev Previous commit
Next Next commit
handle symlinks and avoid sort
  • Loading branch information
zeripath committed Feb 20, 2020
commit 6d78bafe377aabe8e946779415f5fbd920af8834
101 changes: 85 additions & 16 deletions routers/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,31 @@ const (
tplMigrating base.TplName = "repo/migrating"
)

type namedBlob struct {
name string
blob *git.Blob
}

func followLinks(entry *git.TreeEntry) (*git.TreeEntry, error) {
var err error
for i := 0; i < 999; i++ {
if entry.IsLink() {
entry, err = entry.FollowLink()
if err != nil {
return nil, err
}
} else {
break
}
}
if entry.IsRegular() || entry.IsExecutable() {
return entry, nil
}
return nil, nil
}

// FIXME: There has to be a more efficient way of doing this
lafriks marked this conversation as resolved.
Show resolved Hide resolved
func getReadmeFileFromPath(commit *git.Commit, treePath string) (*git.Blob, error) {
func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, error) {
tree, err := commit.SubTree(treePath)
if err != nil {
return nil, err
Expand All @@ -47,25 +70,48 @@ func getReadmeFileFromPath(commit *git.Commit, treePath string) (*git.Blob, erro
if err != nil {
return nil, err
}
entries.CustomSort(base.NaturalSortLess)

var readmeFiles [4]*git.Blob
var readmeFiles [4]*namedBlob
var exts = []string{".md", ".txt", ""} // sorted by priority
for _, entry := range entries {
if entry.IsDir() {
zeripath marked this conversation as resolved.
Show resolved Hide resolved
continue
}
for i, ext := range exts {
if markup.IsReadmeFile(entry.Name(), ext) {
readmeFiles[i] = entry.Blob()
if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) {
name := entry.Name()
entry, err := followLinks(entry)
if err != nil {
return nil, err
}
if entry != nil {
readmeFiles[i] = &namedBlob{
name,
entry.Blob(),
}
}
}
}
}

if markup.IsReadmeFile(entry.Name()) {
readmeFiles[3] = entry.Blob()
if readmeFiles[3] == nil || base.NaturalSortLess(readmeFiles[3].name, entry.Blob().Name()) {
name := entry.Name()
entry, err := followLinks(entry)
zeripath marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
if entry != nil {
readmeFiles[3] = &namedBlob{
name,
entry.Blob(),
}
}
}
}
}
var readmeFile *git.Blob
var readmeFile *namedBlob
for _, f := range readmeFiles {
if f != nil {
readmeFile = f
Expand Down Expand Up @@ -104,7 +150,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
// 3 for the extensions in exts[] in order
// the last one is for a readme that doesn't
// strictly match an extension
var readmeFiles [4]*git.Blob
var readmeFiles [4]*namedBlob
var docsEntries [3]*git.TreeEntry
zeripath marked this conversation as resolved.
Show resolved Hide resolved
var exts = []string{".md", ".txt", ""} // sorted by priority
for _, entry := range entries {
Expand All @@ -129,16 +175,38 @@ func renderDirectory(ctx *context.Context, treeLink string) {

zeripath marked this conversation as resolved.
Show resolved Hide resolved
for i, ext := range exts {
if markup.IsReadmeFile(entry.Name(), ext) {
readmeFiles[i] = entry.Blob()
name := entry.Name()
entry, err := followLinks(entry)
if err != nil {
ctx.ServerError("FollowLinks", err)
return
}
if entry != nil {
readmeFiles[i] = &namedBlob{
name,
entry.Blob(),
}
}
}
}

if markup.IsReadmeFile(entry.Name()) {
readmeFiles[3] = entry.Blob()
name := entry.Name()
entry, err := followLinks(entry)
if err != nil {
ctx.ServerError("FollowLinks", err)
return
}
if entry != nil {
readmeFiles[3] = &namedBlob{
name,
entry.Blob(),
}
}
}
}

var readmeFile *git.Blob
var readmeFile *namedBlob
readmeTreelink := treeLink
for _, f := range readmeFiles {
if f != nil {
Expand All @@ -158,6 +226,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
return
}
if readmeFile != nil {
readmeFile.name = entry.Name() + "/" + readmeFile.name
readmeTreelink = treeLink + "/" + entry.GetSubJumpablePathName()
break
}
Expand All @@ -169,7 +238,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
ctx.Data["ReadmeInList"] = true
ctx.Data["ReadmeExist"] = true

dataRc, err := readmeFile.DataAsync()
dataRc, err := readmeFile.blob.DataAsync()
if err != nil {
ctx.ServerError("Data", err)
return
Expand All @@ -182,7 +251,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {

isTextFile := base.IsTextFile(buf)
ctx.Data["FileIsText"] = isTextFile
ctx.Data["FileName"] = readmeFile.Name()
ctx.Data["FileName"] = readmeFile.name
fileSize := int64(0)
isLFSFile := false
ctx.Data["IsLFSFile"] = false
Expand Down Expand Up @@ -224,13 +293,13 @@ func renderDirectory(ctx *context.Context, treeLink string) {

fileSize = meta.Size
ctx.Data["FileSize"] = meta.Size
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.Name()))
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64)
}
}

if !isLFSFile {
fileSize = readmeFile.Size()
fileSize = readmeFile.blob.Size()
}

if isTextFile {
Expand All @@ -243,10 +312,10 @@ func renderDirectory(ctx *context.Context, treeLink string) {
d, _ := ioutil.ReadAll(dataRc)
buf = charset.ToUTF8WithFallback(append(buf, d...))

if markupType := markup.Type(readmeFile.Name()); markupType != "" {
if markupType := markup.Type(readmeFile.name); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = string(markupType)
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, readmeTreelink, ctx.Repo.Repository.ComposeMetas()))
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeMetas()))
} else {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = strings.Replace(
Expand Down