git_data.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright 2025 BackendServerTemplate Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package git
  5. import (
  6. "fmt"
  7. "github.com/SongZihuan/BackendServerTemplate/tool/generate/basefile"
  8. "github.com/SongZihuan/BackendServerTemplate/tool/generate/mod"
  9. "github.com/SongZihuan/BackendServerTemplate/tool/global"
  10. "github.com/SongZihuan/BackendServerTemplate/tool/utils/fileutils"
  11. "github.com/SongZihuan/BackendServerTemplate/tool/utils/gitutils"
  12. "log"
  13. "os"
  14. "strings"
  15. "sync"
  16. )
  17. var onceGitInfo sync.Once
  18. var lastCommit string = ""
  19. var lastTag string = ""
  20. var lastTagCommit string = ""
  21. var secondToLastTag string = ""
  22. var secondToLastTagCommit string = ""
  23. var firstCommit string = ""
  24. var onceIsGithub sync.Once
  25. var isGithub bool = false
  26. func InitGitData() (err error) {
  27. onceGitInfo.Do(func() {
  28. err = initGitData()
  29. })
  30. return err
  31. }
  32. func initGitData() (err error) {
  33. if !gitutils.HasGit() {
  34. log.Println("generate: `.git` not found, get git info skip")
  35. return nil
  36. }
  37. log.Println("generate: get git info")
  38. defer log.Println("generate: get git info finish")
  39. defer func() {
  40. if err != nil {
  41. lastCommit = ""
  42. lastTag = ""
  43. lastTagCommit = ""
  44. secondToLastTag = ""
  45. secondToLastTagCommit = ""
  46. firstCommit = ""
  47. }
  48. }()
  49. lastCommit, err = gitutils.GetLastCommit()
  50. if err != nil {
  51. return err
  52. }
  53. log.Printf("generate: get git last commit: %s\n", lastCommit)
  54. firstCommit, err = gitutils.GetFirstCommit()
  55. if err != nil {
  56. return err
  57. }
  58. log.Printf("generate: get git first commit: %s\n", firstCommit)
  59. tagList, err := gitutils.GetTagListWithFilter(func(s string) bool {
  60. return strings.HasPrefix(s, "v")
  61. })
  62. if err != nil {
  63. return err
  64. }
  65. log.Printf("generate: get git tag list length: %d\n", len(tagList))
  66. if len(tagList) > 0 {
  67. lastTag = tagList[0]
  68. log.Printf("generate: get git last tag: %s\n", lastTag)
  69. lastTagCommit, err = gitutils.GetTagCommit(lastTag)
  70. if err != nil {
  71. return err
  72. }
  73. log.Printf("generate: get git last tag commist: %s\n", lastTagCommit)
  74. } else {
  75. lastTag = ""
  76. lastTagCommit = ""
  77. log.Println("generate: skip to get git last tag and last tag commit")
  78. }
  79. if len(tagList) > 1 {
  80. secondToLastTag = tagList[1]
  81. log.Printf("generate: get git second to last tag: %s\n", secondToLastTag)
  82. secondToLastTagCommit, err = gitutils.GetTagCommit(secondToLastTag)
  83. if err != nil {
  84. return err
  85. }
  86. log.Printf("generate: get git second to last tag commit: %s\n", secondToLastTagCommit)
  87. } else {
  88. secondToLastTag = ""
  89. secondToLastTagCommit = ""
  90. log.Println("generate: skip to get git second to last tag and second to last tag commit")
  91. }
  92. return nil
  93. }
  94. func Version() string {
  95. _ = InitGitData()
  96. return lastTag
  97. }
  98. func WriteGitData() (err error) {
  99. log.Println("generate: write git data")
  100. defer log.Println("generate: write git data finish")
  101. _ = InitGitData()
  102. log.Printf("generate: write %s to file %s\n", lastCommit, basefile.FileCommitDateTxt)
  103. err = fileutils.Write(basefile.FileCommitDateTxt, lastCommit)
  104. if err != nil {
  105. return err
  106. }
  107. log.Printf("generate: write %s to file %s\n", lastTag, basefile.FileTagDataTxt)
  108. err = fileutils.Write(basefile.FileTagDataTxt, lastTag)
  109. if err != nil {
  110. return err
  111. }
  112. log.Printf("generate: write %s to file %s\n", lastTagCommit, basefile.FileTagCommitData)
  113. err = fileutils.Write(basefile.FileTagCommitData, lastTagCommit)
  114. if err != nil {
  115. return err
  116. }
  117. return nil
  118. }
  119. func GetGitHubCompareMD() string {
  120. _ = InitGitData()
  121. compare, url := GetGitHubCompareURL()
  122. if compare == "" || url == "" {
  123. return ""
  124. }
  125. return fmt.Sprintf("**Git Changelog:** [%s](%s)", compare, url)
  126. }
  127. func GetGitHubCompareURL() (string, string) {
  128. _ = InitGitData()
  129. if !IsGitHub() || lastTag == "" || firstCommit == lastTagCommit {
  130. return "", ""
  131. }
  132. moduleName, err := mod.GetGoModuleName()
  133. if err != nil {
  134. return "", ""
  135. }
  136. if secondToLastTag != "" {
  137. compare := fmt.Sprintf("%s...%s", secondToLastTag, lastTag)
  138. return compare, fmt.Sprintf("https://%s/compare/%s", moduleName, compare)
  139. }
  140. return lastTag, fmt.Sprintf("https://%s/compare/%s...%s", moduleName, firstCommit, lastTag)
  141. }
  142. func IsGitHub() bool {
  143. onceIsGithub.Do(func() {
  144. moduleName, err := mod.GetGoModuleName()
  145. if err != nil {
  146. log.Println("generate: the module is not on github, because module name not found")
  147. isGithub = false
  148. return
  149. }
  150. if strings.HasPrefix(moduleName, "github.com/") {
  151. log.Println("generate: the module is on github")
  152. isGithub = true
  153. } else {
  154. log.Println("generate: the module is not on github")
  155. isGithub = false
  156. }
  157. })
  158. return isGithub
  159. }
  160. func WriteGitIgnore() error {
  161. if !gitutils.HasGit() {
  162. log.Printf("generate: `.git` not found, write %s skip\n", basefile.FileGitIgnore)
  163. return nil
  164. }
  165. log.Printf("generate: write %s file\n", basefile.FileGitIgnore)
  166. defer log.Printf("generate: write %s file finish\n", basefile.FileGitIgnore)
  167. s, err := os.Stat(basefile.FileGitIgnore)
  168. if err != nil {
  169. log.Printf("generaate: file %s not exists, create new one\n", basefile.FileGitIgnore)
  170. return newGitIgnore()
  171. }
  172. if s.IsDir() {
  173. log.Printf("generaate: %s is dir\n", basefile.FileGitIgnore)
  174. return fmt.Errorf("%s is dir", basefile.FileGitIgnore)
  175. }
  176. res, err := fileutils.CheckFileByLine(basefile.FileGitIgnore, func(s string) bool {
  177. if s == global.GitIgnoreExtFlag {
  178. return true
  179. }
  180. return false
  181. })
  182. if err != nil {
  183. return err
  184. } else if res {
  185. log.Printf("generaate: file %s check ok\n", basefile.FileGitIgnore)
  186. return nil
  187. }
  188. log.Printf("generaate: auto ignore '%s', write to file %s\n", global.GitIgnoreExtFlag, basefile.FileGitIgnore)
  189. return appendGitIgnore()
  190. }
  191. func newGitIgnore() error {
  192. return fileutils.Write(basefile.FileGitIgnore, fmt.Sprintf("# auto write by go generate\n%s\n", global.GitIgnoreExtFlag))
  193. }
  194. func appendGitIgnore() error {
  195. // 写入前添加\n,确保在新的一行
  196. return fileutils.AppendOnExistsFile(basefile.FileGitIgnore, fmt.Sprintf("\n# auto write by go generate\n%s\n", global.GitIgnoreExtFlag))
  197. }