2011-03-25 05:32:26 +01:00
|
|
|
<?php
|
|
|
|
|
2014-08-20 23:26:29 +02:00
|
|
|
final class HeraldDifferentialRevisionAdapter
|
|
|
|
extends HeraldDifferentialAdapter {
|
2011-03-25 05:32:26 +01:00
|
|
|
|
|
|
|
protected $revision;
|
|
|
|
|
2013-11-09 01:48:17 +01:00
|
|
|
protected $buildPlans = array();
|
2011-03-25 05:32:26 +01:00
|
|
|
|
2011-04-06 05:49:31 +02:00
|
|
|
protected $affectedPackages;
|
|
|
|
protected $changesets;
|
2014-04-14 21:06:26 +02:00
|
|
|
private $haveHunks;
|
2011-04-06 05:49:31 +02:00
|
|
|
|
2013-10-05 00:15:48 +02:00
|
|
|
public function getAdapterApplicationClass() {
|
2014-07-23 02:03:09 +02:00
|
|
|
return 'PhabricatorDifferentialApplication';
|
2013-08-02 17:55:13 +02:00
|
|
|
}
|
|
|
|
|
2015-04-23 00:25:34 +02:00
|
|
|
protected function newObject() {
|
2015-04-22 23:01:32 +02:00
|
|
|
return new DifferentialRevision();
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:47 +02:00
|
|
|
protected function initializeNewAdapter() {
|
|
|
|
$this->revision = $this->newObject();
|
|
|
|
}
|
|
|
|
|
2013-10-05 21:55:34 +02:00
|
|
|
public function getObject() {
|
|
|
|
return $this->revision;
|
|
|
|
}
|
|
|
|
|
2013-08-02 17:55:13 +02:00
|
|
|
public function getAdapterContentType() {
|
|
|
|
return 'differential';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAdapterContentName() {
|
|
|
|
return pht('Differential Revisions');
|
|
|
|
}
|
|
|
|
|
2013-12-27 22:16:33 +01:00
|
|
|
public function getAdapterContentDescription() {
|
|
|
|
return pht(
|
|
|
|
"React to revisions being created or updated.\n".
|
|
|
|
"Revision rules can send email, flag revisions, add reviewers, ".
|
|
|
|
"and run build plans.");
|
|
|
|
}
|
|
|
|
|
2013-12-31 01:48:07 +01:00
|
|
|
public function supportsRuleType($rule_type) {
|
|
|
|
switch ($rule_type) {
|
|
|
|
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
|
|
|
|
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
|
|
|
|
return true;
|
|
|
|
case HeraldRuleTypeConfig::RULE_TYPE_OBJECT:
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-02 21:35:33 +02:00
|
|
|
public function getRepetitionOptions() {
|
|
|
|
return array(
|
|
|
|
HeraldRepetitionPolicyConfig::EVERY,
|
|
|
|
HeraldRepetitionPolicyConfig::FIRST,
|
|
|
|
);
|
|
|
|
}
|
2013-08-02 19:25:45 +02:00
|
|
|
|
2013-08-02 17:55:13 +02:00
|
|
|
public static function newLegacyAdapter(
|
2011-04-06 05:49:31 +02:00
|
|
|
DifferentialRevision $revision,
|
|
|
|
DifferentialDiff $diff) {
|
2013-08-02 17:55:13 +02:00
|
|
|
$object = new HeraldDifferentialRevisionAdapter();
|
|
|
|
|
2013-10-05 01:30:43 +02:00
|
|
|
// Reload the revision to pick up relationship information.
|
|
|
|
$revision = id(new DifferentialRevisionQuery())
|
|
|
|
->withIDs(array($revision->getID()))
|
|
|
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
|
|
->needRelationships(true)
|
|
|
|
->needReviewerStatus(true)
|
|
|
|
->executeOne();
|
|
|
|
|
2013-08-02 17:55:13 +02:00
|
|
|
$object->revision = $revision;
|
2015-07-08 21:25:48 +02:00
|
|
|
$object->setDiff($diff);
|
2013-08-02 17:55:13 +02:00
|
|
|
|
|
|
|
return $object;
|
2011-03-25 05:32:26 +01:00
|
|
|
}
|
|
|
|
|
2013-11-09 01:48:17 +01:00
|
|
|
public function getBuildPlans() {
|
|
|
|
return $this->buildPlans;
|
|
|
|
}
|
|
|
|
|
2011-03-25 05:32:26 +01:00
|
|
|
public function getHeraldName() {
|
|
|
|
return $this->revision->getTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function loadChangesets() {
|
2011-04-06 05:49:31 +02:00
|
|
|
if ($this->changesets === null) {
|
2015-07-08 21:25:48 +02:00
|
|
|
$this->changesets = $this->getDiff()->loadChangesets();
|
2011-04-06 05:49:31 +02:00
|
|
|
}
|
|
|
|
return $this->changesets;
|
|
|
|
}
|
|
|
|
|
2014-08-20 23:26:29 +02:00
|
|
|
protected function loadChangesetsWithHunks() {
|
2014-04-14 21:06:26 +02:00
|
|
|
$changesets = $this->loadChangesets();
|
|
|
|
|
|
|
|
if ($changesets && !$this->haveHunks) {
|
|
|
|
$this->haveHunks = true;
|
|
|
|
|
|
|
|
id(new DifferentialHunkQuery())
|
|
|
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
|
|
->withChangesets($changesets)
|
|
|
|
->needAttachToChangesets(true)
|
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $changesets;
|
|
|
|
}
|
|
|
|
|
2011-04-06 05:49:31 +02:00
|
|
|
public function loadAffectedPackages() {
|
|
|
|
if ($this->affectedPackages === null) {
|
|
|
|
$this->affectedPackages = array();
|
|
|
|
|
|
|
|
$repository = $this->loadRepository();
|
|
|
|
if ($repository) {
|
|
|
|
$packages = PhabricatorOwnersPackage::loadAffectedPackages(
|
|
|
|
$repository,
|
|
|
|
$this->loadAffectedPaths());
|
|
|
|
$this->affectedPackages = $packages;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->affectedPackages;
|
|
|
|
}
|
|
|
|
|
2015-07-08 21:25:48 +02:00
|
|
|
public function loadReviewers() {
|
2015-07-30 20:39:35 +02:00
|
|
|
$reviewers = $this->getObject()->getReviewerStatus();
|
|
|
|
return mpull($reviewers, 'getReviewerPHID');
|
2013-08-02 20:32:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getActions($rule_type) {
|
|
|
|
switch ($rule_type) {
|
|
|
|
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
|
Support custom actions in Herald
Summary:
This was significantly easier than expected. Here's an example of what an extension class might look like:
```
<?php
final class AddRiskReviewHeraldCustomAction extends HeraldCustomAction {
public function appliesToAdapter(HeraldAdapter $adapter) {
return $adapter instanceof HeraldDifferentialRevisionAdapter;
}
public function appliesToRuleType($rule_type) {
return $rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL ||
$rule_type == HeraldRuleTypeConfig::RULE_TYPE_OBJECT;
}
public function getActionKey() {
return 'custom:add-risk';
}
public function getActionName() {
return 'Add risk rating (JSON)';
}
public function getActionType() {
return HeraldAdapter::VALUE_TEXT;
}
public function applyEffect(
HeraldAdapter $adapter,
$object,
HeraldEffect $effect) {
$key = "phragile:risk-rating";
// Read existing value.
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_VIEW);
$field_list->readFieldsFromStorage($object);
$field_list = mpull($field_list->getFields(), null, 'getFieldKey');
$field = $field_list[$key];
$field->setObject($object);
$field->setViewer(PhabricatorUser::getOmnipotentUser());
$risk = $field->getValue();
$old_risk = $risk; // PHP copies arrays by default!
// Add new value to array.
$herald_args = phutil_json_decode($effect->getTarget());
$risk[$herald_args['key']] = array(
'value' => $herald_args['value'],
'reason' => $herald_args['reason']);
$risk_key = $herald_args['key'];
// Set new value.
$adapter->queueTransaction(
id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', $key)
->setOldValue($old_risk)
->setNewValue($risk));
return new HeraldApplyTranscript(
$effect,
true,
pht(
'Modifying automatic risk ratings (key: %s)!',
$risk_key));
}
}
```
Test Plan: Created a custom action for differential revisions, set up a Herald rule to match and trigger the custom action, did 'arc diff' and saw the action trigger in the transcripts.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: locutus, edutibau, ite-klass, epriestley, Korvin
Maniphest Tasks: T4884
Differential Revision: https://secure.phabricator.com/D8784
2014-07-02 06:29:46 +02:00
|
|
|
return array_merge(
|
|
|
|
array(
|
|
|
|
self::ACTION_APPLY_BUILD_PLANS,
|
|
|
|
),
|
|
|
|
parent::getActions($rule_type));
|
2013-08-02 20:32:50 +02:00
|
|
|
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
|
Support custom actions in Herald
Summary:
This was significantly easier than expected. Here's an example of what an extension class might look like:
```
<?php
final class AddRiskReviewHeraldCustomAction extends HeraldCustomAction {
public function appliesToAdapter(HeraldAdapter $adapter) {
return $adapter instanceof HeraldDifferentialRevisionAdapter;
}
public function appliesToRuleType($rule_type) {
return $rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL ||
$rule_type == HeraldRuleTypeConfig::RULE_TYPE_OBJECT;
}
public function getActionKey() {
return 'custom:add-risk';
}
public function getActionName() {
return 'Add risk rating (JSON)';
}
public function getActionType() {
return HeraldAdapter::VALUE_TEXT;
}
public function applyEffect(
HeraldAdapter $adapter,
$object,
HeraldEffect $effect) {
$key = "phragile:risk-rating";
// Read existing value.
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_VIEW);
$field_list->readFieldsFromStorage($object);
$field_list = mpull($field_list->getFields(), null, 'getFieldKey');
$field = $field_list[$key];
$field->setObject($object);
$field->setViewer(PhabricatorUser::getOmnipotentUser());
$risk = $field->getValue();
$old_risk = $risk; // PHP copies arrays by default!
// Add new value to array.
$herald_args = phutil_json_decode($effect->getTarget());
$risk[$herald_args['key']] = array(
'value' => $herald_args['value'],
'reason' => $herald_args['reason']);
$risk_key = $herald_args['key'];
// Set new value.
$adapter->queueTransaction(
id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', $key)
->setOldValue($old_risk)
->setNewValue($risk));
return new HeraldApplyTranscript(
$effect,
true,
pht(
'Modifying automatic risk ratings (key: %s)!',
$risk_key));
}
}
```
Test Plan: Created a custom action for differential revisions, set up a Herald rule to match and trigger the custom action, did 'arc diff' and saw the action trigger in the transcripts.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: locutus, edutibau, ite-klass, epriestley, Korvin
Maniphest Tasks: T4884
Differential Revision: https://secure.phabricator.com/D8784
2014-07-02 06:29:46 +02:00
|
|
|
return array_merge(
|
2015-07-30 20:39:35 +02:00
|
|
|
array(),
|
Support custom actions in Herald
Summary:
This was significantly easier than expected. Here's an example of what an extension class might look like:
```
<?php
final class AddRiskReviewHeraldCustomAction extends HeraldCustomAction {
public function appliesToAdapter(HeraldAdapter $adapter) {
return $adapter instanceof HeraldDifferentialRevisionAdapter;
}
public function appliesToRuleType($rule_type) {
return $rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL ||
$rule_type == HeraldRuleTypeConfig::RULE_TYPE_OBJECT;
}
public function getActionKey() {
return 'custom:add-risk';
}
public function getActionName() {
return 'Add risk rating (JSON)';
}
public function getActionType() {
return HeraldAdapter::VALUE_TEXT;
}
public function applyEffect(
HeraldAdapter $adapter,
$object,
HeraldEffect $effect) {
$key = "phragile:risk-rating";
// Read existing value.
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_VIEW);
$field_list->readFieldsFromStorage($object);
$field_list = mpull($field_list->getFields(), null, 'getFieldKey');
$field = $field_list[$key];
$field->setObject($object);
$field->setViewer(PhabricatorUser::getOmnipotentUser());
$risk = $field->getValue();
$old_risk = $risk; // PHP copies arrays by default!
// Add new value to array.
$herald_args = phutil_json_decode($effect->getTarget());
$risk[$herald_args['key']] = array(
'value' => $herald_args['value'],
'reason' => $herald_args['reason']);
$risk_key = $herald_args['key'];
// Set new value.
$adapter->queueTransaction(
id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', $key)
->setOldValue($old_risk)
->setNewValue($risk));
return new HeraldApplyTranscript(
$effect,
true,
pht(
'Modifying automatic risk ratings (key: %s)!',
$risk_key));
}
}
```
Test Plan: Created a custom action for differential revisions, set up a Herald rule to match and trigger the custom action, did 'arc diff' and saw the action trigger in the transcripts.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: locutus, edutibau, ite-klass, epriestley, Korvin
Maniphest Tasks: T4884
Differential Revision: https://secure.phabricator.com/D8784
2014-07-02 06:29:46 +02:00
|
|
|
parent::getActions($rule_type));
|
2013-08-02 20:32:50 +02:00
|
|
|
}
|
2011-03-25 05:32:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function applyHeraldEffects(array $effects) {
|
2012-03-30 22:51:54 +02:00
|
|
|
assert_instances_of($effects, 'HeraldEffect');
|
|
|
|
|
2011-03-25 05:32:26 +01:00
|
|
|
$result = array();
|
|
|
|
|
|
|
|
foreach ($effects as $effect) {
|
|
|
|
$action = $effect->getAction();
|
|
|
|
switch ($action) {
|
2013-11-09 01:48:17 +01:00
|
|
|
case self::ACTION_APPLY_BUILD_PLANS:
|
|
|
|
foreach ($effect->getTarget() as $phid) {
|
|
|
|
$this->buildPlans[] = $phid;
|
|
|
|
}
|
|
|
|
$result[] = new HeraldApplyTranscript(
|
|
|
|
$effect,
|
|
|
|
true,
|
|
|
|
pht('Applied build plans.'));
|
|
|
|
break;
|
2011-03-25 05:32:26 +01:00
|
|
|
default:
|
2015-04-22 23:00:44 +02:00
|
|
|
$result[] = $this->applyStandardEffect($effect);
|
Support custom actions in Herald
Summary:
This was significantly easier than expected. Here's an example of what an extension class might look like:
```
<?php
final class AddRiskReviewHeraldCustomAction extends HeraldCustomAction {
public function appliesToAdapter(HeraldAdapter $adapter) {
return $adapter instanceof HeraldDifferentialRevisionAdapter;
}
public function appliesToRuleType($rule_type) {
return $rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL ||
$rule_type == HeraldRuleTypeConfig::RULE_TYPE_OBJECT;
}
public function getActionKey() {
return 'custom:add-risk';
}
public function getActionName() {
return 'Add risk rating (JSON)';
}
public function getActionType() {
return HeraldAdapter::VALUE_TEXT;
}
public function applyEffect(
HeraldAdapter $adapter,
$object,
HeraldEffect $effect) {
$key = "phragile:risk-rating";
// Read existing value.
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_VIEW);
$field_list->readFieldsFromStorage($object);
$field_list = mpull($field_list->getFields(), null, 'getFieldKey');
$field = $field_list[$key];
$field->setObject($object);
$field->setViewer(PhabricatorUser::getOmnipotentUser());
$risk = $field->getValue();
$old_risk = $risk; // PHP copies arrays by default!
// Add new value to array.
$herald_args = phutil_json_decode($effect->getTarget());
$risk[$herald_args['key']] = array(
'value' => $herald_args['value'],
'reason' => $herald_args['reason']);
$risk_key = $herald_args['key'];
// Set new value.
$adapter->queueTransaction(
id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', $key)
->setOldValue($old_risk)
->setNewValue($risk));
return new HeraldApplyTranscript(
$effect,
true,
pht(
'Modifying automatic risk ratings (key: %s)!',
$risk_key));
}
}
```
Test Plan: Created a custom action for differential revisions, set up a Herald rule to match and trigger the custom action, did 'arc diff' and saw the action trigger in the transcripts.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: locutus, edutibau, ite-klass, epriestley, Korvin
Maniphest Tasks: T4884
Differential Revision: https://secure.phabricator.com/D8784
2014-07-02 06:29:46 +02:00
|
|
|
break;
|
2011-03-25 05:32:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
2014-07-23 02:03:09 +02:00
|
|
|
|
2011-03-25 05:32:26 +01:00
|
|
|
}
|