context_gin.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package context
  2. import (
  3. "strings"
  4. "github.com/G-Node/git-module"
  5. "github.com/G-Node/gogs/internal/db"
  6. "github.com/G-Node/gogs/internal/setting"
  7. "github.com/G-Node/libgin/libgin"
  8. log "gopkg.in/clog.v1"
  9. )
  10. // getRepoDOI returns the DOI for the repository based on the following rules:
  11. // - if the repository belongs to the DOI user and has a tag that matches the
  12. // DOI prefix, returns the tag.
  13. // - if the repo is forked by the DOI user, check the DOI fork for the tag as above.
  14. // - if the repo is forked by the DOI user and the fork doesn't have a tag,
  15. // returns the (old-style) calculated DOI, based on the hash of the repository
  16. // path.
  17. // - An empty string is returned if it is not not forked by the DOI user.
  18. // If an error occurs at any point, returns an empty string (the error is logged).
  19. // Tag retrieval is allowed to fail and falls back on the hashed DOI method.
  20. func getRepoDOI(c *Context) string {
  21. repo := c.Repo.Repository
  22. var doiFork *db.Repository
  23. if repo.Owner.Name == "doi" {
  24. doiFork = repo
  25. } else {
  26. if forks, err := repo.GetForks(); err == nil {
  27. for _, fork := range forks {
  28. if fork.MustOwner().Name == "doi" {
  29. doiFork = fork
  30. break
  31. }
  32. }
  33. } else {
  34. log.Error(2, "failed to get forks for repository %q (%d): %v", repo.FullName(), repo.ID, err)
  35. return ""
  36. }
  37. }
  38. if doiFork == nil {
  39. // not owned or forked by DOI, so not registered
  40. return ""
  41. }
  42. // check the DOI fork for a tag that matches our DOI prefix
  43. // if multiple exit, get the latest one
  44. doiBase := setting.DOI.Base
  45. doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
  46. if err != nil {
  47. log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
  48. return ""
  49. }
  50. if tags, err := doiForkGit.GetTags(); err == nil {
  51. var latestTime int64
  52. latestTag := ""
  53. for _, tagName := range tags {
  54. if strings.Contains(tagName, doiBase) {
  55. tag, err := doiForkGit.GetTag(tagName)
  56. if err != nil {
  57. // log the error and continue to the next tag
  58. log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
  59. continue
  60. }
  61. commit, err := tag.Commit()
  62. if err != nil {
  63. // log the error and continue to the next tag
  64. log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
  65. continue
  66. }
  67. commitTime := commit.Committer.When.Unix()
  68. if commitTime > latestTime {
  69. latestTag = tagName
  70. latestTime = commitTime
  71. }
  72. return latestTag
  73. }
  74. }
  75. } else {
  76. // this shouldn't happen even if there are no tags
  77. // log the error, but fall back to the old method anyway
  78. log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
  79. }
  80. // Has DOI fork but isn't tagged: return old style has-based DOI
  81. repoPath := repo.FullName()
  82. // get base repo name if it's a DOI fork
  83. if c.Repo.Repository.IsFork && c.Repo.Owner.Name == "doi" {
  84. repoPath = c.Repo.Repository.BaseRepo.FullName()
  85. }
  86. uuid := libgin.RepoPathToUUID(repoPath)
  87. return doiBase + uuid[:6]
  88. }
  89. // hasDataCite returns 'true' if a repository includes a file called
  90. // 'datacite.yml' in its root. No checks are made to determine if the file is
  91. // valid. If any error occurs, for example due to an uninitialised repository
  92. // or missing repository root, it returns 'false' without error.
  93. func hasDataCite(c *Context) bool {
  94. commit, err := c.Repo.GitRepo.GetBranchCommit(c.Repo.Repository.DefaultBranch)
  95. if err != nil {
  96. return false
  97. }
  98. _, err = commit.GetBlobByPath("./datacite.yml")
  99. return err == nil
  100. }