From e8f063de25c1bdc5eccf83329d554f42008c8f44 Mon Sep 17 00:00:00 2001
From: epriestley <git@epriestley.com>
Date: Wed, 8 Jul 2015 12:26:57 -0700
Subject: [PATCH] Modularize Herald Diffusion pre-commit content fields

Summary: Ref T8726. The gruntwork part of this is finally over.

Test Plan:
  - Made a huge rule with every field.
  - Applied migration.
  - Verified the rule was still the same.
  - Pushed a bunch of commits and verified transcripts.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8726

Differential Revision: https://secure.phabricator.com/D13601
---
 .../sql/autopatches/20150708.herald.3.sql     | 146 +++++++++++
 src/__phutil_library_map__.php                |  44 ++++
 ...eCommitContentAffectedFilesHeraldField.php |  24 ++
 ...usionPreCommitContentAuthorHeraldField.php |  30 +++
 ...onPreCommitContentAuthorRawHeraldField.php |  24 ++
 ...ionPreCommitContentBranchesHeraldField.php |  24 ++
 ...onPreCommitContentCommitterHeraldField.php |  30 +++
 ...reCommitContentCommitterRawHeraldField.php |  24 ++
 ...mmitContentDiffContentAddedHeraldField.php |  24 ++
 ...PreCommitContentDiffContentHeraldField.php |  24 ++
 ...itContentDiffContentRemovedHeraldField.php |  24 ++
 ...reCommitContentDiffEnormousHeraldField.php |  24 ++
 .../DiffusionPreCommitContentHeraldField.php  |  17 ++
 ...fusionPreCommitContentMergeHeraldField.php |  24 ++
 ...sionPreCommitContentMessageHeraldField.php |  24 ++
 ...usionPreCommitContentPusherHeraldField.php |  24 ++
 ...mitContentPusherIsCommitterHeraldField.php |  27 +++
 ...CommitContentPusherProjectsHeraldField.php |  31 +++
 ...nPreCommitContentRepositoryHeraldField.php |  24 ++
 ...itContentRepositoryProjectsHeraldField.php |  32 +++
 ...mmitContentRevisionAcceptedHeraldField.php |  35 +++
 ...ionPreCommitContentRevisionHeraldField.php |  30 +++
 ...mitContentRevisionReviewersHeraldField.php |  36 +++
 ...tContentRevisionSubscribersHeraldField.php |  37 +++
 .../herald/HeraldPreCommitContentAdapter.php  | 119 +--------
 .../herald/adapter/HeraldAdapter.php          | 226 ++----------------
 26 files changed, 815 insertions(+), 313 deletions(-)
 create mode 100644 resources/sql/autopatches/20150708.herald.3.sql
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentRemovedHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentDiffEnormousHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryProjectsHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRevisionAcceptedHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRevisionHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRevisionReviewersHeraldField.php
 create mode 100644 src/applications/diffusion/herald/DiffusionPreCommitContentRevisionSubscribersHeraldField.php

diff --git a/resources/sql/autopatches/20150708.herald.3.sql b/resources/sql/autopatches/20150708.herald.3.sql
new file mode 100644
index 0000000000..2085941a7b
--- /dev/null
+++ b/resources/sql/autopatches/20150708.herald.3.sql
@@ -0,0 +1,146 @@
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.message'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'body';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.author'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'author';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.author.raw'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'author-raw';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.committer'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'committer';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.committer.raw'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'committer-raw';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.branches'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'branches';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.pusher'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'pusher';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.pusher.projects'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'pusher-projects';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.repository'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'repository';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.repository.projects'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'repository-projects';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.pusher.is-committer'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'pusher-is-committer';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.revision'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'differential-revision';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.revision.accepted'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'differential-accepted';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.revision.reviewers'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'differential-reviewers';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.revision.subscribers'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'differential-ccs';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.diff.enormous'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'diff-enormous';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.affected'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'diff-file';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.diff.content'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'diff-content';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.diff.new'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'diff-added-content';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.commit.diff.old'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'diff-removed-content';
+
+UPDATE {$NAMESPACE}_herald.herald_condition c
+  JOIN {$NAMESPACE}_herald.herald_rule r
+  ON c.ruleID = r.id
+  SET c.fieldName = 'diffusion.pre.content.merge'
+  WHERE r.contentType = 'HeraldPreCommitContentAdapter'
+  AND c.fieldName = 'is-merge-commit';
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 665235b544..c010916d8f 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -616,6 +616,28 @@ phutil_register_library_map(array(
     'DiffusionPathTreeController' => 'applications/diffusion/controller/DiffusionPathTreeController.php',
     'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php',
     'DiffusionPhpExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPhpExternalSymbolsSource.php',
+    'DiffusionPreCommitContentAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php',
+    'DiffusionPreCommitContentAuthorHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php',
+    'DiffusionPreCommitContentAuthorRawHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php',
+    'DiffusionPreCommitContentBranchesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php',
+    'DiffusionPreCommitContentCommitterHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php',
+    'DiffusionPreCommitContentCommitterRawHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php',
+    'DiffusionPreCommitContentDiffContentAddedHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php',
+    'DiffusionPreCommitContentDiffContentHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentDiffContentHeraldField.php',
+    'DiffusionPreCommitContentDiffContentRemovedHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentDiffContentRemovedHeraldField.php',
+    'DiffusionPreCommitContentDiffEnormousHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentDiffEnormousHeraldField.php',
+    'DiffusionPreCommitContentHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php',
+    'DiffusionPreCommitContentMergeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php',
+    'DiffusionPreCommitContentMessageHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php',
+    'DiffusionPreCommitContentPusherHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php',
+    'DiffusionPreCommitContentPusherIsCommitterHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php',
+    'DiffusionPreCommitContentPusherProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php',
+    'DiffusionPreCommitContentRepositoryHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRepositoryHeraldField.php',
+    'DiffusionPreCommitContentRepositoryProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRepositoryProjectsHeraldField.php',
+    'DiffusionPreCommitContentRevisionAcceptedHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRevisionAcceptedHeraldField.php',
+    'DiffusionPreCommitContentRevisionHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRevisionHeraldField.php',
+    'DiffusionPreCommitContentRevisionReviewersHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRevisionReviewersHeraldField.php',
+    'DiffusionPreCommitContentRevisionSubscribersHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentRevisionSubscribersHeraldField.php',
     'DiffusionPreCommitRefChangeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefChangeHeraldField.php',
     'DiffusionPreCommitRefHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefHeraldField.php',
     'DiffusionPreCommitRefNameHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefNameHeraldField.php',
@@ -4107,6 +4129,28 @@ phutil_register_library_map(array(
     'DiffusionPathTreeController' => 'DiffusionController',
     'DiffusionPathValidateController' => 'DiffusionController',
     'DiffusionPhpExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
+    'DiffusionPreCommitContentAffectedFilesHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentAuthorHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentAuthorRawHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentBranchesHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentCommitterHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentCommitterRawHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentDiffContentAddedHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentDiffContentHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentDiffContentRemovedHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentDiffEnormousHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentHeraldField' => 'HeraldField',
+    'DiffusionPreCommitContentMergeHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentMessageHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentPusherHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentPusherIsCommitterHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentPusherProjectsHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRepositoryHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRepositoryProjectsHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRevisionAcceptedHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRevisionHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRevisionReviewersHeraldField' => 'DiffusionPreCommitContentHeraldField',
+    'DiffusionPreCommitContentRevisionSubscribersHeraldField' => 'DiffusionPreCommitContentHeraldField',
     'DiffusionPreCommitRefChangeHeraldField' => 'DiffusionPreCommitRefHeraldField',
     'DiffusionPreCommitRefHeraldField' => 'HeraldField',
     'DiffusionPreCommitRefNameHeraldField' => 'DiffusionPreCommitRefHeraldField',
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php
new file mode 100644
index 0000000000..97a89b8422
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentAffectedFilesHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.affected';
+
+  public function getHeraldFieldName() {
+    return pht('Affected files');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getDiffContent('name');
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php
new file mode 100644
index 0000000000..50a55a043c
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php
@@ -0,0 +1,30 @@
+<?php
+
+final class DiffusionPreCommitContentAuthorHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.author';
+
+  public function getHeraldFieldName() {
+    return pht('Author');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getAuthorPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_PHID_NULLABLE;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_USER;
+    }
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php
new file mode 100644
index 0000000000..502eb1f0c4
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentAuthorRawHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.author.raw';
+
+  public function getHeraldFieldName() {
+    return pht('Raw Author');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getAuthorRaw();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php
new file mode 100644
index 0000000000..e64c2afaf3
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentBranchesHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.branches';
+
+  public function getHeraldFieldName() {
+    return pht('Branches');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getBranches();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php
new file mode 100644
index 0000000000..0f7c6543d3
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php
@@ -0,0 +1,30 @@
+<?php
+
+final class DiffusionPreCommitContentCommitterHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.committer';
+
+  public function getHeraldFieldName() {
+    return pht('Committer');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getCommitterPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_PHID_NULLABLE;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_USER;
+    }
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php
new file mode 100644
index 0000000000..fe9743317f
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentCommitterRawHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.committer.raw';
+
+  public function getHeraldFieldName() {
+    return pht('Raw Committer');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getCommitterRaw();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php
new file mode 100644
index 0000000000..1fa54c2fa8
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentDiffContentAddedHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.diff.new';
+
+  public function getHeraldFieldName() {
+    return pht('Added diff content');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getDiffContent('+');
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT_MAP;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentHeraldField.php
new file mode 100644
index 0000000000..6e7419a5f6
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentDiffContentHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.diff.content';
+
+  public function getHeraldFieldName() {
+    return pht('Diff content');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getDiffContent('*');
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT_MAP;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentRemovedHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentRemovedHeraldField.php
new file mode 100644
index 0000000000..72e044e23a
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffContentRemovedHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentDiffContentRemovedHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.diff.old';
+
+  public function getHeraldFieldName() {
+    return pht('Removed diff content');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getDiffContent('-');
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT_MAP;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentDiffEnormousHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffEnormousHeraldField.php
new file mode 100644
index 0000000000..d496dea3a1
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentDiffEnormousHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentDiffEnormousHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.diff.enormous';
+
+  public function getHeraldFieldName() {
+    return pht('Diff is enormous');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->isDiffEnormous();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_BOOL;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_NONE;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php
new file mode 100644
index 0000000000..0f323cc9c6
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php
@@ -0,0 +1,17 @@
+<?php
+
+abstract class DiffusionPreCommitContentHeraldField extends HeraldField {
+
+  public function supportsObject($object) {
+    if (!($object instanceof PhabricatorRepositoryPushLog)) {
+      return false;
+    }
+
+    if ($this->getAdapter()->isPreCommitRefAdapter()) {
+      return false;
+    }
+
+    return true;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php
new file mode 100644
index 0000000000..cc60173710
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentMergeHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.merge';
+
+  public function getHeraldFieldName() {
+    return pht('Is merge commit');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getIsMergeCommit();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_BOOL;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_NONE;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php
new file mode 100644
index 0000000000..e1ad9e59d4
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentMessageHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.commit.message';
+
+  public function getHeraldFieldName() {
+    return pht('Commit message');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getCommitRef()->getMessage();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_TEXT;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_TEXT;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php
new file mode 100644
index 0000000000..657c2a34c5
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentPusherHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.pusher';
+
+  public function getHeraldFieldName() {
+    return pht('Pusher');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getHookEngine()->getViewer()->getPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_PHID;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_USER;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php
new file mode 100644
index 0000000000..4904b6f39f
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php
@@ -0,0 +1,27 @@
+<?php
+
+final class DiffusionPreCommitContentPusherIsCommitterHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.pusher.is-committer';
+
+  public function getHeraldFieldName() {
+    return pht('Pusher is committer');
+  }
+
+  public function getHeraldFieldValue($object) {
+    $pusher = $this->getAdapter()->getHookEngine()->getViewer()->getPHID();
+    $committer = $this->getAdapter()->getCommitterPHID();
+
+    return ($pusher === $committer);
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_BOOL;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_NONE;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php
new file mode 100644
index 0000000000..61d3e06009
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php
@@ -0,0 +1,31 @@
+<?php
+
+final class DiffusionPreCommitContentPusherProjectsHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.pusher.projects';
+
+  public function getHeraldFieldName() {
+    return pht('Pusher projects');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()
+      ->getHookEngine()
+      ->loadViewerProjectPHIDsForHerald();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_PROJECT;
+    }
+  }
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryHeraldField.php
new file mode 100644
index 0000000000..c789b3e766
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryHeraldField.php
@@ -0,0 +1,24 @@
+<?php
+
+final class DiffusionPreCommitContentRepositoryHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.repository';
+
+  public function getHeraldFieldName() {
+    return pht('Repository');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return $this->getAdapter()->getHookEngine()->getRepository()->getPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_PHID;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_REPOSITORY;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryProjectsHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryProjectsHeraldField.php
new file mode 100644
index 0000000000..6053b92d9d
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRepositoryProjectsHeraldField.php
@@ -0,0 +1,32 @@
+<?php
+
+final class DiffusionPreCommitContentRepositoryProjectsHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.repository.projects';
+
+  public function getHeraldFieldName() {
+    return pht('Repository projects');
+  }
+
+  public function getHeraldFieldValue($object) {
+    return PhabricatorEdgeQuery::loadDestinationPHIDs(
+      $this->getAdapter()->getHookEngine()->getRepository()->getPHID(),
+      PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return HeraldField::STANDARD_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_PROJECT;
+    }
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionAcceptedHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionAcceptedHeraldField.php
new file mode 100644
index 0000000000..e060f7d1c8
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionAcceptedHeraldField.php
@@ -0,0 +1,35 @@
+<?php
+
+final class DiffusionPreCommitContentRevisionAcceptedHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.revision.accepted';
+
+  public function getHeraldFieldName() {
+    return pht('Accepted Differential revision');
+  }
+
+  public function getHeraldFieldValue($object) {
+    $revision = $this->getAdapter()->getRevision();
+
+    if (!$revision) {
+      return null;
+    }
+
+    $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
+    if ($revision->getStatus() != $status_accepted) {
+      return null;
+    }
+
+    return $revision->getPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_PHID_BOOL;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_NONE;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionHeraldField.php
new file mode 100644
index 0000000000..665d72f9d0
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionHeraldField.php
@@ -0,0 +1,30 @@
+<?php
+
+final class DiffusionPreCommitContentRevisionHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.revision';
+
+  public function getHeraldFieldName() {
+    return pht('Differential revision');
+  }
+
+  public function getHeraldFieldValue($object) {
+    $revision = $this->getAdapter()->getRevision();
+
+    if (!$revision) {
+      return null;
+    }
+
+    return $revision->getPHID();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_PHID_BOOL;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    return HeraldAdapter::VALUE_NONE;
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionReviewersHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionReviewersHeraldField.php
new file mode 100644
index 0000000000..c24751c3ea
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionReviewersHeraldField.php
@@ -0,0 +1,36 @@
+<?php
+
+final class DiffusionPreCommitContentRevisionReviewersHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.revision.reviewers';
+
+  public function getHeraldFieldName() {
+    return pht('Differential reviewers');
+  }
+
+  public function getHeraldFieldValue($object) {
+    $revision = $this->getAdapter()->getRevision();
+
+    if (!$revision) {
+      return array();
+    }
+
+    return $revision->getReviewers();
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_USER_OR_PROJECT;
+    }
+  }
+
+}
diff --git a/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionSubscribersHeraldField.php b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionSubscribersHeraldField.php
new file mode 100644
index 0000000000..0aaa043b5a
--- /dev/null
+++ b/src/applications/diffusion/herald/DiffusionPreCommitContentRevisionSubscribersHeraldField.php
@@ -0,0 +1,37 @@
+<?php
+
+final class DiffusionPreCommitContentRevisionSubscribersHeraldField
+  extends DiffusionPreCommitContentHeraldField {
+
+  const FIELDCONST = 'diffusion.pre.content.revision.subscribers';
+
+  public function getHeraldFieldName() {
+    return pht('Differential subscribers');
+  }
+
+  public function getHeraldFieldValue($object) {
+    $revision = $this->getAdapter()->getRevision();
+
+    if (!$revision) {
+      return array();
+    }
+
+    $phid = $revision->getPHID();
+    return PhabricatorSubscribersQuery::loadSubscribersForPHID($phid);
+  }
+
+  protected function getHeraldFieldStandardConditions() {
+    return self::STANDARD_LIST;
+  }
+
+  public function getHeraldFieldValueType($condition) {
+    switch ($condition) {
+      case HeraldAdapter::CONDITION_EXISTS:
+      case HeraldAdapter::CONDITION_NOT_EXISTS:
+        return HeraldAdapter::VALUE_NONE;
+      default:
+        return HeraldAdapter::VALUE_USER_OR_PROJECT;
+    }
+  }
+
+}
diff --git a/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php
index 05674eb230..3756651c7e 100644
--- a/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php
+++ b/src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php
@@ -25,111 +25,16 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     return false;
   }
 
-  public function getFields() {
-    return array_merge(
-      array(
-        self::FIELD_BODY,
-        self::FIELD_AUTHOR,
-        self::FIELD_AUTHOR_RAW,
-        self::FIELD_COMMITTER,
-        self::FIELD_COMMITTER_RAW,
-        self::FIELD_BRANCHES,
-        self::FIELD_DIFF_FILE,
-        self::FIELD_DIFF_CONTENT,
-        self::FIELD_DIFF_ADDED_CONTENT,
-        self::FIELD_DIFF_REMOVED_CONTENT,
-        self::FIELD_DIFF_ENORMOUS,
-        self::FIELD_REPOSITORY,
-        self::FIELD_REPOSITORY_PROJECTS,
-        self::FIELD_PUSHER,
-        self::FIELD_PUSHER_PROJECTS,
-        self::FIELD_PUSHER_IS_COMMITTER,
-        self::FIELD_DIFFERENTIAL_REVISION,
-        self::FIELD_DIFFERENTIAL_ACCEPTED,
-        self::FIELD_DIFFERENTIAL_REVIEWERS,
-        self::FIELD_DIFFERENTIAL_CCS,
-        self::FIELD_IS_MERGE_COMMIT,
-      ),
-      parent::getFields());
-  }
-
   public function getHeraldName() {
     return pht('Push Log (Content)');
   }
 
-  public function getHeraldField($field) {
-    $log = $this->getObject();
-    switch ($field) {
-      case self::FIELD_BODY:
-        return $this->getCommitRef()->getMessage();
-      case self::FIELD_AUTHOR:
-        return $this->getAuthorPHID();
-      case self::FIELD_AUTHOR_RAW:
-        return $this->getAuthorRaw();
-      case self::FIELD_COMMITTER:
-        return $this->getCommitterPHID();
-      case self::FIELD_COMMITTER_RAW:
-        return $this->getCommitterRaw();
-      case self::FIELD_BRANCHES:
-        return $this->getBranches();
-      case self::FIELD_DIFF_FILE:
-        return $this->getDiffContent('name');
-      case self::FIELD_DIFF_CONTENT:
-        return $this->getDiffContent('*');
-      case self::FIELD_DIFF_ADDED_CONTENT:
-        return $this->getDiffContent('+');
-      case self::FIELD_DIFF_REMOVED_CONTENT:
-        return $this->getDiffContent('-');
-      case self::FIELD_DIFF_ENORMOUS:
-        $this->getDiffContent('*');
-        return ($this->changesets instanceof Exception);
-      case self::FIELD_REPOSITORY:
-        return $this->getHookEngine()->getRepository()->getPHID();
-      case self::FIELD_REPOSITORY_PROJECTS:
-        return $this->getHookEngine()->getRepository()->getProjectPHIDs();
-      case self::FIELD_PUSHER:
-        return $this->getHookEngine()->getViewer()->getPHID();
-      case self::FIELD_PUSHER_PROJECTS:
-        return $this->getHookEngine()->loadViewerProjectPHIDsForHerald();
-      case self::FIELD_DIFFERENTIAL_REVISION:
-        $revision = $this->getRevision();
-        if (!$revision) {
-          return null;
-        }
-        return $revision->getPHID();
-      case self::FIELD_DIFFERENTIAL_ACCEPTED:
-        $revision = $this->getRevision();
-        if (!$revision) {
-          return null;
-        }
-        $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
-        if ($revision->getStatus() != $status_accepted) {
-          return null;
-        }
-        return $revision->getPHID();
-      case self::FIELD_DIFFERENTIAL_REVIEWERS:
-        $revision = $this->getRevision();
-        if (!$revision) {
-          return array();
-        }
-        return $revision->getReviewers();
-      case self::FIELD_DIFFERENTIAL_CCS:
-        $revision = $this->getRevision();
-        if (!$revision) {
-          return array();
-        }
-        return $revision->getCCPHIDs();
-      case self::FIELD_IS_MERGE_COMMIT:
-        return $this->getIsMergeCommit();
-      case self::FIELD_PUSHER_IS_COMMITTER:
-        $pusher_phid = $this->getHookEngine()->getViewer()->getPHID();
-        return ($this->getCommitterPHID() == $pusher_phid);
-    }
-
-    return parent::getHeraldField($field);
+  public function isDiffEnormous() {
+    $this->getDiffContent('*');
+    return ($this->changesets instanceof Exception);
   }
 
-  private function getDiffContent($type) {
+  public function getDiffContent($type) {
     if ($this->changesets === null) {
       try {
         $this->changesets = $this->getHookEngine()->loadChangesetsForCommit(
@@ -178,7 +83,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     return $result;
   }
 
-  private function getCommitRef() {
+  public function getCommitRef() {
     if ($this->commitRef === null) {
       $this->commitRef = $this->getHookEngine()->loadCommitRefForCommit(
         $this->getObject()->getRefNew());
@@ -186,7 +91,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     return $this->commitRef;
   }
 
-  private function getAuthorPHID() {
+  public function getAuthorPHID() {
     $repository = $this->getHookEngine()->getRepository();
     $vcs = $repository->getVersionControlSystem();
     switch ($vcs) {
@@ -204,7 +109,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     }
   }
 
-  private function getCommitterPHID() {
+  public function getCommitterPHID() {
     $repository = $this->getHookEngine()->getRepository();
     $vcs = $repository->getVersionControlSystem();
     switch ($vcs) {
@@ -225,7 +130,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     }
   }
 
-  private function getAuthorRaw() {
+  public function getAuthorRaw() {
     $repository = $this->getHookEngine()->getRepository();
     $vcs = $repository->getVersionControlSystem();
     switch ($vcs) {
@@ -239,7 +144,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     }
   }
 
-  private function getCommitterRaw() {
+  public function getCommitterRaw() {
     $repository = $this->getHookEngine()->getRepository();
     $vcs = $repository->getVersionControlSystem();
     switch ($vcs) {
@@ -275,7 +180,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     return $this->fields;
   }
 
-  private function getRevision() {
+  public function getRevision() {
     if ($this->revision === false) {
       $fields = $this->getCommitFields();
       $revision_id = idx($fields, 'revisionID');
@@ -293,7 +198,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     return $this->revision;
   }
 
-  private function getIsMergeCommit() {
+  public function getIsMergeCommit() {
     $repository = $this->getHookEngine()->getRepository();
     $vcs = $repository->getVersionControlSystem();
     switch ($vcs) {
@@ -313,7 +218,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
     }
   }
 
-  private function getBranches() {
+  public function getBranches() {
     return $this->getHookEngine()->loadBranches(
       $this->getObject()->getRefNew());
   }
diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php
index d6f0aa007a..31b5863dde 100644
--- a/src/applications/herald/adapter/HeraldAdapter.php
+++ b/src/applications/herald/adapter/HeraldAdapter.php
@@ -2,33 +2,6 @@
 
 abstract class HeraldAdapter extends Phobject {
 
-  const FIELD_TITLE                  = 'title';
-  const FIELD_BODY                   = 'body';
-  const FIELD_AUTHOR                 = 'author';
-  const FIELD_REVIEWER               = 'reviewer';
-  const FIELD_COMMITTER              = 'committer';
-  const FIELD_DIFF_FILE              = 'diff-file';
-  const FIELD_DIFF_CONTENT           = 'diff-content';
-  const FIELD_DIFF_ADDED_CONTENT     = 'diff-added-content';
-  const FIELD_DIFF_REMOVED_CONTENT   = 'diff-removed-content';
-  const FIELD_DIFF_ENORMOUS          = 'diff-enormous';
-  const FIELD_REPOSITORY             = 'repository';
-  const FIELD_REPOSITORY_PROJECTS    = 'repository-projects';
-  const FIELD_AFFECTED_PACKAGE       = 'affected-package';
-  const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
-  const FIELD_AUTHOR_PROJECTS        = 'authorprojects';
-  const FIELD_PUSHER                 = 'pusher';
-  const FIELD_PUSHER_PROJECTS        = 'pusher-projects';
-  const FIELD_DIFFERENTIAL_REVISION  = 'differential-revision';
-  const FIELD_DIFFERENTIAL_REVIEWERS = 'differential-reviewers';
-  const FIELD_DIFFERENTIAL_CCS       = 'differential-ccs';
-  const FIELD_DIFFERENTIAL_ACCEPTED  = 'differential-accepted';
-  const FIELD_IS_MERGE_COMMIT        = 'is-merge-commit';
-  const FIELD_BRANCHES               = 'branches';
-  const FIELD_AUTHOR_RAW             = 'author-raw';
-  const FIELD_COMMITTER_RAW          = 'committer-raw';
-  const FIELD_PUSHER_IS_COMMITTER    = 'pusher-is-committer';
-
   const CONDITION_CONTAINS        = 'contains';
   const CONDITION_NOT_CONTAINS    = '!contains';
   const CONDITION_IS              = 'is';
@@ -178,13 +151,9 @@ abstract class HeraldAdapter extends Phobject {
 
   abstract public function getHeraldName();
 
-  public function getHeraldField($field_name) {
-    $impl = $this->getFieldImplementation($field_name);
-    if ($impl) {
-      return $impl->getHeraldFieldValue($this->getObject());
-    }
-
-    throw new Exception(pht("Unknown field '%s'!", $field_name));
+  public function getHeraldField($field_key) {
+    return $this->requireFieldImplementation($field_key)
+      ->getHeraldFieldValue($this->getObject());
   }
 
   public function applyHeraldEffects(array $effects) {
@@ -358,38 +327,7 @@ abstract class HeraldAdapter extends Phobject {
   }
 
   public function getFieldNameMap() {
-    $map = mpull($this->getFieldImplementationMap(), 'getHeraldFieldName');
-
-    return $map + array(
-      self::FIELD_TITLE => pht('Title'),
-      self::FIELD_BODY => pht('Body'),
-      self::FIELD_AUTHOR => pht('Author'),
-      self::FIELD_COMMITTER => pht('Committer'),
-      self::FIELD_REVIEWER => pht('Reviewer'),
-      self::FIELD_DIFF_FILE => pht('Any changed filename'),
-      self::FIELD_DIFF_CONTENT => pht('Any changed file content'),
-      self::FIELD_DIFF_ADDED_CONTENT => pht('Any added file content'),
-      self::FIELD_DIFF_REMOVED_CONTENT => pht('Any removed file content'),
-      self::FIELD_DIFF_ENORMOUS => pht('Change is enormous'),
-      self::FIELD_REPOSITORY => pht('Repository'),
-      self::FIELD_REPOSITORY_PROJECTS => pht('Repository\'s projects'),
-      self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
-      self::FIELD_AFFECTED_PACKAGE_OWNER =>
-        pht("Any affected package's owner"),
-      self::FIELD_AUTHOR_PROJECTS => pht("Author's projects"),
-      self::FIELD_PUSHER => pht('Pusher'),
-      self::FIELD_PUSHER_PROJECTS => pht("Pusher's projects"),
-      self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'),
-      self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'),
-      self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'),
-      self::FIELD_DIFFERENTIAL_ACCEPTED
-        => pht('Accepted Differential revision'),
-      self::FIELD_IS_MERGE_COMMIT => pht('Commit is a merge'),
-      self::FIELD_BRANCHES => pht('Commit\'s branches'),
-      self::FIELD_AUTHOR_RAW => pht('Raw author name'),
-      self::FIELD_COMMITTER_RAW => pht('Raw committer name'),
-      self::FIELD_PUSHER_IS_COMMITTER => pht('Pusher same as committer'),
-    );
+    return mpull($this->getFieldImplementationMap(), 'getHeraldFieldName');
   }
 
 
@@ -425,97 +363,22 @@ abstract class HeraldAdapter extends Phobject {
   }
 
   public function getConditionsForField($field) {
-    $impl = $this->getFieldImplementation($field);
-    if ($impl) {
-      return $impl->getHeraldFieldConditions();
-    }
+    return $this->requireFieldImplementation($field)
+      ->getHeraldFieldConditions();
+  }
 
-    switch ($field) {
-      case self::FIELD_TITLE:
-      case self::FIELD_BODY:
-      case self::FIELD_COMMITTER_RAW:
-      case self::FIELD_AUTHOR_RAW:
-        return array(
-          self::CONDITION_CONTAINS,
-          self::CONDITION_NOT_CONTAINS,
-          self::CONDITION_IS,
-          self::CONDITION_IS_NOT,
-          self::CONDITION_REGEXP,
-        );
-      case self::FIELD_REVIEWER:
-      case self::FIELD_PUSHER:
-        return array(
-          self::CONDITION_IS_ANY,
-          self::CONDITION_IS_NOT_ANY,
-        );
-      case self::FIELD_REPOSITORY:
-      case self::FIELD_AUTHOR:
-      case self::FIELD_COMMITTER:
-        return array(
-          self::CONDITION_IS_ANY,
-          self::CONDITION_IS_NOT_ANY,
-          self::CONDITION_EXISTS,
-          self::CONDITION_NOT_EXISTS,
-        );
-      case self::FIELD_AUTHOR_PROJECTS:
-      case self::FIELD_AFFECTED_PACKAGE:
-      case self::FIELD_AFFECTED_PACKAGE_OWNER:
-      case self::FIELD_PUSHER_PROJECTS:
-      case self::FIELD_REPOSITORY_PROJECTS:
-        return array(
-          self::CONDITION_INCLUDE_ALL,
-          self::CONDITION_INCLUDE_ANY,
-          self::CONDITION_INCLUDE_NONE,
-          self::CONDITION_EXISTS,
-          self::CONDITION_NOT_EXISTS,
-        );
-      case self::FIELD_DIFF_FILE:
-      case self::FIELD_BRANCHES:
-        return array(
-          self::CONDITION_CONTAINS,
-          self::CONDITION_REGEXP,
-        );
-      case self::FIELD_DIFF_CONTENT:
-      case self::FIELD_DIFF_ADDED_CONTENT:
-      case self::FIELD_DIFF_REMOVED_CONTENT:
-        return array(
-          self::CONDITION_CONTAINS,
-          self::CONDITION_REGEXP,
-          self::CONDITION_REGEXP_PAIR,
-        );
-      case self::FIELD_DIFFERENTIAL_REVIEWERS:
-        return array(
-          self::CONDITION_EXISTS,
-          self::CONDITION_NOT_EXISTS,
-          self::CONDITION_INCLUDE_ALL,
-          self::CONDITION_INCLUDE_ANY,
-          self::CONDITION_INCLUDE_NONE,
-        );
-      case self::FIELD_DIFFERENTIAL_CCS:
-        return array(
-          self::CONDITION_INCLUDE_ALL,
-          self::CONDITION_INCLUDE_ANY,
-          self::CONDITION_INCLUDE_NONE,
-        );
-      case self::FIELD_DIFFERENTIAL_REVISION:
-      case self::FIELD_DIFFERENTIAL_ACCEPTED:
-        return array(
-          self::CONDITION_EXISTS,
-          self::CONDITION_NOT_EXISTS,
-        );
-      case self::FIELD_IS_MERGE_COMMIT:
-      case self::FIELD_DIFF_ENORMOUS:
-      case self::FIELD_PUSHER_IS_COMMITTER:
-        return array(
-          self::CONDITION_IS_TRUE,
-          self::CONDITION_IS_FALSE,
-        );
-      default:
-        throw new Exception(
-          pht(
-            "This adapter does not define conditions for field '%s'!",
-            $field));
+  private function requireFieldImplementation($field_key) {
+    $field = $this->getFieldImplementation($field_key);
+
+    if (!$field) {
+      throw new Exception(
+        pht(
+          'No field with key "%s" is available to Herald adapter "%s".',
+          $field_key,
+          get_class($this)));
     }
+
+    return $field;
   }
 
   public function doesConditionMatch(
@@ -884,57 +747,8 @@ abstract class HeraldAdapter extends Phobject {
 
 
   public function getValueTypeForFieldAndCondition($field, $condition) {
-    $impl = $this->getFieldImplementation($field);
-    if ($impl) {
-      return $impl->getHeraldFieldValueType($condition);
-    }
-
-    switch ($condition) {
-      case self::CONDITION_CONTAINS:
-      case self::CONDITION_NOT_CONTAINS:
-      case self::CONDITION_REGEXP:
-      case self::CONDITION_REGEXP_PAIR:
-        return self::VALUE_TEXT;
-      case self::CONDITION_IS:
-      case self::CONDITION_IS_NOT:
-        return self::VALUE_TEXT;
-      case self::CONDITION_IS_ANY:
-      case self::CONDITION_IS_NOT_ANY:
-        switch ($field) {
-          case self::FIELD_REPOSITORY:
-            return self::VALUE_REPOSITORY;
-          default:
-            return self::VALUE_USER;
-        }
-        break;
-      case self::CONDITION_INCLUDE_ALL:
-      case self::CONDITION_INCLUDE_ANY:
-      case self::CONDITION_INCLUDE_NONE:
-        switch ($field) {
-          case self::FIELD_REPOSITORY:
-            return self::VALUE_REPOSITORY;
-          case self::FIELD_AFFECTED_PACKAGE:
-            return self::VALUE_OWNERS_PACKAGE;
-          case self::FIELD_AUTHOR_PROJECTS:
-          case self::FIELD_PUSHER_PROJECTS:
-          case self::FIELD_REPOSITORY_PROJECTS:
-            return self::VALUE_PROJECT;
-          default:
-            return self::VALUE_USER;
-        }
-        break;
-      case self::CONDITION_IS_ME:
-      case self::CONDITION_IS_NOT_ME:
-      case self::CONDITION_EXISTS:
-      case self::CONDITION_NOT_EXISTS:
-      case self::CONDITION_UNCONDITIONALLY:
-      case self::CONDITION_NEVER:
-      case self::CONDITION_IS_TRUE:
-      case self::CONDITION_IS_FALSE:
-        return self::VALUE_NONE;
-      default:
-        throw new Exception(pht("Unknown condition '%s'.", $condition));
-    }
+    return $this->requireFieldImplementation($field)
+      ->getHeraldFieldValueType($condition);
   }
 
   public function getValueTypeForAction($action, $rule_type) {
-- 
GitLab