فهرست منبع

Move repo DOI checks to contexter

Check if a repository is registered when building the repository context
instead of just on the front page root dir listing.
This way, the DOI badge is rendered in the header on all pages of a
repository: Non-root directories, file views, issues, pull requests,
wiki pages, etc.
Achilleas Koutsou 5 سال پیش
والد
کامیت
4ae9fb6fc8
3فایلهای تغییر یافته به همراه98 افزوده شده و 94 حذف شده
  1. 87 0
      internal/context/context_gin.go
  2. 8 4
      internal/context/repo.go
  3. 3 90
      internal/route/repo/repo_gin.go

+ 87 - 0
internal/context/context_gin.go

@@ -5,8 +5,11 @@ import (
 	"path"
 	"strings"
 
+	"github.com/G-Node/git-module"
+	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/tool"
+	"github.com/G-Node/libgin/libgin"
 	"github.com/unknwon/com"
 	log "gopkg.in/clog.v1"
 )
@@ -59,3 +62,87 @@ func readNotice(c *Context) {
 	c.Data["NoticeTitle"] = noticetext[0]
 	c.Data["NoticeMessage"] = noticetext[1]
 }
+
+// getRepoDOI returns the DOI for the repository based on the following rules:
+// - if the repository belongs to the DOI user and has a tag that matches the
+// DOI prefix, returns the tag.
+// - if the repo is forked by the DOI user, check the DOI fork for the tag as above.
+// - if the repo is forked by the DOI user and the fork doesn't have a tag,
+// returns the (old-style) calculated DOI, based on the hash of the repository
+// path.
+// - An empty string is returned if it is not not forked by the DOI user.
+// If an error occurs at any point, returns an empty string (the error is logged).
+// Tag retrieval is allowed to fail and falls back on the hashed DOI method.
+func getRepoDOI(c *Context) string {
+	repo := c.Repo.Repository
+	var doiFork *db.Repository
+	if repo.Owner.Name == "doi" {
+		doiFork = repo
+	} else {
+		if forks, err := repo.GetForks(); err == nil {
+			for _, fork := range forks {
+				if fork.MustOwner().Name == "doi" {
+					doiFork = fork
+					break
+				}
+			}
+		} else {
+			log.Error(2, "failed to get forks for repository %q (%d): %v", repo.FullName(), repo.ID, err)
+			return ""
+		}
+	}
+
+	if doiFork == nil {
+		// not owned or forked by DOI, so not registered
+		return ""
+	}
+
+	// check the DOI fork for a tag that matches our DOI prefix
+	// if multiple exit, get the latest one
+	doiBase := setting.DOI.Base
+
+	doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
+	if err != nil {
+		log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
+		return ""
+	}
+	if tags, err := doiForkGit.GetTags(); err == nil {
+		var latestTime int64
+		latestTag := ""
+		for _, tagName := range tags {
+			if strings.Contains(tagName, doiBase) {
+				tag, err := doiForkGit.GetTag(tagName)
+				if err != nil {
+					// log the error and continue to the next tag
+					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					continue
+				}
+				commit, err := tag.Commit()
+				if err != nil {
+					// log the error and continue to the next tag
+					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					continue
+				}
+				commitTime := commit.Committer.When.Unix()
+				if commitTime > latestTime {
+					latestTag = tagName
+					latestTime = commitTime
+				}
+				return latestTag
+			}
+		}
+	} else {
+		// this shouldn't happen even if there are no tags
+		// log the error, but fall back to the old method anyway
+		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
+	}
+
+	// Has DOI fork but isn't tagged: return old style has-based DOI
+	repoPath := repo.FullName()
+	// get base repo name if it's a DOI fork
+	if c.Repo.Repository.IsFork && c.Repo.Owner.Name == "doi" {
+		repoPath = c.Repo.Repository.BaseRepo.FullName()
+	}
+	uuid := libgin.RepoPathToUUID(repoPath)
+	return doiBase + uuid[:6]
+}

+ 8 - 4
internal/context/repo.go

@@ -6,17 +6,16 @@ package context
 
 import (
 	"fmt"
-	"io/ioutil"
-	"strings"
-
 	"gopkg.in/editorconfig/editorconfig-core-go.v1"
 	"gopkg.in/macaron.v1"
+	"io/ioutil"
+	"strings"
 
 	"github.com/G-Node/git-module"
-
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/db/errors"
 	"github.com/G-Node/gogs/internal/setting"
+	"github.com/G-Node/libgin/libgin"
 )
 
 type PullRequest struct {
@@ -270,6 +269,11 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 		c.Data["CommitID"] = c.Repo.CommitID
 
 		c.Data["IsGuest"] = !c.Repo.HasAccess()
+
+		if doi := getRepoDOI(c); doi != "" && libgin.IsRegisteredDOI(doi) {
+			c.Data["DOI"] = doi
+		}
+
 	}
 }
 

+ 3 - 90
internal/route/repo/repo_gin.go

@@ -14,7 +14,6 @@ import (
 
 	"github.com/G-Node/git-module"
 	"github.com/G-Node/gogs/internal/context"
-	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/setting"
 	"github.com/G-Node/gogs/internal/tool"
 	"github.com/G-Node/libgin/libgin"
@@ -94,17 +93,15 @@ func readDataciteFile(entry *git.TreeEntry, c *context.Context) {
 		return
 	}
 	c.Data["DOIInfo"] = &doiInfo
-
-	if doi := getRepoDOI(c); doi != "" && libgin.IsRegisteredDOI(doi) {
-		c.Data["DOI"] = doi
-	}
-
 	c.Data["IsDOIReady"] = isDOIReady(c)
 }
 
 // True if repository is not Private, is not registered, or is registered and
 // has changes.
 func isDOIReady(c *context.Context) bool {
+	if hasDC, ok := c.Data["HasDatacite"]; !ok || !hasDC.(bool) {
+		return false
+	}
 	dbrepo := c.Repo.Repository
 	gitrepo := c.Repo.GitRepo
 
@@ -139,90 +136,6 @@ func isDOIReady(c *context.Context) bool {
 	return !dbrepo.IsPrivate && !headIsRegistered
 }
 
-// getRepoDOI returns the DOI for the repository based on the following rules:
-// - if the repository belongs to the DOI user and has a tag that matches the
-// DOI prefix, returns the tag.
-// - if the repo is forked by the DOI user, check the DOI fork for the tag as above.
-// - if the repo is forked by the DOI user and the fork doesn't have a tag,
-// returns the (old-style) calculated DOI, based on the hash of the repository
-// path.
-// - An empty string is returned if it is not not forked by the DOI user.
-// If an error occurs at any point, returns an empty string (the error is logged).
-// Tag retrieval is allowed to fail and falls back on the hashed DOI method.
-func getRepoDOI(c *context.Context) string {
-	repo := c.Repo.Repository
-	var doiFork *db.Repository
-	if repo.Owner.Name == "doi" {
-		doiFork = repo
-	} else {
-		if forks, err := repo.GetForks(); err == nil {
-			for _, fork := range forks {
-				if fork.MustOwner().Name == "doi" {
-					doiFork = fork
-					break
-				}
-			}
-		} else {
-			log.Error(2, "failed to get forks for repository %q (%d): %v", repo.FullName(), repo.ID, err)
-			return ""
-		}
-	}
-
-	if doiFork == nil {
-		// not owned or forked by DOI, so not registered
-		return ""
-	}
-
-	// check the DOI fork for a tag that matches our DOI prefix
-	// if multiple exit, get the latest one
-	doiBase := setting.DOI.Base
-
-	doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
-	if err != nil {
-		log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
-		return ""
-	}
-	if tags, err := doiForkGit.GetTags(); err == nil {
-		var latestTime int64
-		latestTag := ""
-		for _, tagName := range tags {
-			if strings.Contains(tagName, doiBase) {
-				tag, err := doiForkGit.GetTag(tagName)
-				if err != nil {
-					// log the error and continue to the next tag
-					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
-					continue
-				}
-				commit, err := tag.Commit()
-				if err != nil {
-					// log the error and continue to the next tag
-					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
-					continue
-				}
-				commitTime := commit.Committer.When.Unix()
-				if commitTime > latestTime {
-					latestTag = tagName
-					latestTime = commitTime
-				}
-				return latestTag
-			}
-		}
-	} else {
-		// this shouldn't happen even if there are no tags
-		// log the error, but fall back to the old method anyway
-		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
-	}
-
-	// Has DOI fork but isn't tagged: return old style has-based DOI
-	repoPath := repo.FullName()
-	// get base repo name if it's a DOI fork
-	if c.Repo.Repository.IsFork && c.Repo.Owner.Name == "doi" {
-		repoPath = c.Repo.Repository.BaseRepo.FullName()
-	}
-	uuid := libgin.RepoPathToUUID(repoPath)
-	return doiBase + uuid[:6]
-}
-
 // resolveAnnexedContent takes a buffer with the contents of a git-annex
 // pointer file and an io.Reader for the underlying file and returns the
 // corresponding buffer and a bufio.Reader for the underlying content file.