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:
parent
e115f11f80
commit
5f4df0f3e3
3 changed files with 103 additions and 2 deletions
|
@ -885,4 +885,43 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
->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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
|
|||
|
||||
private $log;
|
||||
private $hookEngine;
|
||||
private $changesets;
|
||||
|
||||
public function setPushLog(PhabricatorRepositoryPushLog $log) {
|
||||
$this->log = $log;
|
||||
|
@ -35,6 +36,11 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
|
|||
public function getFields() {
|
||||
return array_merge(
|
||||
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_PUSHER,
|
||||
self::FIELD_PUSHER_PROJECTS,
|
||||
|
@ -78,6 +84,14 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
|
|||
public function getHeraldField($field) {
|
||||
$log = $this->getObject();
|
||||
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:
|
||||
return $this->hookEngine->getRepository()->getPHID();
|
||||
case self::FIELD_PUSHER:
|
||||
|
@ -89,7 +103,6 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
|
|||
return parent::getHeraldField($field);
|
||||
}
|
||||
|
||||
|
||||
public function applyHeraldEffects(array $effects) {
|
||||
assert_instances_of($effects, 'HeraldEffect');
|
||||
|
||||
|
@ -117,4 +130,53 @@ final class HeraldPreCommitContentAdapter extends HeraldAdapter {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ final class HeraldRule extends HeraldDAO
|
|||
protected $ruleType;
|
||||
protected $isDisabled = 0;
|
||||
|
||||
protected $configVersion = 17;
|
||||
protected $configVersion = 18;
|
||||
|
||||
// phids for which this rule has been applied
|
||||
private $ruleApplied = self::ATTACHABLE;
|
||||
|
|
Loading…
Reference in a new issue