Provide basic commit content hooks for Herald
Summary: Ref T4195. This doesn't provide any interesting fields yet (content, affected paths, commit message) but fires the hook correctly. Test Plan: Added a blocking hook and saw it fire. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4195 Differential Revision: https://secure.phabricator.com/D7789
This commit is contained in:
		| @@ -756,6 +756,7 @@ phutil_register_library_map(array( | |||||||
|     'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php', |     'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php', | ||||||
|     'HeraldPHIDTypeRule' => 'applications/herald/phid/HeraldPHIDTypeRule.php', |     'HeraldPHIDTypeRule' => 'applications/herald/phid/HeraldPHIDTypeRule.php', | ||||||
|     'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php', |     'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php', | ||||||
|  |     'HeraldPreCommitContentAdapter' => 'applications/diffusion/herald/HeraldPreCommitContentAdapter.php', | ||||||
|     'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php', |     'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php', | ||||||
|     'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php', |     'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php', | ||||||
|     'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php', |     'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php', | ||||||
| @@ -3180,6 +3181,7 @@ phutil_register_library_map(array( | |||||||
|     'HeraldNewController' => 'HeraldController', |     'HeraldNewController' => 'HeraldController', | ||||||
|     'HeraldPHIDTypeRule' => 'PhabricatorPHIDType', |     'HeraldPHIDTypeRule' => 'PhabricatorPHIDType', | ||||||
|     'HeraldPholioMockAdapter' => 'HeraldAdapter', |     'HeraldPholioMockAdapter' => 'HeraldAdapter', | ||||||
|  |     'HeraldPreCommitContentAdapter' => 'HeraldAdapter', | ||||||
|     'HeraldPreCommitRefAdapter' => 'HeraldAdapter', |     'HeraldPreCommitRefAdapter' => 'HeraldAdapter', | ||||||
|     'HeraldRecursiveConditionsException' => 'Exception', |     'HeraldRecursiveConditionsException' => 'Exception', | ||||||
|     'HeraldRemarkupRule' => 'PhabricatorRemarkupRuleObject', |     'HeraldRemarkupRule' => 'PhabricatorRemarkupRuleObject', | ||||||
|   | |||||||
| @@ -132,12 +132,13 @@ final class DiffusionCommitHookEngine extends Phobject { | |||||||
|         throw $ex; |         throw $ex; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       $this->applyHeraldRefRules($ref_updates); |       $this->applyHeraldRefRules($ref_updates, $all_updates); | ||||||
|  |  | ||||||
|       $content_updates = $this->findContentUpdates($ref_updates); |       $content_updates = $this->findContentUpdates($ref_updates); | ||||||
|       $all_updates = array_merge($all_updates, $content_updates); |       $all_updates = array_merge($all_updates, $content_updates); | ||||||
|  |  | ||||||
|       // TODO: Fire content Herald rules. |       $this->applyHeraldContentRules($content_updates, $all_updates); | ||||||
|  |  | ||||||
|       // TODO: Fire external hooks. |       // TODO: Fire external hooks. | ||||||
|  |  | ||||||
|       // If we make it this far, we're accepting these changes. Mark all the |       // If we make it this far, we're accepting these changes. Mark all the | ||||||
| @@ -225,19 +226,41 @@ final class DiffusionCommitHookEngine extends Phobject { | |||||||
|  |  | ||||||
| /* -(  Herald  )------------------------------------------------------------- */ | /* -(  Herald  )------------------------------------------------------------- */ | ||||||
|  |  | ||||||
|  |   private function applyHeraldRefRules( | ||||||
|  |     array $ref_updates, | ||||||
|  |     array $all_updates) { | ||||||
|  |     $this->applyHeraldRules( | ||||||
|  |       $ref_updates, | ||||||
|  |       new HeraldPreCommitRefAdapter(), | ||||||
|  |       $all_updates); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   private function applyHeraldRefRules(array $ref_updates) { |   private function applyHeraldContentRules( | ||||||
|     if (!$ref_updates) { |     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; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     $adapter_template->setHookEngine($this); | ||||||
|  |  | ||||||
|     $engine = new HeraldEngine(); |     $engine = new HeraldEngine(); | ||||||
|     $rules = null; |     $rules = null; | ||||||
|     $blocking_effect = null; |     $blocking_effect = null; | ||||||
|     foreach ($ref_updates as $ref_update) { |     foreach ($updates as $update) { | ||||||
|       $adapter = id(new HeraldPreCommitRefAdapter()) |       $adapter = id(clone $adapter_template) | ||||||
|         ->setPushLog($ref_update) |         ->setPushLog($update); | ||||||
|         ->setHookEngine($this); |  | ||||||
|  |  | ||||||
|       if ($rules === null) { |       if ($rules === null) { | ||||||
|         $rules = $engine->loadRulesForAdapter($adapter); |         $rules = $engine->loadRulesForAdapter($adapter); | ||||||
| @@ -258,9 +281,9 @@ final class DiffusionCommitHookEngine extends Phobject { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if ($blocking_effect) { |     if ($blocking_effect) { | ||||||
|       foreach ($ref_updates as $ref_update) { |       foreach ($all_updates as $update) { | ||||||
|         $ref_update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD); |         $update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD); | ||||||
|         $ref_update->setRejectDetails($blocking_effect->getRulePHID()); |         $update->setRejectDetails($blocking_effect->getRulePHID()); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       $message = $blocking_effect->getTarget(); |       $message = $blocking_effect->getTarget(); | ||||||
|   | |||||||
| @@ -0,0 +1,120 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class HeraldPreCommitContentAdapter extends HeraldAdapter { | ||||||
|  |  | ||||||
|  |   private $log; | ||||||
|  |   private $hookEngine; | ||||||
|  |  | ||||||
|  |   public function setPushLog(PhabricatorRepositoryPushLog $log) { | ||||||
|  |     $this->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; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -16,7 +16,7 @@ final class HeraldRule extends HeraldDAO | |||||||
|   protected $ruleType; |   protected $ruleType; | ||||||
|   protected $isDisabled = 0; |   protected $isDisabled = 0; | ||||||
|  |  | ||||||
|   protected $configVersion = 16; |   protected $configVersion = 17; | ||||||
|  |  | ||||||
|   // phids for which this rule has been applied |   // phids for which this rule has been applied | ||||||
|   private $ruleApplied = self::ATTACHABLE; |   private $ruleApplied = self::ATTACHABLE; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley