hook.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. "strings"
  11. )
  12. var (
  13. // Direcotry of hook and sample files. Can be changed to "custom_hooks" for very purpose.
  14. HookDir = "hooks"
  15. HookSampleDir = HookDir
  16. // HookNames is a list of Git server hooks' name that are supported.
  17. HookNames = []string{
  18. "pre-receive",
  19. "update",
  20. "post-receive",
  21. }
  22. )
  23. var (
  24. ErrNotValidHook = errors.New("not a valid Git hook")
  25. )
  26. // IsValidHookName returns true if given name is a valid Git hook.
  27. func IsValidHookName(name string) bool {
  28. for _, hn := range HookNames {
  29. if hn == name {
  30. return true
  31. }
  32. }
  33. return false
  34. }
  35. // Hook represents a Git hook.
  36. type Hook struct {
  37. name string
  38. IsActive bool // Indicates whether repository has this hook.
  39. Content string // Content of hook if it's active.
  40. Sample string // Sample content from Git.
  41. path string // Hook file path.
  42. }
  43. // GetHook returns a Git hook by given name and repository.
  44. func GetHook(repoPath, name string) (*Hook, error) {
  45. if !IsValidHookName(name) {
  46. return nil, ErrNotValidHook
  47. }
  48. h := &Hook{
  49. name: name,
  50. path: path.Join(repoPath, HookDir, name),
  51. }
  52. if isFile(h.path) {
  53. data, err := ioutil.ReadFile(h.path)
  54. if err != nil {
  55. return nil, err
  56. }
  57. h.IsActive = true
  58. h.Content = string(data)
  59. return h, nil
  60. }
  61. // Check sample file
  62. samplePath := path.Join(repoPath, HookSampleDir, h.name) + ".sample"
  63. if isFile(samplePath) {
  64. data, err := ioutil.ReadFile(samplePath)
  65. if err != nil {
  66. return nil, err
  67. }
  68. h.Sample = string(data)
  69. }
  70. return h, nil
  71. }
  72. func (h *Hook) Name() string {
  73. return h.name
  74. }
  75. // Update updates content hook file.
  76. func (h *Hook) Update() error {
  77. if len(strings.TrimSpace(h.Content)) == 0 {
  78. if isExist(h.path) {
  79. return os.Remove(h.path)
  80. }
  81. return nil
  82. }
  83. os.MkdirAll(path.Dir(h.path), os.ModePerm)
  84. return ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm)
  85. }
  86. // ListHooks returns a list of Git hooks of given repository.
  87. func ListHooks(repoPath string) (_ []*Hook, err error) {
  88. if !isDir(path.Join(repoPath, "hooks")) {
  89. return nil, errors.New("hooks path does not exist")
  90. }
  91. hooks := make([]*Hook, len(HookNames))
  92. for i, name := range HookNames {
  93. hooks[i], err = GetHook(repoPath, name)
  94. if err != nil {
  95. return nil, err
  96. }
  97. }
  98. return hooks, nil
  99. }