hook.go 2.3 KB

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