選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

hook.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2015 The Gogs 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. "errors"
  7. "io/ioutil"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. "strings"
  12. "github.com/unknwon/com"
  13. )
  14. // hookNames is a list of Git server hooks' name that are supported.
  15. var hookNames = []string{
  16. "pre-receive",
  17. "update",
  18. "post-receive",
  19. }
  20. var (
  21. // ErrNotValidHook error when a git hook is not valid
  22. ErrNotValidHook = errors.New("not a valid Git hook")
  23. )
  24. // IsValidHookName returns true if given name is a valid Git hook.
  25. func IsValidHookName(name string) bool {
  26. for _, hn := range hookNames {
  27. if hn == name {
  28. return true
  29. }
  30. }
  31. return false
  32. }
  33. // Hook represents a Git hook.
  34. type Hook struct {
  35. name string
  36. IsActive bool // Indicates whether repository has this hook.
  37. Content string // Content of hook if it's active.
  38. Sample string // Sample content from Git.
  39. path string // Hook file path.
  40. }
  41. // GetHook returns a Git hook by given name and repository.
  42. func GetHook(repoPath, name string) (*Hook, error) {
  43. if !IsValidHookName(name) {
  44. return nil, ErrNotValidHook
  45. }
  46. h := &Hook{
  47. name: name,
  48. path: path.Join(repoPath, "hooks", name+".d", name),
  49. }
  50. samplePath := filepath.Join(repoPath, "hooks", name+".sample")
  51. if isFile(h.path) {
  52. data, err := ioutil.ReadFile(h.path)
  53. if err != nil {
  54. return nil, err
  55. }
  56. h.IsActive = true
  57. h.Content = string(data)
  58. } else if isFile(samplePath) {
  59. data, err := ioutil.ReadFile(samplePath)
  60. if err != nil {
  61. return nil, err
  62. }
  63. h.Sample = string(data)
  64. }
  65. return h, nil
  66. }
  67. // Name return the name of the hook
  68. func (h *Hook) Name() string {
  69. return h.name
  70. }
  71. // Update updates hook settings.
  72. func (h *Hook) Update() error {
  73. if len(strings.TrimSpace(h.Content)) == 0 {
  74. if isExist(h.path) {
  75. err := os.Remove(h.path)
  76. if err != nil {
  77. return err
  78. }
  79. }
  80. h.IsActive = false
  81. return nil
  82. }
  83. d := filepath.Dir(h.path)
  84. if err := os.MkdirAll(d, os.ModePerm); err != nil {
  85. return err
  86. }
  87. err := ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm)
  88. if err != nil {
  89. return err
  90. }
  91. h.IsActive = true
  92. return nil
  93. }
  94. // ListHooks returns a list of Git hooks of given repository.
  95. func ListHooks(repoPath string) (_ []*Hook, err error) {
  96. if !isDir(path.Join(repoPath, "hooks")) {
  97. return nil, errors.New("hooks path does not exist")
  98. }
  99. hooks := make([]*Hook, len(hookNames))
  100. for i, name := range hookNames {
  101. hooks[i], err = GetHook(repoPath, name)
  102. if err != nil {
  103. return nil, err
  104. }
  105. }
  106. return hooks, nil
  107. }
  108. const (
  109. // HookPathUpdate hook update path
  110. HookPathUpdate = "hooks/update"
  111. )
  112. // SetUpdateHook writes given content to update hook of the reposiotry.
  113. func SetUpdateHook(repoPath, content string) (err error) {
  114. log("Setting update hook: %s", repoPath)
  115. hookPath := path.Join(repoPath, HookPathUpdate)
  116. if com.IsExist(hookPath) {
  117. err = os.Remove(hookPath)
  118. } else {
  119. err = os.MkdirAll(path.Dir(hookPath), os.ModePerm)
  120. }
  121. if err != nil {
  122. return err
  123. }
  124. return ioutil.WriteFile(hookPath, []byte(content), 0777)
  125. }