Fix #264
parent
91e5c24a31
commit
64c68220d2
@ -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)
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
0.5.4.1005 Beta
|
0.5.5.1006 Beta
|
@ -0,0 +1,41 @@
|
|||||||
|
{{template "ng/base/head" .}}
|
||||||
|
{{template "ng/base/header" .}}
|
||||||
|
<div id="repo-wrapper">
|
||||||
|
{{template "repo/header" .}}
|
||||||
|
<div id="setting-wrapper" class="main-wrapper">
|
||||||
|
<div id="repo-setting" class="container clear">
|
||||||
|
{{template "repo/settings/nav" .}}
|
||||||
|
<div class="grid-4-5 left">
|
||||||
|
<div class="setting-content">
|
||||||
|
{{template "ng/base/alert" .}}
|
||||||
|
<div id="setting-content">
|
||||||
|
<div id="repo-hooks-panel" class="panel panel-radius">
|
||||||
|
<div class="panel-header">
|
||||||
|
<strong>{{.i18n.Tr "repo.settings.githooks"}}</strong>
|
||||||
|
</div>
|
||||||
|
<form class="form form-align panel-body" id="repo-setting-form" action="{{.RepoLink}}/settings/hooks/git/{{.Hook.Name}}" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<div class="text-center panel-desc">{{.i18n.Tr "repo.settings.githook_edit_desc"}}</div>
|
||||||
|
{{with .Hook}}
|
||||||
|
<div class="field">
|
||||||
|
<label>{{$.i18n.Tr "repo.settings.githook_name"}}</label>
|
||||||
|
<label class="text-left">{{.Name}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="field clear">
|
||||||
|
<label class="left" for="content">{{$.i18n.Tr "repo.settings.githook_content"}}</label>
|
||||||
|
<textarea class="ipt-textarea ipt-large ipt-radius" id="content" name="content" cols="60" rows="20" wrap="off">{{if .IsActive}}{{.Content}}{{else}}{{.Sample}}{{end}}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<span class="form-label"></span>
|
||||||
|
<button class="btn btn-green btn-large btn-radius" id="change-reponame-btn" href="#change-reponame-modal">{{$.i18n.Tr "repo.settings.update_githook"}}</button>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "ng/base/footer" .}}
|
@ -0,0 +1,37 @@
|
|||||||
|
{{template "ng/base/head" .}}
|
||||||
|
{{template "ng/base/header" .}}
|
||||||
|
<div id="repo-wrapper">
|
||||||
|
{{template "repo/header" .}}
|
||||||
|
<div id="setting-wrapper" class="main-wrapper">
|
||||||
|
<div id="repo-setting" class="container clear">
|
||||||
|
{{template "repo/settings/nav" .}}
|
||||||
|
<div class="grid-4-5 left">
|
||||||
|
<div class="setting-content">
|
||||||
|
{{template "ng/base/alert" .}}
|
||||||
|
<div id="setting-content">
|
||||||
|
<div id="repo-hooks-panel" class="panel panel-radius">
|
||||||
|
<div class="panel-header">
|
||||||
|
<strong>{{.i18n.Tr "repo.settings.githooks"}}</strong>
|
||||||
|
</div>
|
||||||
|
<ul class="panel-body setting-list">
|
||||||
|
<li>{{.i18n.Tr "repo.settings.githooks_desc" | Str2html}}</li>
|
||||||
|
{{range .Hooks}}
|
||||||
|
<li>
|
||||||
|
{{if .IsActive}}
|
||||||
|
<span class="left text-success"><i class="octicon octicon-check"></i></span>
|
||||||
|
{{else}}
|
||||||
|
<span class="left text-grey"><i class="octicon octicon-primitive-dot"></i></span>
|
||||||
|
{{end}}
|
||||||
|
<span>{{.Name}}</span>
|
||||||
|
<a href="{{$.RepoLink}}/settings/hooks/git/{{.Name}}" class="text-blue right"><i class="fa fa-pencil"></i></a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "ng/base/footer" .}}
|
Loading…
Reference in New Issue