@@ -36,6 +36,83 @@ const (
36
36
tplMigrating base.TplName = "repo/migrating"
37
37
)
38
38
39
+ type namedBlob struct {
40
+ name string
41
+ isSymlink bool
42
+ blob * git.Blob
43
+ }
44
+
45
+ // FIXME: There has to be a more efficient way of doing this
46
+ func getReadmeFileFromPath (commit * git.Commit , treePath string ) (* namedBlob , error ) {
47
+ tree , err := commit .SubTree (treePath )
48
+ if err != nil {
49
+ return nil , err
50
+ }
51
+
52
+ entries , err := tree .ListEntries ()
53
+ if err != nil {
54
+ return nil , err
55
+ }
56
+
57
+ var readmeFiles [4 ]* namedBlob
58
+ var exts = []string {".md" , ".txt" , "" } // sorted by priority
59
+ for _ , entry := range entries {
60
+ if entry .IsDir () {
61
+ continue
62
+ }
63
+ for i , ext := range exts {
64
+ if markup .IsReadmeFile (entry .Name (), ext ) {
65
+ if readmeFiles [i ] == nil || base .NaturalSortLess (readmeFiles [i ].name , entry .Blob ().Name ()) {
66
+ name := entry .Name ()
67
+ isSymlink := entry .IsLink ()
68
+ target := entry
69
+ if isSymlink {
70
+ target , err = entry .FollowLinks ()
71
+ if err != nil && ! git .IsErrBadLink (err ) {
72
+ return nil , err
73
+ }
74
+ }
75
+ if target != nil && (target .IsExecutable () || target .IsRegular ()) {
76
+ readmeFiles [i ] = & namedBlob {
77
+ name ,
78
+ isSymlink ,
79
+ target .Blob (),
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ if markup .IsReadmeFile (entry .Name ()) {
87
+ if readmeFiles [3 ] == nil || base .NaturalSortLess (readmeFiles [3 ].name , entry .Blob ().Name ()) {
88
+ name := entry .Name ()
89
+ isSymlink := entry .IsLink ()
90
+ if isSymlink {
91
+ entry , err = entry .FollowLinks ()
92
+ if err != nil && ! git .IsErrBadLink (err ) {
93
+ return nil , err
94
+ }
95
+ }
96
+ if entry != nil && (entry .IsExecutable () || entry .IsRegular ()) {
97
+ readmeFiles [3 ] = & namedBlob {
98
+ name ,
99
+ isSymlink ,
100
+ entry .Blob (),
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ var readmeFile * namedBlob
107
+ for _ , f := range readmeFiles {
108
+ if f != nil {
109
+ readmeFile = f
110
+ break
111
+ }
112
+ }
113
+ return readmeFile , nil
114
+ }
115
+
39
116
func renderDirectory (ctx * context.Context , treeLink string ) {
40
117
tree , err := ctx .Repo .Commit .SubTree (ctx .Repo .TreePath )
41
118
if err != nil {
@@ -65,38 +142,107 @@ func renderDirectory(ctx *context.Context, treeLink string) {
65
142
// 3 for the extensions in exts[] in order
66
143
// the last one is for a readme that doesn't
67
144
// strictly match an extension
68
- var readmeFiles [4 ]* git.Blob
145
+ var readmeFiles [4 ]* namedBlob
146
+ var docsEntries [3 ]* git.TreeEntry
69
147
var exts = []string {".md" , ".txt" , "" } // sorted by priority
70
148
for _ , entry := range entries {
71
149
if entry .IsDir () {
150
+ lowerName := strings .ToLower (entry .Name ())
151
+ switch lowerName {
152
+ case "docs" :
153
+ if entry .Name () == "docs" || docsEntries [0 ] == nil {
154
+ docsEntries [0 ] = entry
155
+ }
156
+ case ".gitea" :
157
+ if entry .Name () == ".gitea" || docsEntries [1 ] == nil {
158
+ docsEntries [1 ] = entry
159
+ }
160
+ case ".github" :
161
+ if entry .Name () == ".github" || docsEntries [2 ] == nil {
162
+ docsEntries [2 ] = entry
163
+ }
164
+ }
72
165
continue
73
166
}
74
167
75
168
for i , ext := range exts {
76
169
if markup .IsReadmeFile (entry .Name (), ext ) {
77
- readmeFiles [i ] = entry .Blob ()
170
+ log .Debug ("%s" , entry .Name ())
171
+ name := entry .Name ()
172
+ isSymlink := entry .IsLink ()
173
+ target := entry
174
+ if isSymlink {
175
+ target , err = entry .FollowLinks ()
176
+ if err != nil && ! git .IsErrBadLink (err ) {
177
+ ctx .ServerError ("FollowLinks" , err )
178
+ return
179
+ }
180
+ }
181
+ log .Debug ("%t" , target == nil )
182
+ if target != nil && (target .IsExecutable () || target .IsRegular ()) {
183
+ readmeFiles [i ] = & namedBlob {
184
+ name ,
185
+ isSymlink ,
186
+ target .Blob (),
187
+ }
188
+ }
78
189
}
79
190
}
80
191
81
192
if markup .IsReadmeFile (entry .Name ()) {
82
- readmeFiles [3 ] = entry .Blob ()
193
+ name := entry .Name ()
194
+ isSymlink := entry .IsLink ()
195
+ if isSymlink {
196
+ entry , err = entry .FollowLinks ()
197
+ if err != nil && ! git .IsErrBadLink (err ) {
198
+ ctx .ServerError ("FollowLinks" , err )
199
+ return
200
+ }
201
+ }
202
+ if entry != nil && (entry .IsExecutable () || entry .IsRegular ()) {
203
+ readmeFiles [3 ] = & namedBlob {
204
+ name ,
205
+ isSymlink ,
206
+ entry .Blob (),
207
+ }
208
+ }
83
209
}
84
210
}
85
211
86
- var readmeFile * git.Blob
212
+ var readmeFile * namedBlob
213
+ readmeTreelink := treeLink
87
214
for _ , f := range readmeFiles {
88
215
if f != nil {
89
216
readmeFile = f
90
217
break
91
218
}
92
219
}
93
220
221
+ if ctx .Repo .TreePath == "" && readmeFile == nil {
222
+ for _ , entry := range docsEntries {
223
+ if entry == nil {
224
+ continue
225
+ }
226
+ readmeFile , err = getReadmeFileFromPath (ctx .Repo .Commit , entry .GetSubJumpablePathName ())
227
+ if err != nil {
228
+ ctx .ServerError ("getReadmeFileFromPath" , err )
229
+ return
230
+ }
231
+ if readmeFile != nil {
232
+ readmeFile .name = entry .Name () + "/" + readmeFile .name
233
+ readmeTreelink = treeLink + "/" + entry .GetSubJumpablePathName ()
234
+ break
235
+ }
236
+ }
237
+ }
238
+
94
239
if readmeFile != nil {
95
240
ctx .Data ["RawFileLink" ] = ""
96
241
ctx .Data ["ReadmeInList" ] = true
97
242
ctx .Data ["ReadmeExist" ] = true
243
+ ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
98
244
99
- dataRc , err := readmeFile .DataAsync ()
245
+ dataRc , err := readmeFile .blob . DataAsync ()
100
246
if err != nil {
101
247
ctx .ServerError ("Data" , err )
102
248
return
@@ -109,7 +255,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
109
255
110
256
isTextFile := base .IsTextFile (buf )
111
257
ctx .Data ["FileIsText" ] = isTextFile
112
- ctx .Data ["FileName" ] = readmeFile .Name ()
258
+ ctx .Data ["FileName" ] = readmeFile .name
113
259
fileSize := int64 (0 )
114
260
isLFSFile := false
115
261
ctx .Data ["IsLFSFile" ] = false
@@ -151,13 +297,13 @@ func renderDirectory(ctx *context.Context, treeLink string) {
151
297
152
298
fileSize = meta .Size
153
299
ctx .Data ["FileSize" ] = meta .Size
154
- filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .Name () ))
300
+ filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
155
301
ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s%s.git/info/lfs/objects/%s/%s" , setting .AppURL , ctx .Repo .Repository .FullName (), meta .Oid , filenameBase64 )
156
302
}
157
303
}
158
304
159
305
if ! isLFSFile {
160
- fileSize = readmeFile .Size ()
306
+ fileSize = readmeFile .blob . Size ()
161
307
}
162
308
163
309
if isTextFile {
@@ -170,10 +316,10 @@ func renderDirectory(ctx *context.Context, treeLink string) {
170
316
d , _ := ioutil .ReadAll (dataRc )
171
317
buf = charset .ToUTF8WithFallback (append (buf , d ... ))
172
318
173
- if markupType := markup .Type (readmeFile .Name () ); markupType != "" {
319
+ if markupType := markup .Type (readmeFile .name ); markupType != "" {
174
320
ctx .Data ["IsMarkup" ] = true
175
321
ctx .Data ["MarkupType" ] = string (markupType )
176
- ctx .Data ["FileContent" ] = string (markup .Render (readmeFile .Name () , buf , treeLink , ctx .Repo .Repository .ComposeMetas ()))
322
+ ctx .Data ["FileContent" ] = string (markup .Render (readmeFile .name , buf , readmeTreelink , ctx .Repo .Repository .ComposeMetas ()))
177
323
} else {
178
324
ctx .Data ["IsRenderedHTML" ] = true
179
325
ctx .Data ["FileContent" ] = strings .Replace (
@@ -218,6 +364,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
218
364
ctx .Data ["Title" ] = ctx .Data ["Title" ].(string ) + " - " + ctx .Repo .TreePath + " at " + ctx .Repo .BranchName
219
365
220
366
fileSize := blob .Size ()
367
+ ctx .Data ["FileIsSymlink" ] = entry .IsLink ()
221
368
ctx .Data ["FileSize" ] = fileSize
222
369
ctx .Data ["FileName" ] = blob .Name ()
223
370
ctx .Data ["HighlightClass" ] = highlight .FileNameToHighlightClass (blob .Name ())
0 commit comments