44package repo
55
66import (
7+ "errors"
78 "fmt"
89 "html/template"
910 "net/http"
@@ -86,29 +87,31 @@ func prepareOpenWithEditorApps(ctx *context.Context) {
8687 ctx .Data ["OpenWithEditorApps" ] = tmplApps
8788}
8889
89- func prepareHomeSidebarCitationFile (ctx * context.Context , entry * git.TreeEntry ) {
90- if entry .Name () != "" {
91- return
92- }
93- tree , err := ctx .Repo .Commit .SubTree (ctx .Repo .TreePath )
94- if err != nil {
95- HandleGitError (ctx , "Repo.Commit.SubTree" , err )
96- return
97- }
98- allEntries , err := tree .ListEntries ()
99- if err != nil {
100- ctx .ServerError ("ListEntries" , err )
101- return
102- }
103- for _ , entry := range allEntries {
104- if entry .Name () == "CITATION.cff" || entry .Name () == "CITATION.bib" {
105- // Read Citation file contents
106- if content , err := entry .Blob ().GetBlobContent (setting .UI .MaxDisplayFileSize ); err != nil {
107- log .Error ("checkCitationFile: GetBlobContent: %v" , err )
108- } else {
109- ctx .Data ["CitiationExist" ] = true
110- ctx .PageData ["citationFileContent" ] = content
111- break
90+ func prepareHomeSidebarCitationFile (entry * git.TreeEntry ) func (ctx * context.Context ) {
91+ return func (ctx * context.Context ) {
92+ if entry .Name () != "" {
93+ return
94+ }
95+ tree , err := ctx .Repo .Commit .SubTree (ctx .Repo .TreePath )
96+ if err != nil {
97+ HandleGitError (ctx , "Repo.Commit.SubTree" , err )
98+ return
99+ }
100+ allEntries , err := tree .ListEntries ()
101+ if err != nil {
102+ ctx .ServerError ("ListEntries" , err )
103+ return
104+ }
105+ for _ , entry := range allEntries {
106+ if entry .Name () == "CITATION.cff" || entry .Name () == "CITATION.bib" {
107+ // Read Citation file contents
108+ if content , err := entry .Blob ().GetBlobContent (setting .UI .MaxDisplayFileSize ); err != nil {
109+ log .Error ("checkCitationFile: GetBlobContent: %v" , err )
110+ } else {
111+ ctx .Data ["CitiationExist" ] = true
112+ ctx .PageData ["citationFileContent" ] = content
113+ break
114+ }
112115 }
113116 }
114117 }
@@ -174,83 +177,21 @@ func prepareHomeSidebarLatestRelease(ctx *context.Context) {
174177 }
175178}
176179
177- func renderHomeCode (ctx * context.Context ) {
178- ctx .Data ["PageIsViewCode" ] = true
179- ctx .Data ["RepositoryUploadEnabled" ] = setting .Repository .Upload .Enabled
180- prepareOpenWithEditorApps (ctx )
181-
182- if ctx .Repo .Commit == nil || ctx .Repo .Repository .IsEmpty || ctx .Repo .Repository .IsBroken () {
183- showEmpty := true
184- var err error
185- if ctx .Repo .GitRepo != nil {
186- showEmpty , err = ctx .Repo .GitRepo .IsEmpty ()
187- if err != nil {
188- log .Error ("GitRepo.IsEmpty: %v" , err )
189- ctx .Repo .Repository .Status = repo_model .RepositoryBroken
190- showEmpty = true
191- ctx .Flash .Error (ctx .Tr ("error.occurred" ), true )
192- }
193- }
194- if showEmpty {
195- ctx .HTML (http .StatusOK , tplRepoEMPTY )
196- return
197- }
198-
199- // the repo is not really empty, so we should update the modal in database
200- // such problem may be caused by:
201- // 1) an error occurs during pushing/receiving. 2) the user replaces an empty git repo manually
202- // and even more: the IsEmpty flag is deeply broken and should be removed with the UI changed to manage to cope with empty repos.
203- // it's possible for a repository to be non-empty by that flag but still 500
204- // because there are no branches - only tags -or the default branch is non-extant as it has been 0-pushed.
205- ctx .Repo .Repository .IsEmpty = false
206- if err = repo_model .UpdateRepositoryCols (ctx , ctx .Repo .Repository , "is_empty" ); err != nil {
207- ctx .ServerError ("UpdateRepositoryCols" , err )
208- return
209- }
210- if err = repo_module .UpdateRepoSize (ctx , ctx .Repo .Repository ); err != nil {
211- ctx .ServerError ("UpdateRepoSize" , err )
212- return
213- }
214-
215- // the repo's IsEmpty has been updated, redirect to this page to make sure middlewares can get the correct values
216- link := ctx .Link
217- if ctx .Req .URL .RawQuery != "" {
218- link += "?" + ctx .Req .URL .RawQuery
219- }
220- ctx .Redirect (link )
221- return
222- }
223-
224- title := ctx .Repo .Repository .Owner .Name + "/" + ctx .Repo .Repository .Name
225- if len (ctx .Repo .Repository .Description ) > 0 {
226- title += ": " + ctx .Repo .Repository .Description
227- }
228- ctx .Data ["Title" ] = title
229-
230- // Get Topics of this repo
231- prepareHomeSidebarRepoTopics (ctx )
232- if ctx .Written () {
180+ func prepareUpstreamDivergingInfo (ctx * context.Context ) {
181+ if ! ctx .Repo .Repository .IsFork || ! ctx .Repo .IsViewBranch || ctx .Repo .TreePath != "" {
233182 return
234183 }
235-
236- // Get current entry user currently looking at.
237- entry , err := ctx .Repo .Commit .GetTreeEntryByPath (ctx .Repo .TreePath )
184+ upstreamDivergingInfo , err := repo_service .GetUpstreamDivergingInfo (ctx , ctx .Repo .Repository , ctx .Repo .BranchName )
238185 if err != nil {
239- HandleGitError (ctx , "Repo.Commit.GetTreeEntryByPath" , err )
240- return
241- }
242-
243- checkOutdatedBranch (ctx )
244-
245- if entry .IsDir () {
246- prepareToRenderDirectory (ctx )
247- } else {
248- renderFile (ctx , entry )
249- }
250- if ctx .Written () {
186+ if ! errors .Is (err , util .ErrNotExist ) && ! errors .Is (err , util .ErrInvalidArgument ) {
187+ log .Error ("GetUpstreamDivergingInfo: %v" , err )
188+ }
251189 return
252190 }
191+ ctx .Data ["UpstreamDivergingInfo" ] = upstreamDivergingInfo
192+ }
253193
194+ func prepareRecentlyPushedNewBranches (ctx * context.Context ) {
254195 if ctx .Doer != nil {
255196 if err := ctx .Repo .Repository .GetBaseRepo (ctx ); err != nil {
256197 ctx .ServerError ("GetBaseRepo" , err )
@@ -280,53 +221,60 @@ func renderHomeCode(ctx *context.Context) {
280221 }
281222 }
282223 }
224+ }
283225
284- var treeNames , paths []string
285- branchLink := ctx .Repo .RepoLink + "/src/" + ctx .Repo .BranchNameSubURL ()
286- treeLink := branchLink
287- if ctx .Repo .TreePath != "" {
288- treeLink += "/" + util .PathEscapeSegments (ctx .Repo .TreePath )
289- treeNames = strings .Split (ctx .Repo .TreePath , "/" )
290- for i := range treeNames {
291- paths = append (paths , strings .Join (treeNames [:i + 1 ], "/" ))
292- }
293- ctx .Data ["HasParentPath" ] = true
294- if len (paths )- 2 >= 0 {
295- ctx .Data ["ParentPath" ] = "/" + paths [len (paths )- 2 ]
226+ func handleRepoEmptyOrBroken (ctx * context.Context ) {
227+ showEmpty := true
228+ var err error
229+ if ctx .Repo .GitRepo != nil {
230+ showEmpty , err = ctx .Repo .GitRepo .IsEmpty ()
231+ if err != nil {
232+ log .Error ("GitRepo.IsEmpty: %v" , err )
233+ ctx .Repo .Repository .Status = repo_model .RepositoryBroken
234+ showEmpty = true
235+ ctx .Flash .Error (ctx .Tr ("error.occurred" ), true )
296236 }
297237 }
238+ if showEmpty {
239+ ctx .HTML (http .StatusOK , tplRepoEMPTY )
240+ return
241+ }
298242
299- isTreePathRoot := ctx .Repo .TreePath == ""
300- if isTreePathRoot {
301- prepareHomeSidebarLicenses (ctx )
302- if ctx .Written () {
303- return
304- }
305- prepareHomeSidebarCitationFile (ctx , entry )
306- if ctx .Written () {
307- return
308- }
243+ // the repo is not really empty, so we should update the modal in database
244+ // such problem may be caused by:
245+ // 1) an error occurs during pushing/receiving. 2) the user replaces an empty git repo manually
246+ // and even more: the IsEmpty flag is deeply broken and should be removed with the UI changed to manage to cope with empty repos.
247+ // it's possible for a repository to be non-empty by that flag but still 500
248+ // because there are no branches - only tags -or the default branch is non-extant as it has been 0-pushed.
249+ ctx .Repo .Repository .IsEmpty = false
250+ if err = repo_model .UpdateRepositoryCols (ctx , ctx .Repo .Repository , "is_empty" ); err != nil {
251+ ctx .ServerError ("UpdateRepositoryCols" , err )
252+ return
253+ }
254+ if err = repo_module .UpdateRepoSize (ctx , ctx .Repo .Repository ); err != nil {
255+ ctx .ServerError ("UpdateRepoSize" , err )
256+ return
257+ }
309258
310- prepareHomeSidebarLanguageStats (ctx )
311- if ctx .Written () {
312- return
313- }
259+ // the repo's IsEmpty has been updated, redirect to this page to make sure middlewares can get the correct values
260+ link := ctx .Link
261+ if ctx .Req .URL .RawQuery != "" {
262+ link += "?" + ctx .Req .URL .RawQuery
263+ }
264+ ctx .Redirect (link )
265+ }
314266
315- prepareHomeSidebarLatestRelease (ctx )
316- if ctx .Written () {
317- return
267+ func prepareToRenderDirOrFile (entry * git.TreeEntry ) func (ctx * context.Context ) {
268+ return func (ctx * context.Context ) {
269+ if entry .IsDir () {
270+ prepareToRenderDirectory (ctx )
271+ } else {
272+ prepareToRenderFile (ctx , entry )
318273 }
319274 }
320-
321- ctx .Data ["Paths" ] = paths
322- ctx .Data ["TreeLink" ] = treeLink
323- ctx .Data ["TreeNames" ] = treeNames
324- ctx .Data ["BranchLink" ] = branchLink
325- ctx .HTML (http .StatusOK , tplRepoHome )
326275}
327276
328- // Home render repository home page
329- func Home (ctx * context.Context ) {
277+ func handleRepoHomeFeed (ctx * context.Context ) bool {
330278 if setting .Other .EnableFeed {
331279 isFeed , _ , showFeedType := feed .GetFeedType (ctx .PathParam (":reponame" ), ctx .Req )
332280 if isFeed {
@@ -338,14 +286,93 @@ func Home(ctx *context.Context) {
338286 case ctx .Repo .TreePath != "" :
339287 feed .ShowFileFeed (ctx , ctx .Repo .Repository , showFeedType )
340288 }
341- return
289+ return true
342290 }
343291 }
292+ return false
293+ }
294+
295+ // Home render repository home page
296+ func Home (ctx * context.Context ) {
297+ if handleRepoHomeFeed (ctx ) {
298+ return
299+ }
344300
301+ // Check whether the repo is viewable: not in migration, and the code unit should be enabled
302+ // Ideally the "feed" logic should be after this, but old code did so, so keep it as-is.
345303 checkHomeCodeViewable (ctx )
346304 if ctx .Written () {
347305 return
348306 }
349307
350- renderHomeCode (ctx )
308+ title := ctx .Repo .Repository .Owner .Name + "/" + ctx .Repo .Repository .Name
309+ if len (ctx .Repo .Repository .Description ) > 0 {
310+ title += ": " + ctx .Repo .Repository .Description
311+ }
312+ ctx .Data ["Title" ] = title
313+ ctx .Data ["PageIsViewCode" ] = true
314+ ctx .Data ["RepositoryUploadEnabled" ] = setting .Repository .Upload .Enabled // show New File / Upload File buttons
315+
316+ if ctx .Repo .Commit == nil || ctx .Repo .Repository .IsEmpty || ctx .Repo .Repository .IsBroken () {
317+ // empty or broken repositories need to be handled differently
318+ handleRepoEmptyOrBroken (ctx )
319+ return
320+ }
321+
322+ // get the current git entry which doer user is currently looking at.
323+ entry , err := ctx .Repo .Commit .GetTreeEntryByPath (ctx .Repo .TreePath )
324+ if err != nil {
325+ HandleGitError (ctx , "Repo.Commit.GetTreeEntryByPath" , err )
326+ return
327+ }
328+
329+ // prepare the tree path
330+ var treeNames , paths []string
331+ branchLink := ctx .Repo .RepoLink + "/src/" + ctx .Repo .BranchNameSubURL ()
332+ treeLink := branchLink
333+ if ctx .Repo .TreePath != "" {
334+ treeLink += "/" + util .PathEscapeSegments (ctx .Repo .TreePath )
335+ treeNames = strings .Split (ctx .Repo .TreePath , "/" )
336+ for i := range treeNames {
337+ paths = append (paths , strings .Join (treeNames [:i + 1 ], "/" ))
338+ }
339+ ctx .Data ["HasParentPath" ] = true
340+ if len (paths )- 2 >= 0 {
341+ ctx .Data ["ParentPath" ] = "/" + paths [len (paths )- 2 ]
342+ }
343+ }
344+ ctx .Data ["Paths" ] = paths
345+ ctx .Data ["TreeLink" ] = treeLink
346+ ctx .Data ["TreeNames" ] = treeNames
347+ ctx .Data ["BranchLink" ] = branchLink
348+
349+ // some UI components are only shown when the tree path is root
350+ isTreePathRoot := ctx .Repo .TreePath == ""
351+
352+ prepareFuncs := []func (* context.Context ){
353+ prepareOpenWithEditorApps ,
354+ prepareHomeSidebarRepoTopics ,
355+ checkOutdatedBranch ,
356+ prepareToRenderDirOrFile (entry ),
357+ prepareRecentlyPushedNewBranches ,
358+ }
359+
360+ if isTreePathRoot {
361+ prepareFuncs = append (prepareFuncs ,
362+ prepareUpstreamDivergingInfo ,
363+ prepareHomeSidebarLicenses ,
364+ prepareHomeSidebarCitationFile (entry ),
365+ prepareHomeSidebarLanguageStats ,
366+ prepareHomeSidebarLatestRelease ,
367+ )
368+ }
369+
370+ for _ , prepare := range prepareFuncs {
371+ prepare (ctx )
372+ if ctx .Written () {
373+ return
374+ }
375+ }
376+
377+ ctx .HTML (http .StatusOK , tplRepoHome )
351378}
0 commit comments