Skip to content

Commit 86b0130

Browse files
committed
hook: predefine sample
1 parent c265e6e commit 86b0130

File tree

3 files changed

+186
-59
lines changed

3 files changed

+186
-59
lines changed

hook.go

+179-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,185 @@ const (
2121
HookPostReceive HookName = "post-receive"
2222
)
2323

24-
// ServerSideHooks contains a list of Git hooks are supported on the server side.
25-
var ServerSideHooks = []HookName{HookPreReceive, HookUpdate, HookPostReceive}
24+
var (
25+
// ServerSideHooks contains a list of Git hooks that are supported on the server side.
26+
ServerSideHooks = []HookName{HookPreReceive, HookUpdate, HookPostReceive}
27+
// ServerSideHookSamples contains samples of Git hooks that are supported on the server side.
28+
ServerSideHookSamples = map[HookName]string{
29+
HookPreReceive: `#!/bin/sh
30+
#
31+
# An example hook script to make use of push options.
32+
# The example simply echoes all push options that start with 'echoback='
33+
# and rejects all pushes when the "reject" push option is used.
34+
#
35+
# To enable this hook, rename this file to "pre-receive".
36+
37+
if test -n "$GIT_PUSH_OPTION_COUNT"
38+
then
39+
i=0
40+
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
41+
do
42+
eval "value=\$GIT_PUSH_OPTION_$i"
43+
case "$value" in
44+
echoback=*)
45+
echo "echo from the pre-receive-hook: ${value#*=}" >&2
46+
;;
47+
reject)
48+
exit 1
49+
esac
50+
i=$((i + 1))
51+
done
52+
fi
53+
`,
54+
HookUpdate: `#!/bin/sh
55+
#
56+
# An example hook script to block unannotated tags from entering.
57+
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
58+
#
59+
# To enable this hook, rename this file to "update".
60+
#
61+
# Config
62+
# ------
63+
# hooks.allowunannotated
64+
# This boolean sets whether unannotated tags will be allowed into the
65+
# repository. By default they won't be.
66+
# hooks.allowdeletetag
67+
# This boolean sets whether deleting tags will be allowed in the
68+
# repository. By default they won't be.
69+
# hooks.allowmodifytag
70+
# This boolean sets whether a tag may be modified after creation. By default
71+
# it won't be.
72+
# hooks.allowdeletebranch
73+
# This boolean sets whether deleting branches will be allowed in the
74+
# repository. By default they won't be.
75+
# hooks.denycreatebranch
76+
# This boolean sets whether remotely creating branches will be denied
77+
# in the repository. By default this is allowed.
78+
#
79+
80+
# --- Command line
81+
refname="$1"
82+
oldrev="$2"
83+
newrev="$3"
84+
85+
# --- Safety check
86+
if [ -z "$GIT_DIR" ]; then
87+
echo "Don't run this script from the command line." >&2
88+
echo " (if you want, you could supply GIT_DIR then run" >&2
89+
echo " $0 <ref> <oldrev> <newrev>)" >&2
90+
exit 1
91+
fi
92+
93+
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
94+
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
95+
exit 1
96+
fi
97+
98+
# --- Config
99+
allowunannotated=$(git config --bool hooks.allowunannotated)
100+
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
101+
denycreatebranch=$(git config --bool hooks.denycreatebranch)
102+
allowdeletetag=$(git config --bool hooks.allowdeletetag)
103+
allowmodifytag=$(git config --bool hooks.allowmodifytag)
104+
105+
# check for no description
106+
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
107+
case "$projectdesc" in
108+
"Unnamed repository"* | "")
109+
echo "*** Project description file hasn't been set" >&2
110+
exit 1
111+
;;
112+
esac
113+
114+
# --- Check types
115+
# if $newrev is 0000...0000, it's a commit to delete a ref.
116+
zero="0000000000000000000000000000000000000000"
117+
if [ "$newrev" = "$zero" ]; then
118+
newrev_type=delete
119+
else
120+
newrev_type=$(git cat-file -t $newrev)
121+
fi
122+
123+
case "$refname","$newrev_type" in
124+
refs/tags/*,commit)
125+
# un-annotated tag
126+
short_refname=${refname##refs/tags/}
127+
if [ "$allowunannotated" != "true" ]; then
128+
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
129+
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
130+
exit 1
131+
fi
132+
;;
133+
refs/tags/*,delete)
134+
# delete tag
135+
if [ "$allowdeletetag" != "true" ]; then
136+
echo "*** Deleting a tag is not allowed in this repository" >&2
137+
exit 1
138+
fi
139+
;;
140+
refs/tags/*,tag)
141+
# annotated tag
142+
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
143+
then
144+
echo "*** Tag '$refname' already exists." >&2
145+
echo "*** Modifying a tag is not allowed in this repository." >&2
146+
exit 1
147+
fi
148+
;;
149+
refs/heads/*,commit)
150+
# branch
151+
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
152+
echo "*** Creating a branch is not allowed in this repository" >&2
153+
exit 1
154+
fi
155+
;;
156+
refs/heads/*,delete)
157+
# delete branch
158+
if [ "$allowdeletebranch" != "true" ]; then
159+
echo "*** Deleting a branch is not allowed in this repository" >&2
160+
exit 1
161+
fi
162+
;;
163+
refs/remotes/*,commit)
164+
# tracking branch
165+
;;
166+
refs/remotes/*,delete)
167+
# delete tracking branch
168+
if [ "$allowdeletebranch" != "true" ]; then
169+
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
170+
exit 1
171+
fi
172+
;;
173+
*)
174+
# Anything else (is there anything else?)
175+
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
176+
exit 1
177+
;;
178+
esac
179+
180+
# --- Finished
181+
exit 0
182+
`,
183+
HookPostReceive: `#!/bin/sh
184+
#
185+
# An example hook script for the "post-receive" event.
186+
#
187+
# The "post-receive" script is run after receive-pack has accepted a pack
188+
# and the repository has been updated. It is passed arguments in through
189+
# stdin in the form
190+
# <oldrev> <newrev> <refname>
191+
# For example:
192+
# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
193+
194+
while read oldrev newrev refname
195+
do
196+
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
197+
if [ "master" = "$branch" ]; then
198+
# Do something
199+
fi
200+
done`,
201+
}
202+
)
26203

27204
// Hook contains information of a Git hook.
28205
type Hook struct {

repo_hook.go

+6-10
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ const DefaultHooksDir = "hooks"
1515

1616
// NewHook creates and returns a new hook with given name. Update method must be called
1717
// to actually save the hook to disk.
18-
func (r *Repository) NewHook(name HookName) *Hook {
18+
func (r *Repository) NewHook(dir string, name HookName) *Hook {
1919
return &Hook{
2020
name: name,
21-
path: filepath.Join(r.path, DefaultHooksDir, string(name)),
21+
path: filepath.Join(r.path, dir, string(name)),
2222
}
2323
}
2424

@@ -43,18 +43,14 @@ func (r *Repository) Hook(dir string, name HookName) (*Hook, error) {
4343
}, nil
4444
}
4545

46-
// 2. Check if a sample file exists.
47-
spath := filepath.Join(r.path, DefaultHooksDir, string(name)+".sample")
48-
if isFile(spath) {
49-
p, err := ioutil.ReadFile(spath)
50-
if err != nil {
51-
return nil, err
52-
}
46+
// 2. Check if sample content exists.
47+
sample := ServerSideHookSamples[name]
48+
if sample != "" {
5349
return &Hook{
5450
name: name,
5551
path: fpath,
5652
isSample: true,
57-
content: string(p),
53+
content: sample,
5854
}, nil
5955
}
6056

repo_hook_test.go

+1-47
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package git
66

77
import (
88
"os"
9-
"path/filepath"
109
"testing"
1110

1211
"github.com/stretchr/testify/assert"
@@ -19,53 +18,8 @@ func TestRepository_Hooks(t *testing.T) {
1918
assert.Nil(t, h)
2019
})
2120

22-
t.Run("no hooks directory", func(t *testing.T) {
23-
wd, err := os.Getwd()
24-
if err != nil {
25-
t.Fatal(err)
26-
}
27-
28-
r, err := Open(wd)
29-
if err != nil {
30-
t.Fatal(err)
31-
}
32-
33-
hooks, err := r.Hooks("")
34-
if err != nil {
35-
t.Fatal(err)
36-
}
37-
assert.Empty(t, hooks)
38-
})
39-
40-
t.Run("no hooks in the directory", func(t *testing.T) {
41-
wd, err := os.Getwd()
42-
if err != nil {
43-
t.Fatal(err)
44-
}
45-
46-
r, err := Open(wd)
47-
if err != nil {
48-
t.Fatal(err)
49-
}
50-
51-
dir := filepath.Join(r.Path(), DefaultHooksDir)
52-
err = os.MkdirAll(dir, os.ModePerm)
53-
if err != nil {
54-
t.Fatal(err)
55-
}
56-
defer func() {
57-
_ = os.RemoveAll(dir)
58-
}()
59-
60-
hooks, err := r.Hooks("")
61-
if err != nil {
62-
t.Fatal(err)
63-
}
64-
assert.Empty(t, hooks)
65-
})
66-
6721
// Save "post-receive" hook with some content
68-
postReceiveHook := testrepo.NewHook(HookPostReceive)
22+
postReceiveHook := testrepo.NewHook(DefaultHooksDir, HookPostReceive)
6923
defer func() {
7024
_ = os.Remove(postReceiveHook.Path())
7125
}()

0 commit comments

Comments
 (0)