Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14407542
D20259.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D20259.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1531,6 +1531,7 @@
'HeraldRemarkupFieldValue' => 'applications/herald/value/HeraldRemarkupFieldValue.php',
'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php',
'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
+ 'HeraldRuleActionAffectsObjectEdgeType' => 'applications/herald/edge/HeraldRuleActionAffectsObjectEdgeType.php',
'HeraldRuleAdapter' => 'applications/herald/adapter/HeraldRuleAdapter.php',
'HeraldRuleAdapterField' => 'applications/herald/field/rule/HeraldRuleAdapterField.php',
'HeraldRuleController' => 'applications/herald/controller/HeraldRuleController.php',
@@ -1540,7 +1541,9 @@
'HeraldRuleEditor' => 'applications/herald/editor/HeraldRuleEditor.php',
'HeraldRuleField' => 'applications/herald/field/rule/HeraldRuleField.php',
'HeraldRuleFieldGroup' => 'applications/herald/field/rule/HeraldRuleFieldGroup.php',
+ 'HeraldRuleIndexEngineExtension' => 'applications/herald/engineextension/HeraldRuleIndexEngineExtension.php',
'HeraldRuleListController' => 'applications/herald/controller/HeraldRuleListController.php',
+ 'HeraldRuleListView' => 'applications/herald/view/HeraldRuleListView.php',
'HeraldRuleNameTransaction' => 'applications/herald/xaction/HeraldRuleNameTransaction.php',
'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php',
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
@@ -7189,8 +7192,10 @@
'PhabricatorFlaggableInterface',
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
+ 'PhabricatorIndexableInterface',
'PhabricatorSubscribableInterface',
),
+ 'HeraldRuleActionAffectsObjectEdgeType' => 'PhabricatorEdgeType',
'HeraldRuleAdapter' => 'HeraldAdapter',
'HeraldRuleAdapterField' => 'HeraldRuleField',
'HeraldRuleController' => 'HeraldController',
@@ -7200,7 +7205,9 @@
'HeraldRuleEditor' => 'PhabricatorApplicationTransactionEditor',
'HeraldRuleField' => 'HeraldField',
'HeraldRuleFieldGroup' => 'HeraldFieldGroup',
+ 'HeraldRuleIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
'HeraldRuleListController' => 'HeraldController',
+ 'HeraldRuleListView' => 'AphrontView',
'HeraldRuleNameTransaction' => 'HeraldRuleTransactionType',
'HeraldRulePHIDType' => 'PhabricatorPHIDType',
'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
diff --git a/src/applications/harbormaster/controller/HarbormasterPlanViewController.php b/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
--- a/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
@@ -62,6 +62,7 @@
$builds_view = $this->newBuildsView($plan);
$options_view = $this->newOptionsView($plan);
+ $rules_view = $this->newRulesView($plan);
$timeline = $this->buildTransactionTimeline(
$plan,
@@ -76,6 +77,7 @@
$error,
$step_list,
$options_view,
+ $rules_view,
$builds_view,
$timeline,
));
@@ -486,6 +488,42 @@
->appendChild($list);
}
+ private function newRulesView(HarbormasterBuildPlan $plan) {
+ $viewer = $this->getViewer();
+
+ $rules = id(new HeraldRuleQuery())
+ ->setViewer($viewer)
+ ->withDisabled(false)
+ ->withAffectedObjectPHIDs(array($plan->getPHID()))
+ ->needValidateAuthors(true)
+ ->execute();
+
+ $list = id(new HeraldRuleListView())
+ ->setViewer($viewer)
+ ->setRules($rules)
+ ->newObjectList();
+
+ $list->setNoDataString(pht('No active Herald rules trigger this build.'));
+
+ $more_href = new PhutilURI(
+ '/herald/',
+ array('affectedPHID' => $plan->getPHID()));
+
+ $more_link = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setIcon('fa-list-ul')
+ ->setText(pht('View All Rules'))
+ ->setHref($more_href);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Run By Herald Rules'))
+ ->addActionLink($more_link);
+
+ return id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->appendChild($list);
+ }
private function newOptionsView(HarbormasterBuildPlan $plan) {
$viewer = $this->getViewer();
diff --git a/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php b/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
--- a/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
+++ b/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
@@ -91,4 +91,9 @@
'Run build plans: %s.',
$this->renderHandleList($value));
}
+
+ public function getPHIDsAffectedByAction(HeraldActionRecord $record) {
+ return $record->getTarget();
+ }
+
}
diff --git a/src/applications/herald/action/HeraldAction.php b/src/applications/herald/action/HeraldAction.php
--- a/src/applications/herald/action/HeraldAction.php
+++ b/src/applications/herald/action/HeraldAction.php
@@ -401,4 +401,8 @@
return null;
}
+ public function getPHIDsAffectedByAction(HeraldActionRecord $record) {
+ return array();
+ }
+
}
diff --git a/src/applications/herald/edge/HeraldRuleActionAffectsObjectEdgeType.php b/src/applications/herald/edge/HeraldRuleActionAffectsObjectEdgeType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/herald/edge/HeraldRuleActionAffectsObjectEdgeType.php
@@ -0,0 +1,8 @@
+<?php
+
+final class HeraldRuleActionAffectsObjectEdgeType
+ extends PhabricatorEdgeType {
+
+ const EDGECONST = 69;
+
+}
diff --git a/src/applications/herald/editor/HeraldRuleEditor.php b/src/applications/herald/editor/HeraldRuleEditor.php
--- a/src/applications/herald/editor/HeraldRuleEditor.php
+++ b/src/applications/herald/editor/HeraldRuleEditor.php
@@ -74,4 +74,8 @@
return $body;
}
+ protected function supportsSearch() {
+ return true;
+ }
+
}
diff --git a/src/applications/herald/engineextension/HeraldRuleIndexEngineExtension.php b/src/applications/herald/engineextension/HeraldRuleIndexEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/herald/engineextension/HeraldRuleIndexEngineExtension.php
@@ -0,0 +1,92 @@
+<?php
+
+final class HeraldRuleIndexEngineExtension
+ extends PhabricatorIndexEngineExtension {
+
+ const EXTENSIONKEY = 'herald.actions';
+
+ public function getExtensionName() {
+ return pht('Herald Actions');
+ }
+
+ public function shouldIndexObject($object) {
+ if (!($object instanceof HeraldRule)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function indexObject(
+ PhabricatorIndexEngine $engine,
+ $object) {
+
+ $edge_type = HeraldRuleActionAffectsObjectEdgeType::EDGECONST;
+
+ $old_edges = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $object->getPHID(),
+ $edge_type);
+ $old_edges = array_fuse($old_edges);
+
+ $new_edges = $this->getPHIDsAffectedByActions($object);
+ $new_edges = array_fuse($new_edges);
+
+ $add_edges = array_diff_key($new_edges, $old_edges);
+ $rem_edges = array_diff_key($old_edges, $new_edges);
+
+ if (!$add_edges && !$rem_edges) {
+ return;
+ }
+
+ $editor = new PhabricatorEdgeEditor();
+
+ foreach ($add_edges as $phid) {
+ $editor->addEdge($object->getPHID(), $edge_type, $phid);
+ }
+
+ foreach ($rem_edges as $phid) {
+ $editor->removeEdge($object->getPHID(), $edge_type, $phid);
+ }
+
+ $editor->save();
+ }
+
+ public function getIndexVersion($object) {
+ $phids = $this->getPHIDsAffectedByActions($object);
+ sort($phids);
+ $phids = implode(':', $phids);
+ return PhabricatorHash::digestForIndex($phids);
+ }
+
+ private function getPHIDsAffectedByActions(HeraldRule $rule) {
+ $viewer = $this->getViewer();
+
+ $rule = id(new HeraldRuleQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($rule->getID()))
+ ->needConditionsAndActions(true)
+ ->executeOne();
+ if (!$rule) {
+ return array();
+ }
+
+ $phids = array();
+
+ $actions = HeraldAction::getAllActions();
+ foreach ($rule->getActions() as $action_record) {
+ $action = idx($actions, $action_record->getAction());
+
+ if (!$action) {
+ continue;
+ }
+
+ foreach ($action->getPHIDsAffectedByAction($action_record) as $phid) {
+ $phids[] = $phid;
+ }
+ }
+
+ $phids = array_fuse($phids);
+ return array_keys($phids);
+ }
+
+}
diff --git a/src/applications/herald/query/HeraldRuleQuery.php b/src/applications/herald/query/HeraldRuleQuery.php
--- a/src/applications/herald/query/HeraldRuleQuery.php
+++ b/src/applications/herald/query/HeraldRuleQuery.php
@@ -11,6 +11,7 @@
private $active;
private $datasourceQuery;
private $triggerObjectPHIDs;
+ private $affectedObjectPHIDs;
private $needConditionsAndActions;
private $needAppliedToPHIDs;
@@ -61,6 +62,11 @@
return $this;
}
+ public function withAffectedObjectPHIDs(array $phids) {
+ $this->affectedObjectPHIDs = $phids;
+ return $this;
+ }
+
public function needConditionsAndActions($need) {
$this->needConditionsAndActions = $need;
return $this;
@@ -261,9 +267,31 @@
$this->triggerObjectPHIDs);
}
+ if ($this->affectedObjectPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'edge_affects.dst IN (%Ls)',
+ $this->affectedObjectPHIDs);
+ }
+
return $where;
}
+ protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
+ $joins = parent::buildJoinClauseParts($conn);
+
+ if ($this->affectedObjectPHIDs !== null) {
+ $joins[] = qsprintf(
+ $conn,
+ 'JOIN %T edge_affects ON rule.phid = edge_affects.src
+ AND edge_affects.type = %d',
+ PhabricatorEdgeConfig::TABLE_NAME_EDGE,
+ HeraldRuleActionAffectsObjectEdgeType::EDGECONST);
+ }
+
+ return $joins;
+ }
+
private function validateRuleAuthors(array $rules) {
// "Global" and "Object" rules always have valid authors.
foreach ($rules as $key => $rule) {
diff --git a/src/applications/herald/query/HeraldRuleSearchEngine.php b/src/applications/herald/query/HeraldRuleSearchEngine.php
--- a/src/applications/herald/query/HeraldRuleSearchEngine.php
+++ b/src/applications/herald/query/HeraldRuleSearchEngine.php
@@ -55,6 +55,10 @@
pht('(Show All)'),
pht('Show Only Disabled Rules'),
pht('Show Only Enabled Rules')),
+ id(new PhabricatorPHIDsSearchField())
+ ->setLabel(pht('Affected Objects'))
+ ->setKey('affectedPHIDs')
+ ->setAliases(array('affectedPHID')),
);
}
@@ -81,6 +85,10 @@
$query->withActive($map['active']);
}
+ if ($map['affectedPHIDs']) {
+ $query->withAffectedObjectPHIDs($map['affectedPHIDs']);
+ }
+
return $query;
}
@@ -127,54 +135,18 @@
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($rules, 'HeraldRule');
-
$viewer = $this->requireViewer();
- $handles = $viewer->loadHandles(mpull($rules, 'getAuthorPHID'));
-
- $content_type_map = HeraldAdapter::getEnabledAdapterMap($viewer);
-
- $list = id(new PHUIObjectItemListView())
- ->setUser($viewer);
- foreach ($rules as $rule) {
- $monogram = $rule->getMonogram();
-
- $item = id(new PHUIObjectItemView())
- ->setObjectName($monogram)
- ->setHeader($rule->getName())
- ->setHref("/{$monogram}");
-
- if ($rule->isPersonalRule()) {
- $item->addIcon('fa-user', pht('Personal Rule'));
- $item->addByline(
- pht(
- 'Authored by %s',
- $handles[$rule->getAuthorPHID()]->renderLink()));
- } else if ($rule->isObjectRule()) {
- $item->addIcon('fa-briefcase', pht('Object Rule'));
- } else {
- $item->addIcon('fa-globe', pht('Global Rule'));
- }
-
- if ($rule->getIsDisabled()) {
- $item->setDisabled(true);
- $item->addIcon('fa-lock grey', pht('Disabled'));
- } else if (!$rule->hasValidAuthor()) {
- $item->setDisabled(true);
- $item->addIcon('fa-user grey', pht('Author Not Active'));
- }
-
- $content_type_name = idx($content_type_map, $rule->getContentType());
- $item->addAttribute(pht('Affects: %s', $content_type_name));
-
- $list->addItem($item);
- }
+
+ $list = id(new HeraldRuleListView())
+ ->setViewer($viewer)
+ ->setRules($rules)
+ ->newObjectList();
$result = new PhabricatorApplicationSearchResultView();
$result->setObjectList($list);
$result->setNoDataString(pht('No rules found.'));
return $result;
-
}
protected function getNewUserBody() {
diff --git a/src/applications/herald/storage/HeraldRule.php b/src/applications/herald/storage/HeraldRule.php
--- a/src/applications/herald/storage/HeraldRule.php
+++ b/src/applications/herald/storage/HeraldRule.php
@@ -6,6 +6,7 @@
PhabricatorFlaggableInterface,
PhabricatorPolicyInterface,
PhabricatorDestructibleInterface,
+ PhabricatorIndexableInterface,
PhabricatorSubscribableInterface {
const TABLE_RULE_APPLIED = 'herald_ruleapplied';
diff --git a/src/applications/herald/view/HeraldRuleListView.php b/src/applications/herald/view/HeraldRuleListView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/herald/view/HeraldRuleListView.php
@@ -0,0 +1,65 @@
+<?php
+
+final class HeraldRuleListView
+ extends AphrontView {
+
+ private $rules;
+
+ public function setRules(array $rules) {
+ assert_instances_of($rules, 'HeraldRule');
+ $this->rules = $rules;
+ return $this;
+ }
+
+ public function render() {
+ return $this->newObjectList();
+ }
+
+ public function newObjectList() {
+ $viewer = $this->getViewer();
+ $rules = $this->rules;
+
+ $handles = $viewer->loadHandles(mpull($rules, 'getAuthorPHID'));
+
+ $content_type_map = HeraldAdapter::getEnabledAdapterMap($viewer);
+
+ $list = id(new PHUIObjectItemListView())
+ ->setViewer($viewer);
+ foreach ($rules as $rule) {
+ $monogram = $rule->getMonogram();
+
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName($monogram)
+ ->setHeader($rule->getName())
+ ->setHref($rule->getURI());
+
+ if ($rule->isPersonalRule()) {
+ $item->addIcon('fa-user', pht('Personal Rule'));
+ $item->addByline(
+ pht(
+ 'Authored by %s',
+ $handles[$rule->getAuthorPHID()]->renderLink()));
+ } else if ($rule->isObjectRule()) {
+ $item->addIcon('fa-briefcase', pht('Object Rule'));
+ } else {
+ $item->addIcon('fa-globe', pht('Global Rule'));
+ }
+
+ if ($rule->getIsDisabled()) {
+ $item->setDisabled(true);
+ $item->addIcon('fa-lock grey', pht('Disabled'));
+ } else if (!$rule->hasValidAuthor()) {
+ $item->setDisabled(true);
+ $item->addIcon('fa-user grey', pht('Author Not Active'));
+ }
+
+ $content_type_name = idx($content_type_map, $rule->getContentType());
+ $item->addAttribute(pht('Affects: %s', $content_type_name));
+
+ $list->addItem($item);
+ }
+
+ return $list;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 25, 3:09 AM (9 h, 23 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6924659
Default Alt Text
D20259.diff (15 KB)
Attached To
Mode
D20259: On Harbormaster build plans, show which Herald rules trigger builds
Attached
Detach File
Event Timeline
Log In to Comment