forked from phacility/phabricator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommit_hook.php
executable file
·169 lines (136 loc) · 5.31 KB
/
commit_hook.php
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env php
<?php
// NOTE: This script will sometimes emit a warning like this on startup:
//
// No entry for terminal type "unknown";
// using dumb terminal settings.
//
// This can be fixed by adding "TERM=dumb" to the shebang line, but doing so
// causes some systems to hang mysteriously. See T7119.
// Commit hooks execute in an unusual context where the environment may be
// unavailable, particularly in SVN. The first parameter to this script is
// either a bare repository identifier ("X"), or a repository identifier
// followed by an instance identifier ("X:instance"). If we have an instance
// identifier, unpack it into the environment before we start up. This allows
// subclasses of PhabricatorConfigSiteSource to read it and build an instance
// environment.
if ($argc > 1) {
$context = $argv[1];
$context = explode(':', $context, 2);
$argv[1] = $context[0];
if (count($context) > 1) {
$_ENV['PHABRICATOR_INSTANCE'] = $context[1];
putenv('PHABRICATOR_INSTANCE='.$context[1]);
}
}
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
if ($argc < 2) {
throw new Exception(pht('usage: commit-hook <callsign>'));
}
$engine = new DiffusionCommitHookEngine();
$repository = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withCallsigns(array($argv[1]))
->needProjectPHIDs(true)
->executeOne();
if (!$repository) {
throw new Exception(pht('No such repository "%s"!', $argv[1]));
}
if (!$repository->isHosted()) {
// This should be redundant, but double check just in case.
throw new Exception(pht('Repository "%s" is not hosted!', $argv[1]));
}
$engine->setRepository($repository);
// Figure out which user is writing the commit.
if ($repository->isGit() || $repository->isHg()) {
$username = getenv(DiffusionCommitHookEngine::ENV_USER);
if (!strlen($username)) {
throw new Exception(
pht('usage: %s should be defined!', DiffusionCommitHookEngine::ENV_USER));
}
if ($repository->isHg()) {
// We respond to several different hooks in Mercurial.
$engine->setMercurialHook($argv[2]);
}
} else if ($repository->isSVN()) {
// NOTE: In Subversion, the entire environment gets wiped so we can't read
// DiffusionCommitHookEngine::ENV_USER. Instead, we've set "--tunnel-user" to
// specify the correct user; read this user out of the commit log.
if ($argc < 4) {
throw new Exception(pht('usage: commit-hook <callsign> <repo> <txn>'));
}
$svn_repo = $argv[2];
$svn_txn = $argv[3];
list($username) = execx('svnlook author -t %s %s', $svn_txn, $svn_repo);
$username = rtrim($username, "\n");
$engine->setSubversionTransactionInfo($svn_txn, $svn_repo);
} else {
throw new Exception(pht('Unknown repository type.'));
}
$user = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withUsernames(array($username))
->executeOne();
if (!$user) {
throw new Exception(pht('No such user "%s"!', $username));
}
$engine->setViewer($user);
// Read stdin for the hook engine.
if ($repository->isHg()) {
// Mercurial leaves stdin open, so we can't just read it until EOF.
$stdin = '';
} else {
// Git and Subversion write data into stdin and then close it. Read the
// data.
$stdin = @file_get_contents('php://stdin');
if ($stdin === false) {
throw new Exception(pht('Failed to read stdin!'));
}
}
$engine->setStdin($stdin);
$engine->setOriginalArgv(array_slice($argv, 2));
$remote_address = getenv(DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS);
if (strlen($remote_address)) {
$engine->setRemoteAddress($remote_address);
}
$remote_protocol = getenv(DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL);
if (strlen($remote_protocol)) {
$engine->setRemoteProtocol($remote_protocol);
}
try {
$err = $engine->execute();
} catch (DiffusionCommitHookRejectException $ex) {
$console = PhutilConsole::getConsole();
if (PhabricatorEnv::getEnvConfig('phabricator.serious-business')) {
$preamble = pht('*** PUSH REJECTED BY COMMIT HOOK ***');
} else {
$preamble = pht(<<<EOTXT
+---------------------------------------------------------------+
| * * * PUSH REJECTED BY EVIL DRAGON BUREAUCRATS * * * |
+---------------------------------------------------------------+
\
\ ^ /^
\ / \ // \
\ |\___/| / \// .\
\ /V V \__ / // | \ \ *----*
/ / \/_/ // | \ \ \ |
@___@` \/_ // | \ \ \/\ \
0/0/| \/_ // | \ \ \ \
0/0/0/0/| \/// | \ \ | |
0/0/0/0/0/_|_ / ( // | \ _\ | /
0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / /
,-} _ *-.|.-~-. .~ ~
\ \__/ `/\ / ~-. _ .-~ /
\____(Oo) *. } { /
( (--) .----~-.\ \-` .~
//__\\\\ \ DENIED! ///.----..< \ _ -~
// \\\\ ///-._ _ _ _ _ _ _{^ - - - - ~
EOTXT
);
}
$console->writeErr("%s\n\n", $preamble);
$console->writeErr("%s\n\n", $ex->getMessage());
$err = 1;
}
exit($err);