2013-12-18 23:18:45 +01:00
|
|
|
<?php
|
|
|
|
|
2014-01-03 21:24:28 +01:00
|
|
|
final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
|
2013-12-18 23:18:45 +01:00
|
|
|
|
2013-12-18 23:18:58 +01:00
|
|
|
private $changesets;
|
2013-12-19 15:55:57 +01:00
|
|
|
private $commitRef;
|
2013-12-20 21:39:01 +01:00
|
|
|
private $fields;
|
|
|
|
private $revision = false;
|
2013-12-18 23:18:45 +01:00
|
|
|
|
|
|
|
public function getAdapterContentName() {
|
|
|
|
return pht('Commit Hook: Commit Content');
|
|
|
|
}
|
|
|
|
|
2013-12-27 22:16:33 +01:00
|
|
|
public function getAdapterSortOrder() {
|
|
|
|
return 2500;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAdapterContentDescription() {
|
|
|
|
return pht(
|
|
|
|
"React to commits being pushed to hosted repositories.\n".
|
2014-03-26 18:44:06 +01:00
|
|
|
"Hook rules can block changes and send push summary mail.");
|
2013-12-27 22:16:33 +01:00
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:00 +02:00
|
|
|
public function isPreCommitRefAdapter() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-18 23:18:45 +01:00
|
|
|
public function getHeraldName() {
|
2014-01-03 21:24:28 +01:00
|
|
|
return pht('Push Log (Content)');
|
2013-12-18 23:18:45 +01:00
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function isDiffEnormous() {
|
|
|
|
$this->getDiffContent('*');
|
|
|
|
return ($this->changesets instanceof Exception);
|
2013-12-18 23:18:45 +01:00
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getDiffContent($type) {
|
2013-12-18 23:18:58 +01:00
|
|
|
if ($this->changesets === null) {
|
|
|
|
try {
|
2014-01-03 21:24:28 +01:00
|
|
|
$this->changesets = $this->getHookEngine()->loadChangesetsForCommit(
|
|
|
|
$this->getObject()->getRefNew());
|
2013-12-18 23:18:58 +01:00
|
|
|
} catch (Exception $ex) {
|
|
|
|
$this->changesets = $ex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->changesets instanceof Exception) {
|
|
|
|
$ex_class = get_class($this->changesets);
|
2017-02-18 10:24:56 +01:00
|
|
|
$ex_message = $this->changesets->getMessage();
|
2013-12-18 23:18:58 +01:00
|
|
|
if ($type === 'name') {
|
|
|
|
return array("<{$ex_class}: {$ex_message}>");
|
|
|
|
} else {
|
|
|
|
return array("<{$ex_class}>" => $ex_message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = array();
|
|
|
|
if ($type === 'name') {
|
|
|
|
foreach ($this->changesets as $change) {
|
|
|
|
$result[] = $change->getFilename();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
foreach ($this->changesets as $change) {
|
|
|
|
$lines = array();
|
|
|
|
foreach ($change->getHunks() as $hunk) {
|
|
|
|
switch ($type) {
|
|
|
|
case '-':
|
|
|
|
$lines[] = $hunk->makeOldFile();
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
$lines[] = $hunk->makeNewFile();
|
|
|
|
break;
|
|
|
|
case '*':
|
|
|
|
default:
|
|
|
|
$lines[] = $hunk->makeChanges();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$result[$change->getFilename()] = implode('', $lines);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getCommitRef() {
|
2013-12-19 15:55:57 +01:00
|
|
|
if ($this->commitRef === null) {
|
2014-01-03 21:24:28 +01:00
|
|
|
$this->commitRef = $this->getHookEngine()->loadCommitRefForCommit(
|
|
|
|
$this->getObject()->getRefNew());
|
2013-12-19 15:55:57 +01:00
|
|
|
}
|
|
|
|
return $this->commitRef;
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getAuthorPHID() {
|
2014-01-03 21:24:28 +01:00
|
|
|
$repository = $this->getHookEngine()->getRepository();
|
2013-12-19 20:05:31 +01:00
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
switch ($vcs) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
|
|
|
$ref = $this->getCommitRef();
|
|
|
|
$author = $ref->getAuthor();
|
|
|
|
if (!strlen($author)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $this->lookupUser($author);
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
|
|
|
// In Subversion, the pusher is always the author.
|
2014-01-03 21:24:28 +01:00
|
|
|
return $this->getHookEngine()->getViewer()->getPHID();
|
2013-12-19 20:05:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getCommitterPHID() {
|
2014-01-03 21:24:28 +01:00
|
|
|
$repository = $this->getHookEngine()->getRepository();
|
2013-12-19 20:05:31 +01:00
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
switch ($vcs) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
2014-03-12 23:24:33 +01:00
|
|
|
// If there's no committer information, we're going to return the
|
|
|
|
// author instead. However, if there's committer information and we
|
|
|
|
// can't resolve it, return `null`.
|
2013-12-19 20:05:31 +01:00
|
|
|
$ref = $this->getCommitRef();
|
|
|
|
$committer = $ref->getCommitter();
|
|
|
|
if (!strlen($committer)) {
|
|
|
|
return $this->getAuthorPHID();
|
|
|
|
}
|
2014-03-12 23:24:33 +01:00
|
|
|
return $this->lookupUser($committer);
|
2013-12-19 20:05:31 +01:00
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
|
|
|
// In Subversion, the pusher is always the committer.
|
2014-01-03 21:24:28 +01:00
|
|
|
return $this->getHookEngine()->getViewer()->getPHID();
|
2013-12-19 20:05:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getAuthorRaw() {
|
2014-01-03 21:24:28 +01:00
|
|
|
$repository = $this->getHookEngine()->getRepository();
|
2013-12-27 22:16:00 +01:00
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
switch ($vcs) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
|
|
|
$ref = $this->getCommitRef();
|
|
|
|
return $ref->getAuthor();
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
|
|
|
// In Subversion, the pusher is always the author.
|
2014-01-03 21:24:28 +01:00
|
|
|
return $this->getHookEngine()->getViewer()->getUsername();
|
2013-12-27 22:16:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getCommitterRaw() {
|
2014-01-03 21:24:28 +01:00
|
|
|
$repository = $this->getHookEngine()->getRepository();
|
2013-12-27 22:16:00 +01:00
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
switch ($vcs) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
|
|
|
// Here, if there's no committer, we're going to return the author
|
|
|
|
// instead.
|
|
|
|
$ref = $this->getCommitRef();
|
|
|
|
$committer = $ref->getCommitter();
|
|
|
|
if (strlen($committer)) {
|
|
|
|
return $committer;
|
|
|
|
}
|
|
|
|
return $ref->getAuthor();
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
|
|
|
// In Subversion, the pusher is always the committer.
|
2014-01-03 21:24:28 +01:00
|
|
|
return $this->getHookEngine()->getViewer()->getUsername();
|
2013-12-27 22:16:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-19 20:05:31 +01:00
|
|
|
private function lookupUser($author) {
|
|
|
|
return id(new DiffusionResolveUserQuery())
|
|
|
|
->withName($author)
|
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
|
2013-12-20 21:39:01 +01:00
|
|
|
private function getCommitFields() {
|
|
|
|
if ($this->fields === null) {
|
|
|
|
$this->fields = id(new DiffusionLowLevelCommitFieldsQuery())
|
2014-01-03 21:24:28 +01:00
|
|
|
->setRepository($this->getHookEngine()->getRepository())
|
2013-12-20 21:39:01 +01:00
|
|
|
->withCommitRef($this->getCommitRef())
|
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
return $this->fields;
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getRevision() {
|
2013-12-20 21:39:01 +01:00
|
|
|
if ($this->revision === false) {
|
|
|
|
$fields = $this->getCommitFields();
|
|
|
|
$revision_id = idx($fields, 'revisionID');
|
|
|
|
if (!$revision_id) {
|
|
|
|
$this->revision = null;
|
|
|
|
} else {
|
|
|
|
$this->revision = id(new DifferentialRevisionQuery())
|
|
|
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
|
|
->withIDs(array($revision_id))
|
Remove obsolete "relationships" code from Differential
Summary:
Ref T10967. There have been two different ways to load reviewers for a while: `needReviewerStatus()` and `needRelationships()`.
The `needRelationships()` stuff was a false start along time ago that didn't really go anywhere. I believe the idea was that we might want to load several different types of edges (subscribers, reviewers, etc) on lots of different types of objects. However, all that stuff pretty much ended up modularizing so that main `Query` classes did not need to know about it, so `needRelationships()` never got generalized or went anywhere.
A handful of things still use it, but get rid of them: they should either `needReviewerStatus()` to get reviewer info, or the ~3 callsites that care about subscribers can just load them directly.
Test Plan:
- Grepped for removed methods (`needRelationships()`, `getReviewers()`, `getCCPHIDs()`, etc).
- Browsed Diffusion, Differential.
- Called `differential.query`.
It's possible I missed some stuff, but it should mostly show up as super obvious fatals ("call needReviewerStatus() before getReviewerStatus()!").
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T10967
Differential Revision: https://secure.phabricator.com/D17518
2017-03-20 22:02:08 +01:00
|
|
|
->needReviewerStatus(true)
|
2013-12-20 21:39:01 +01:00
|
|
|
->executeOne();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->revision;
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getIsMergeCommit() {
|
2014-01-03 21:24:28 +01:00
|
|
|
$repository = $this->getHookEngine()->getRepository();
|
2013-12-20 21:39:40 +01:00
|
|
|
$vcs = $repository->getVersionControlSystem();
|
|
|
|
switch ($vcs) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
|
|
|
$parents = id(new DiffusionLowLevelParentsQuery())
|
|
|
|
->setRepository($repository)
|
2014-01-03 21:24:28 +01:00
|
|
|
->withIdentifier($this->getObject()->getRefNew())
|
2013-12-20 21:39:40 +01:00
|
|
|
->execute();
|
|
|
|
|
|
|
|
return (count($parents) > 1);
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
|
|
|
// NOTE: For now, we ignore "svn:mergeinfo" at all levels. We might
|
|
|
|
// change this some day, but it's not nearly as clear a signal as
|
|
|
|
// ancestry is in Git/Mercurial.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:26:57 +02:00
|
|
|
public function getBranches() {
|
2014-01-03 21:24:28 +01:00
|
|
|
return $this->getHookEngine()->loadBranches(
|
|
|
|
$this->getObject()->getRefNew());
|
2013-12-26 19:40:16 +01:00
|
|
|
}
|
|
|
|
|
2013-12-18 23:18:45 +01:00
|
|
|
}
|