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', | ||||
|     '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', | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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 $isDisabled = 0; | ||||
|  | ||||
|   protected $configVersion = 16; | ||||
|   protected $configVersion = 17; | ||||
|  | ||||
|   // phids for which this rule has been applied | ||||
|   private $ruleApplied = self::ATTACHABLE; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley