1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 08:12:40 +01:00

Support Mercurial pretxnchangegroup hooks

Summary: Ref T4189. Fixes T2066. Mercurial has a //lot// of hooks so I'm not 100% sure this is all we need to install (we may need separate hooks for tags/bookmarks) but it should cover most of what we're after at least.

Test Plan:
  - `bin/repository pull`'d a Mercurial repo and got a hook install.
  - Pushed to a Mercurial repository over SSH and HTTP, with good/bad hooks. Saw hooks fire.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2066, T4189

Differential Revision: https://secure.phabricator.com/D7685
This commit is contained in:
epriestley 2013-12-02 15:46:03 -08:00
parent 017d6ccd07
commit f93c6985ad
5 changed files with 65 additions and 9 deletions

View file

@ -29,11 +29,16 @@ $engine->setRepository($repository);
// Figure out which user is writing the commit. // Figure out which user is writing the commit.
if ($repository->isGit()) { if ($repository->isGit() || $repository->isHg()) {
$username = getenv('PHABRICATOR_USER'); $username = getenv('PHABRICATOR_USER');
if (!strlen($username)) { if (!strlen($username)) {
throw new Exception(pht('usage: PHABRICATOR_USER should be defined!')); throw new Exception(pht('usage: PHABRICATOR_USER should be defined!'));
} }
// TODO: If this is a Mercurial repository, the hook we're responding to
// is available in $argv[2]. It's unclear if we actually need this, or if
// we can block all actions we care about with just pretxnchangegroup.
} else if ($repository->isSVN()) { } else if ($repository->isSVN()) {
// NOTE: In Subversion, the entire environment gets wiped so we can't read // NOTE: In Subversion, the entire environment gets wiped so we can't read
// PHABRICATOR_USER. Instead, we've set "--tunnel-user" to specify the // PHABRICATOR_USER. Instead, we've set "--tunnel-user" to specify the
@ -50,7 +55,7 @@ if ($repository->isGit()) {
$engine->setSubversionTransactionInfo($svn_txn, $svn_repo); $engine->setSubversionTransactionInfo($svn_txn, $svn_repo);
} else { } else {
throw new Exceptiont(pht('Unknown repository type.')); throw new Exception(pht('Unknown repository type.'));
} }
$user = id(new PhabricatorPeopleQuery()) $user = id(new PhabricatorPeopleQuery())
@ -67,9 +72,16 @@ $engine->setViewer($user);
// Read stdin for the hook engine. // Read stdin for the hook engine.
$stdin = @file_get_contents('php://stdin'); if ($repository->isHg()) {
if ($stdin === false) { // Mercurial leaves stdin open, so we can't just read it until EOF.
throw new Exception(pht('Failed to read stdin!')); $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->setStdin($stdin);

View file

@ -406,7 +406,9 @@ final class DiffusionServeController extends DiffusionController {
return $user; return $user;
} }
private function serveMercurialRequest(PhabricatorRepository $repository) { private function serveMercurialRequest(
PhabricatorRepository $repository,
PhabricatorUser $viewer) {
$request = $this->getRequest(); $request = $this->getRequest();
$bin = Filesystem::resolveBinary('hg'); $bin = Filesystem::resolveBinary('hg');
@ -414,7 +416,9 @@ final class DiffusionServeController extends DiffusionController {
throw new Exception("Unable to find `hg` in PATH!"); throw new Exception("Unable to find `hg` in PATH!");
} }
$env = array(); $env = array(
'PHABRICATOR_USER' => $viewer->getUsername(),
);
$input = PhabricatorStartup::getRawInput(); $input = PhabricatorStartup::getRawInput();
$cmd = $request->getStr('cmd'); $cmd = $request->getStr('cmd');

View file

@ -51,6 +51,9 @@ final class DiffusionCommitHookEngine extends Phobject {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$err = $this->executeSubversionHook(); $err = $this->executeSubversionHook();
break; break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$err = $this->executeMercurialHook();
break;
default: default:
throw new Exception(pht('Unsupported repository type "%s"!', $type)); throw new Exception(pht('Unsupported repository type "%s"!', $type));
} }
@ -73,6 +76,13 @@ final class DiffusionCommitHookEngine extends Phobject {
return 0; return 0;
} }
private function executeMercurialHook() {
// TODO: Here, too, useful things should be done.
return 0;
}
private function parseGitUpdates($stdin) { private function parseGitUpdates($stdin) {
$updates = array(); $updates = array();

View file

@ -42,7 +42,8 @@ final class DiffusionSSHMercurialServeWorkflow
$command = csprintf('hg -R %s serve --stdio', $repository->getLocalPath()); $command = csprintf('hg -R %s serve --stdio', $repository->getLocalPath());
$command = PhabricatorDaemon::sudoCommandAsDaemonUser($command); $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
$future = new ExecFuture('%C', $command); $future = id(new ExecFuture('%C', $command))
->setEnv($this->getEnvironment());
$io_channel = $this->getIOChannel(); $io_channel = $this->getIOChannel();
$protocol_channel = new DiffusionSSHMercurialWireClientProtocolChannel( $protocol_channel = new DiffusionSSHMercurialWireClientProtocolChannel(

View file

@ -87,6 +87,8 @@ final class PhabricatorRepositoryPullEngine
$this->installGitHook(); $this->installGitHook();
} else if ($is_svn) { } else if ($is_svn) {
$this->installSubversionHook(); $this->installSubversionHook();
} else if ($is_hg) {
$this->installMercurialHook();
} else { } else {
$this->logPull( $this->logPull(
pht( pht(
@ -335,7 +337,7 @@ final class PhabricatorRepositoryPullEngine
$path); $path);
} else { } else {
$repository->execxRemoteCommand( $repository->execxRemoteCommand(
'clone -- %s %s', 'clone --noupdate -- %s %s',
$repository->getRemoteURI(), $repository->getRemoteURI(),
$path); $path);
} }
@ -383,6 +385,33 @@ final class PhabricatorRepositoryPullEngine
} }
/**
* @task hg
*/
private function installMercurialHook() {
$repository = $this->getRepository();
$path = $repository->getLocalPath().'.hg/hgrc';
$root = dirname(phutil_get_library_root('phabricator'));
$bin = $root.'/bin/commit-hook';
$data = array();
$data[] = '[hooks]';
$data[] = csprintf(
'pretxnchangegroup.phabricator = %s %s %s',
$bin,
$repository->getCallsign(),
'pretxnchangegroup');
$data[] = null;
$data = implode("\n", $data);
$this->log('%s', pht('Installing commit hook config to "%s"...', $path));
Filesystem::writeFile($path, $data);
}
/* -( Pulling Subversion Working Copies )---------------------------------- */ /* -( Pulling Subversion Working Copies )---------------------------------- */