You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.5 KiB

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