diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 6aa910135c..1824448bb7 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -756,6 +756,7 @@ phutil_register_library_map(array( 'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php', 'HeraldPHIDTypeRule' => 'applications/herald/phid/HeraldPHIDTypeRule.php', 'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php', + 'HeraldPreCommitContentAdapter' => 'applications/diffusion/herald/HeraldPreCommitContentAdapter.php', 'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php', 'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php', 'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php', @@ -3180,6 +3181,7 @@ phutil_register_library_map(array( 'HeraldNewController' => 'HeraldController', 'HeraldPHIDTypeRule' => 'PhabricatorPHIDType', 'HeraldPholioMockAdapter' => 'HeraldAdapter', + 'HeraldPreCommitContentAdapter' => 'HeraldAdapter', 'HeraldPreCommitRefAdapter' => 'HeraldAdapter', 'HeraldRecursiveConditionsException' => 'Exception', 'HeraldRemarkupRule' => 'PhabricatorRemarkupRuleObject', diff --git a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php index d45a9c336c..b669bbf555 100644 --- a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php +++ b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php @@ -132,12 +132,13 @@ final class DiffusionCommitHookEngine extends Phobject { throw $ex; } - $this->applyHeraldRefRules($ref_updates); + $this->applyHeraldRefRules($ref_updates, $all_updates); $content_updates = $this->findContentUpdates($ref_updates); $all_updates = array_merge($all_updates, $content_updates); - // TODO: Fire content Herald rules. + $this->applyHeraldContentRules($content_updates, $all_updates); + // TODO: Fire external hooks. // If we make it this far, we're accepting these changes. Mark all the @@ -225,19 +226,41 @@ final class DiffusionCommitHookEngine extends Phobject { /* -( Herald )------------------------------------------------------------- */ + private function applyHeraldRefRules( + array $ref_updates, + array $all_updates) { + $this->applyHeraldRules( + $ref_updates, + new HeraldPreCommitRefAdapter(), + $all_updates); + } - private function applyHeraldRefRules(array $ref_updates) { - if (!$ref_updates) { + private function applyHeraldContentRules( + array $content_updates, + array $all_updates) { + $this->applyHeraldRules( + $content_updates, + new HeraldPreCommitContentAdapter(), + $all_updates); + } + + private function applyHeraldRules( + array $updates, + HeraldAdapter $adapter_template, + array $all_updates) { + + if (!$updates) { return; } + $adapter_template->setHookEngine($this); + $engine = new HeraldEngine(); $rules = null; $blocking_effect = null; - foreach ($ref_updates as $ref_update) { - $adapter = id(new HeraldPreCommitRefAdapter()) - ->setPushLog($ref_update) - ->setHookEngine($this); + foreach ($updates as $update) { + $adapter = id(clone $adapter_template) + ->setPushLog($update); if ($rules === null) { $rules = $engine->loadRulesForAdapter($adapter); @@ -258,9 +281,9 @@ final class DiffusionCommitHookEngine extends Phobject { } if ($blocking_effect) { - foreach ($ref_updates as $ref_update) { - $ref_update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD); - $ref_update->setRejectDetails($blocking_effect->getRulePHID()); + foreach ($all_updates as $update) { + $update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD); + $update->setRejectDetails($blocking_effect->getRulePHID()); } $message = $blocking_effect->getTarget(); diff --git a/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php new file mode 100644 index 0000000000..24d4dcf129 --- /dev/null +++ b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php @@ -0,0 +1,120 @@ +log = $log; + return $this; + } + + public function setHookEngine(DiffusionCommitHookEngine $engine) { + $this->hookEngine = $engine; + return $this; + } + + public function getAdapterApplicationClass() { + return 'PhabricatorApplicationDiffusion'; + } + + public function getObject() { + return $this->log; + } + + public function getAdapterContentName() { + return pht('Commit Hook: Commit Content'); + } + + public function getFieldNameMap() { + return array( + ) + parent::getFieldNameMap(); + } + + public function getFields() { + return array_merge( + array( + self::FIELD_REPOSITORY, + self::FIELD_PUSHER, + self::FIELD_PUSHER_PROJECTS, + self::FIELD_RULE, + ), + parent::getFields()); + } + + public function getConditionsForField($field) { + switch ($field) { + } + return parent::getConditionsForField($field); + } + + public function getActions($rule_type) { + switch ($rule_type) { + case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: + return array( + self::ACTION_BLOCK, + self::ACTION_NOTHING + ); + case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: + return array( + self::ACTION_NOTHING, + ); + } + } + + public function getValueTypeForFieldAndCondition($field, $condition) { + return parent::getValueTypeForFieldAndCondition($field, $condition); + } + + public function getPHID() { + return $this->getObject()->getPHID(); + } + + public function getHeraldName() { + return pht('Push Log'); + } + + public function getHeraldField($field) { + $log = $this->getObject(); + switch ($field) { + case self::FIELD_REPOSITORY: + return $this->hookEngine->getRepository()->getPHID(); + case self::FIELD_PUSHER: + return $this->hookEngine->getViewer()->getPHID(); + case self::FIELD_PUSHER_PROJECTS: + return $this->hookEngine->loadViewerProjectPHIDsForHerald(); + } + + return parent::getHeraldField($field); + } + + + public function applyHeraldEffects(array $effects) { + assert_instances_of($effects, 'HeraldEffect'); + + $result = array(); + foreach ($effects as $effect) { + $action = $effect->getAction(); + switch ($action) { + case self::ACTION_NOTHING: + $result[] = new HeraldApplyTranscript( + $effect, + true, + pht('Did nothing.')); + break; + case self::ACTION_BLOCK: + $result[] = new HeraldApplyTranscript( + $effect, + true, + pht('Blocked push.')); + break; + default: + throw new Exception(pht('No rules to handle action "%s"!', $action)); + } + } + + return $result; + } + +} diff --git a/src/applications/herald/storage/HeraldRule.php b/src/applications/herald/storage/HeraldRule.php index 140f57ee8d..877750fe29 100644 --- a/src/applications/herald/storage/HeraldRule.php +++ b/src/applications/herald/storage/HeraldRule.php @@ -16,7 +16,7 @@ final class HeraldRule extends HeraldDAO protected $ruleType; protected $isDisabled = 0; - protected $configVersion = 16; + protected $configVersion = 17; // phids for which this rule has been applied private $ruleApplied = self::ATTACHABLE;