summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorUnknwon <joe2010xtmf@163.com>2014-10-06 17:50:00 -0400
committerUnknwon <joe2010xtmf@163.com>2014-10-06 17:50:00 -0400
commit64c68220d203cb07be001184cde4b35d4b503344 (patch)
tree1355846382ff21a2b1a3de606da3d9979a479dc8 /modules
parent91e5c24a314170490139d661a921d94b8ab0555b (diff)
downloadgitea-64c68220d203cb07be001184cde4b35d4b503344.tar.gz
gitea-64c68220d203cb07be001184cde4b35d4b503344.zip
Fix #264
Diffstat (limited to 'modules')
-rw-r--r--modules/git/hooks.go111
-rw-r--r--modules/git/utils.go21
-rw-r--r--modules/middleware/repo.go10
-rw-r--r--modules/setting/setting.go2
4 files changed, 144 insertions, 0 deletions
diff --git a/modules/git/hooks.go b/modules/git/hooks.go
new file mode 100644
index 0000000000..b8d15e5e75
--- /dev/null
+++ b/modules/git/hooks.go
@@ -0,0 +1,111 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package git
+
+import (
+ "errors"
+ "io/ioutil"
+ "os"
+ "path"
+ "strings"
+)
+
+// hookNames is a list of Git hooks' name that are supported.
+var hookNames = []string{
+ "pre-applypatch",
+ "applypatch-msg",
+ "prepare-commit-msg",
+ "commit-msg",
+ "pre-commit",
+ "pre-rebase",
+ "post-commit",
+ "post-receive",
+ "post-update",
+}
+
+var (
+ ErrNotValidHook = errors.New("not a valid Git hook")
+)
+
+// IsValidHookName returns true if given name is a valid Git hook.
+func IsValidHookName(name string) bool {
+ for _, hn := range hookNames {
+ if hn == name {
+ return true
+ }
+ }
+ return false
+}
+
+// Hook represents a Git hook.
+type Hook struct {
+ name string
+ IsActive bool // Indicates whether repository has this hook.
+ Content string // Content of hook if it's active.
+ Sample string // Sample content from Git.
+ path string // Hook file path.
+}
+
+// GetHook returns a Git hook by given name and repository.
+func GetHook(repoPath, name string) (*Hook, error) {
+ if !IsValidHookName(name) {
+ return nil, ErrNotValidHook
+ }
+ h := &Hook{
+ name: name,
+ path: path.Join(repoPath, "hooks", name),
+ }
+ if isFile(h.path) {
+ data, err := ioutil.ReadFile(h.path)
+ if err != nil {
+ return nil, err
+ }
+ h.IsActive = true
+ h.Content = string(data)
+ } else if isFile(h.path + ".sample") {
+ data, err := ioutil.ReadFile(h.path + ".sample")
+ if err != nil {
+ return nil, err
+ }
+ h.Sample = string(data)
+ }
+ return h, nil
+}
+
+func (h *Hook) Name() string {
+ return h.name
+}
+
+// Update updates hook settings.
+func (h *Hook) Update() error {
+ if len(strings.TrimSpace(h.Content)) == 0 {
+ return os.Remove(h.path)
+ }
+ return ioutil.WriteFile(h.path, []byte(h.Content), os.ModePerm)
+}
+
+// ListHooks returns a list of Git hooks of given repository.
+func ListHooks(repoPath string) (_ []*Hook, err error) {
+ if !isDir(path.Join(repoPath, "hooks")) {
+ return nil, errors.New("hooks path does not exist")
+ }
+
+ hooks := make([]*Hook, len(hookNames))
+ for i, name := range hookNames {
+ hooks[i], err = GetHook(repoPath, name)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return hooks, nil
+}
+
+func (repo *Repository) GetHook(name string) (*Hook, error) {
+ return GetHook(repo.Path, name)
+}
+
+func (repo *Repository) Hooks() ([]*Hook, error) {
+ return ListHooks(repo.Path)
+}
diff --git a/modules/git/utils.go b/modules/git/utils.go
index 26eef23191..6abbca557b 100644
--- a/modules/git/utils.go
+++ b/modules/git/utils.go
@@ -7,6 +7,7 @@ package git
import (
"bytes"
"container/list"
+ "os"
"path/filepath"
"strings"
)
@@ -46,3 +47,23 @@ func RefEndName(refStr string) string {
func filepathFromSHA1(rootdir, sha1 string) string {
return filepath.Join(rootdir, "objects", sha1[:2], sha1[2:])
}
+
+// isDir returns true if given path is a directory,
+// or returns false when it's a file or does not exist.
+func isDir(dir string) bool {
+ f, e := os.Stat(dir)
+ if e != nil {
+ return false
+ }
+ return f.IsDir()
+}
+
+// isFile returns true if given path is a file,
+// or returns false when it's a directory or does not exist.
+func isFile(filePath string) bool {
+ f, e := os.Stat(filePath)
+ if e != nil {
+ return false
+ }
+ return !f.IsDir()
+}
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index c6250f6d59..78af58eac8 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -308,3 +308,13 @@ func RequireTrueOwner() macaron.Handler {
}
}
}
+
+// GitHookService checks if repsitory Git hooks service has been enabled.
+func GitHookService() macaron.Handler {
+ return func(ctx *Context) {
+ if !setting.Service.EnableGitHooks {
+ ctx.Handle(404, "GitHookService", nil)
+ return
+ }
+ }
+}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 67e48108d9..b8fc4dec2e 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -275,6 +275,7 @@ var Service struct {
LdapAuth bool
ActiveCodeLives int
ResetPwdCodeLives int
+ EnableGitHooks bool
}
func newService() {
@@ -284,6 +285,7 @@ func newService() {
Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW")
Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR")
Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION")
+ Service.EnableGitHooks = Cfg.MustBool("service", "ENABLE_GIT_HOOKS")
}
var logLevels = map[string]string{