Support SVN pre-commit hoooks
Summary: Ref T4189. This adds SVN support, which was a little more messy than I though. Principally, we can not use `PHABRICATOR_USER` for Subversion, because it strips away the entire environment for "security reasons". Instead, use `--tunnel-user` plus `svnlook author` to figure out the author. Also fix "ssh://" clone URIs, which needs to be "svn+ssh://". Test Plan: - Made SVN commits through the hook. - Made Git commits, too, to make sure I didn't break anything. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4189 Differential Revision: https://secure.phabricator.com/D7683
This commit is contained in:
@@ -4,32 +4,15 @@
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
$username = getenv('PHABRICATOR_USER');
|
||||
if (!$username) {
|
||||
throw new Exception(pht('usage: define PHABRICATOR_USER in environment'));
|
||||
}
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withUsernames(array($username))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
throw new Exception(pht('No such user "%s"!', $username));
|
||||
}
|
||||
|
||||
if ($argc < 2) {
|
||||
throw new Exception(pht('usage: commit-hook <callsign>'));
|
||||
}
|
||||
|
||||
$engine = new DiffusionCommitHookEngine();
|
||||
|
||||
$repository = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($user)
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withCallsigns(array($argv[1]))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
// This capability check is redundant, but can't hurt.
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
DiffusionCapabilityPush::CAPABILITY,
|
||||
))
|
||||
->executeOne();
|
||||
|
||||
if (!$repository) {
|
||||
@@ -37,19 +20,59 @@ if (!$repository) {
|
||||
}
|
||||
|
||||
if (!$repository->isHosted()) {
|
||||
// This should be redundant too, but double check just in case.
|
||||
// This should be redundant, but double check just in case.
|
||||
throw new Exception(pht('Repository "%s" is not hosted!', $callsign));
|
||||
}
|
||||
|
||||
$engine->setRepository($repository);
|
||||
|
||||
|
||||
// Figure out which user is writing the commit.
|
||||
|
||||
if ($repository->isGit()) {
|
||||
$username = getenv('PHABRICATOR_USER');
|
||||
if (!strlen($username)) {
|
||||
throw new Exception(pht('usage: PHABRICATOR_USER should be defined!'));
|
||||
}
|
||||
} else if ($repository->isSVN()) {
|
||||
// NOTE: In Subversion, the entire environment gets wiped so we can't read
|
||||
// PHABRICATOR_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 Exceptiont(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.
|
||||
|
||||
$stdin = @file_get_contents('php://stdin');
|
||||
if ($stdin === false) {
|
||||
throw new Exception(pht('Failed to read stdin!'));
|
||||
}
|
||||
|
||||
$engine = id(new DiffusionCommitHookEngine())
|
||||
->setViewer($user)
|
||||
->setRepository($repository)
|
||||
->setStdin($stdin);
|
||||
$engine->setStdin($stdin);
|
||||
|
||||
$err = $engine->execute();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user