1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.util;
44
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertNull;
47 import static org.junit.Assert.fail;
48
49 import java.io.ByteArrayOutputStream;
50 import java.io.File;
51 import java.io.IOException;
52 import java.io.PrintStream;
53
54 import org.eclipse.jgit.api.Git;
55 import org.eclipse.jgit.api.errors.AbortedByHookException;
56 import org.eclipse.jgit.hooks.CommitMsgHook;
57 import org.eclipse.jgit.hooks.PreCommitHook;
58 import org.eclipse.jgit.junit.JGitTestUtil;
59 import org.eclipse.jgit.junit.RepositoryTestCase;
60 import org.eclipse.jgit.revwalk.RevCommit;
61 import org.junit.Assume;
62 import org.junit.Test;
63
64 public class HookTest extends RepositoryTestCase {
65
66 @Test
67 public void testFindHook() throws Exception {
68 assumeSupportedPlatform();
69
70 assertNull("no hook should be installed",
71 FS.DETECTED.findHook(db, PreCommitHook.NAME));
72 File hookFile = writeHookFile(PreCommitHook.NAME,
73 "#!/bin/bash\necho \"test $1 $2\"");
74 assertEquals("expected to find pre-commit hook", hookFile,
75 FS.DETECTED.findHook(db, PreCommitHook.NAME));
76 }
77
78 @Test
79 public void testFailedCommitMsgHookBlocksCommit() throws Exception {
80 assumeSupportedPlatform();
81
82 writeHookFile(CommitMsgHook.NAME,
83 "#!/bin/sh\necho \"test\"\n\necho 1>&2 \"stderr\"\nexit 1");
84 Git git = Git.wrap(db);
85 String path = "a.txt";
86 writeTrashFile(path, "content");
87 git.add().addFilepattern(path).call();
88 ByteArrayOutputStream out = new ByteArrayOutputStream();
89 try {
90 git.commit().setMessage("commit")
91 .setHookOutputStream(new PrintStream(out)).call();
92 fail("expected commit-msg hook to abort commit");
93 } catch (AbortedByHookException e) {
94 assertEquals("unexpected error message from commit-msg hook",
95 "Rejected by \"commit-msg\" hook.\nstderr\n",
96 e.getMessage());
97 assertEquals("unexpected output from commit-msg hook", "test\n",
98 out.toString());
99 }
100 }
101
102 @Test
103 public void testCommitMsgHookReceivesCorrectParameter() throws Exception {
104 assumeSupportedPlatform();
105
106 writeHookFile(CommitMsgHook.NAME,
107 "#!/bin/sh\necho $1\n\necho 1>&2 \"stderr\"\nexit 0");
108 Git git = Git.wrap(db);
109 String path = "a.txt";
110 writeTrashFile(path, "content");
111 git.add().addFilepattern(path).call();
112 ByteArrayOutputStream out = new ByteArrayOutputStream();
113 git.commit().setMessage("commit")
114 .setHookOutputStream(new PrintStream(out)).call();
115 assertEquals(".git/COMMIT_EDITMSG\n", out.toString("UTF-8"));
116 }
117
118 @Test
119 public void testCommitMsgHookCanModifyCommitMessage() throws Exception {
120 assumeSupportedPlatform();
121
122 writeHookFile(CommitMsgHook.NAME,
123 "#!/bin/sh\necho \"new message\" > $1\nexit 0");
124 Git git = Git.wrap(db);
125 String path = "a.txt";
126 writeTrashFile(path, "content");
127 git.add().addFilepattern(path).call();
128 ByteArrayOutputStream out = new ByteArrayOutputStream();
129 RevCommit revCommit = git.commit().setMessage("commit")
130 .setHookOutputStream(new PrintStream(out)).call();
131 assertEquals("new message\n", revCommit.getFullMessage());
132 }
133
134 @Test
135 public void testRunHook() throws Exception {
136 assumeSupportedPlatform();
137
138 writeHookFile(PreCommitHook.NAME,
139 "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\necho 1>&2 \"stderr\"");
140 ByteArrayOutputStream out = new ByteArrayOutputStream();
141 ByteArrayOutputStream err = new ByteArrayOutputStream();
142 ProcessResult res = FS.DETECTED.runHookIfPresent(db,
143 PreCommitHook.NAME,
144 new String[] {
145 "arg1", "arg2" },
146 new PrintStream(out), new PrintStream(err), "stdin");
147 assertEquals("unexpected hook output", "test arg1 arg2\nstdin\n",
148 out.toString("UTF-8"));
149 assertEquals("unexpected output on stderr stream", "stderr\n",
150 err.toString("UTF-8"));
151 assertEquals("unexpected exit code", 0, res.getExitCode());
152 assertEquals("unexpected process status", ProcessResult.Status.OK,
153 res.getStatus());
154 }
155
156 @Test
157 public void testFailedPreCommitHookBlockCommit() throws Exception {
158 assumeSupportedPlatform();
159
160 writeHookFile(PreCommitHook.NAME,
161 "#!/bin/sh\necho \"test\"\n\necho 1>&2 \"stderr\"\nexit 1");
162 Git git = Git.wrap(db);
163 String path = "a.txt";
164 writeTrashFile(path, "content");
165 git.add().addFilepattern(path).call();
166 ByteArrayOutputStream out = new ByteArrayOutputStream();
167 try {
168 git.commit().setMessage("commit")
169 .setHookOutputStream(new PrintStream(out)).call();
170 fail("expected pre-commit hook to abort commit");
171 } catch (AbortedByHookException e) {
172 assertEquals("unexpected error message from pre-commit hook",
173 "Rejected by \"pre-commit\" hook.\nstderr\n",
174 e.getMessage());
175 assertEquals("unexpected output from pre-commit hook", "test\n",
176 out.toString());
177 }
178 }
179
180 private File writeHookFile(final String name, final String data)
181 throws IOException {
182 File path = new File(db.getWorkTree() + "/.git/hooks/", name);
183 JGitTestUtil.write(path, data);
184 FS.DETECTED.setExecute(path, true);
185 return path;
186 }
187
188 private void assumeSupportedPlatform() {
189 Assume.assumeTrue(FS.DETECTED instanceof FS_POSIX
190 || FS.DETECTED instanceof FS_Win32_Cygwin);
191 }
192 }