1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-20 05:42:40 +01:00

Support "changed filename" and "file content" fields for commit content Herald rules

Summary: Ref T4195. Adds support for diff content rules.

Test Plan: Pushed SVN and Git changes through, saw them generate reasonable transcripts. Mercurial still isn't hooked up to this phase.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4195

Differential Revision: https://secure.phabricator.com/D7791
This commit is contained in:
epriestley 2013-12-18 14:18:58 -08:00
parent e115f11f80
commit 5f4df0f3e3
3 changed files with 103 additions and 2 deletions

View file

@ -885,4 +885,43 @@ final class DiffusionCommitHookEngine extends Phobject {
->setRejectDetails(null); ->setRejectDetails(null);
} }
public function loadChangesetsForCommit($identifier) {
$vcs = $this->getRepository()->getVersionControlSystem();
switch ($vcs) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
// For git and hg, we can use normal commands.
$drequest = DiffusionRequest::newFromDictionary(
array(
'repository' => $this->getRepository(),
'user' => $this->getViewer(),
'commit' => $identifier,
));
$raw_diff = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)
->setTimeout(5 * 60)
->setLinesOfContext(0)
->loadRawDiff();
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
// TODO: This diff has 3 lines of context, which produces slightly
// incorrect "added file content" and "removed file content" results.
// This may also choke on binaries, but "svnlook diff" does not support
// the "--diff-cmd" flag.
// For subversion, we need to use `svnlook`.
list($raw_diff) = execx(
'svnlook diff -t %s %s',
$this->subversionTransaction,
$this->subversionRepository);
break;
default:
throw new Exception(pht("Unknown VCS '%s!'", $vcs));
}
$parser = new ArcanistDiffParser();
$changes = $parser->parseDiff($raw_diff);
$diff = DifferentialDiff::newFromRawChanges($changes);
return $diff->getChangesets();
}
} }

View file

@ -4,6 +4,7 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
private $log; private $log;
private $hookEngine; private $hookEngine;
private $changesets;
public function setPushLog(PhabricatorRepositoryPushLog $log) { public function setPushLog(PhabricatorRepositoryPushLog $log) {
$this->log = $log; $this->log = $log;
@ -35,6 +36,11 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
public function getFields() { public function getFields() {
return array_merge( return array_merge(
array( array(
self::FIELD_BODY,
self::FIELD_DIFF_FILE,
self::FIELD_DIFF_CONTENT,
self::FIELD_DIFF_ADDED_CONTENT,
self::FIELD_DIFF_REMOVED_CONTENT,
self::FIELD_REPOSITORY, self::FIELD_REPOSITORY,
self::FIELD_PUSHER, self::FIELD_PUSHER,
self::FIELD_PUSHER_PROJECTS, self::FIELD_PUSHER_PROJECTS,
@ -78,6 +84,14 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
public function getHeraldField($field) { public function getHeraldField($field) {
$log = $this->getObject(); $log = $this->getObject();
switch ($field) { switch ($field) {
case self::FIELD_DIFF_FILE:
return $this->getDiffContent('name');
case self::FIELD_DIFF_CONTENT:
return $this->getDiffContent('*');
case self::FIELD_DIFF_ADDED_CONTENT:
return $this->getDiffContent('+');
case self::FIELD_DIFF_REMOVED_CONTENT:
return $this->getDiffContent('-');
case self::FIELD_REPOSITORY: case self::FIELD_REPOSITORY:
return $this->hookEngine->getRepository()->getPHID(); return $this->hookEngine->getRepository()->getPHID();
case self::FIELD_PUSHER: case self::FIELD_PUSHER:
@ -89,7 +103,6 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
return parent::getHeraldField($field); return parent::getHeraldField($field);
} }
public function applyHeraldEffects(array $effects) { public function applyHeraldEffects(array $effects) {
assert_instances_of($effects, 'HeraldEffect'); assert_instances_of($effects, 'HeraldEffect');
@ -117,4 +130,53 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
return $result; return $result;
} }
private function getDiffContent($type) {
if ($this->changesets === null) {
try {
$this->changesets = $this->hookEngine->loadChangesetsForCommit(
$this->log->getRefNew());
} catch (Exception $ex) {
$this->changesets = $ex;
}
}
if ($this->changesets instanceof Exception) {
$ex_class = get_class($this->changesets);
$ex_message = $this->changesets->getmessage();
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;
}
} }

View file

@ -16,7 +16,7 @@ final class HeraldRule extends HeraldDAO
protected $ruleType; protected $ruleType;
protected $isDisabled = 0; protected $isDisabled = 0;
protected $configVersion = 17; protected $configVersion = 18;
// phids for which this rule has been applied // phids for which this rule has been applied
private $ruleApplied = self::ATTACHABLE; private $ruleApplied = self::ATTACHABLE;