Page MenuHomePhabricator

D17058.diff
No OneTemporary

D17058.diff

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
@@ -353,8 +353,10 @@
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
'DifferentialApplyPatchField' => 'applications/differential/customfield/DifferentialApplyPatchField.php',
'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php',
+ 'DifferentialAuditorsCommitMessageField' => 'applications/differential/field/DifferentialAuditorsCommitMessageField.php',
'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php',
'DifferentialAuthorField' => 'applications/differential/customfield/DifferentialAuthorField.php',
+ 'DifferentialBlameRevisionCommitMessageField' => 'applications/differential/field/DifferentialBlameRevisionCommitMessageField.php',
'DifferentialBlameRevisionField' => 'applications/differential/customfield/DifferentialBlameRevisionField.php',
'DifferentialBlockHeraldAction' => 'applications/differential/herald/DifferentialBlockHeraldAction.php',
'DifferentialBlockingReviewerDatasource' => 'applications/differential/typeahead/DifferentialBlockingReviewerDatasource.php',
@@ -383,10 +385,12 @@
'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php',
'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
+ 'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php',
'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php',
'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php',
'DifferentialCommitsField' => 'applications/differential/customfield/DifferentialCommitsField.php',
'DifferentialConduitAPIMethod' => 'applications/differential/conduit/DifferentialConduitAPIMethod.php',
+ 'DifferentialConflictsCommitMessageField' => 'applications/differential/field/DifferentialConflictsCommitMessageField.php',
'DifferentialConflictsField' => 'applications/differential/customfield/DifferentialConflictsField.php',
'DifferentialController' => 'applications/differential/controller/DifferentialController.php',
'DifferentialCoreCustomField' => 'applications/differential/customfield/DifferentialCoreCustomField.php',
@@ -444,6 +448,7 @@
'DifferentialGetRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetRevisionConduitAPIMethod.php',
'DifferentialGetWorkingCopy' => 'applications/differential/DifferentialGetWorkingCopy.php',
'DifferentialGitHubLandingStrategy' => 'applications/differential/landing/DifferentialGitHubLandingStrategy.php',
+ 'DifferentialGitSVNIDCommitMessageField' => 'applications/differential/field/DifferentialGitSVNIDCommitMessageField.php',
'DifferentialGitSVNIDField' => 'applications/differential/customfield/DifferentialGitSVNIDField.php',
'DifferentialHarbormasterField' => 'applications/differential/customfield/DifferentialHarbormasterField.php',
'DifferentialHiddenComment' => 'applications/differential/storage/DifferentialHiddenComment.php',
@@ -461,6 +466,7 @@
'DifferentialInlineCommentMailView' => 'applications/differential/mail/DifferentialInlineCommentMailView.php',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/DifferentialInlineCommentPreviewController.php',
'DifferentialInlineCommentQuery' => 'applications/differential/query/DifferentialInlineCommentQuery.php',
+ 'DifferentialJIRAIssuesCommitMessageField' => 'applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php',
'DifferentialJIRAIssuesField' => 'applications/differential/customfield/DifferentialJIRAIssuesField.php',
'DifferentialLandingActionMenuEventListener' => 'applications/differential/landing/DifferentialLandingActionMenuEventListener.php',
'DifferentialLandingStrategy' => 'applications/differential/landing/DifferentialLandingStrategy.php',
@@ -493,7 +499,9 @@
'DifferentialResponsibleDatasource' => 'applications/differential/typeahead/DifferentialResponsibleDatasource.php',
'DifferentialResponsibleUserDatasource' => 'applications/differential/typeahead/DifferentialResponsibleUserDatasource.php',
'DifferentialResponsibleViewerFunctionDatasource' => 'applications/differential/typeahead/DifferentialResponsibleViewerFunctionDatasource.php',
+ 'DifferentialRevertPlanCommitMessageField' => 'applications/differential/field/DifferentialRevertPlanCommitMessageField.php',
'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php',
+ 'DifferentialReviewedByCommitMessageField' => 'applications/differential/field/DifferentialReviewedByCommitMessageField.php',
'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php',
'DifferentialReviewerDatasource' => 'applications/differential/typeahead/DifferentialReviewerDatasource.php',
'DifferentialReviewerForRevisionEdgeType' => 'applications/differential/edge/DifferentialReviewerForRevisionEdgeType.php',
@@ -503,6 +511,7 @@
'DifferentialReviewersAddBlockingSelfHeraldAction' => 'applications/differential/herald/DifferentialReviewersAddBlockingSelfHeraldAction.php',
'DifferentialReviewersAddReviewersHeraldAction' => 'applications/differential/herald/DifferentialReviewersAddReviewersHeraldAction.php',
'DifferentialReviewersAddSelfHeraldAction' => 'applications/differential/herald/DifferentialReviewersAddSelfHeraldAction.php',
+ 'DifferentialReviewersCommitMessageField' => 'applications/differential/field/DifferentialReviewersCommitMessageField.php',
'DifferentialReviewersField' => 'applications/differential/customfield/DifferentialReviewersField.php',
'DifferentialReviewersHeraldAction' => 'applications/differential/herald/DifferentialReviewersHeraldAction.php',
'DifferentialReviewersView' => 'applications/differential/view/DifferentialReviewersView.php',
@@ -530,6 +539,7 @@
'DifferentialRevisionHasTaskRelationship' => 'applications/differential/relationships/DifferentialRevisionHasTaskRelationship.php',
'DifferentialRevisionHeraldField' => 'applications/differential/herald/DifferentialRevisionHeraldField.php',
'DifferentialRevisionHeraldFieldGroup' => 'applications/differential/herald/DifferentialRevisionHeraldFieldGroup.php',
+ 'DifferentialRevisionIDCommitMessageField' => 'applications/differential/field/DifferentialRevisionIDCommitMessageField.php',
'DifferentialRevisionIDField' => 'applications/differential/customfield/DifferentialRevisionIDField.php',
'DifferentialRevisionLandController' => 'applications/differential/controller/DifferentialRevisionLandController.php',
'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php',
@@ -563,9 +573,15 @@
'DifferentialSchemaSpec' => 'applications/differential/storage/DifferentialSchemaSpec.php',
'DifferentialSetDiffPropertyConduitAPIMethod' => 'applications/differential/conduit/DifferentialSetDiffPropertyConduitAPIMethod.php',
'DifferentialStoredCustomField' => 'applications/differential/customfield/DifferentialStoredCustomField.php',
+ 'DifferentialSubscribersCommitMessageField' => 'applications/differential/field/DifferentialSubscribersCommitMessageField.php',
'DifferentialSubscribersField' => 'applications/differential/customfield/DifferentialSubscribersField.php',
+ 'DifferentialSummaryCommitMessageField' => 'applications/differential/field/DifferentialSummaryCommitMessageField.php',
'DifferentialSummaryField' => 'applications/differential/customfield/DifferentialSummaryField.php',
+ 'DifferentialTagsCommitMessageField' => 'applications/differential/field/DifferentialTagsCommitMessageField.php',
+ 'DifferentialTasksCommitMessageField' => 'applications/differential/field/DifferentialTasksCommitMessageField.php',
+ 'DifferentialTestPlanCommitMessageField' => 'applications/differential/field/DifferentialTestPlanCommitMessageField.php',
'DifferentialTestPlanField' => 'applications/differential/customfield/DifferentialTestPlanField.php',
+ 'DifferentialTitleCommitMessageField' => 'applications/differential/field/DifferentialTitleCommitMessageField.php',
'DifferentialTitleField' => 'applications/differential/customfield/DifferentialTitleField.php',
'DifferentialTransaction' => 'applications/differential/storage/DifferentialTransaction.php',
'DifferentialTransactionComment' => 'applications/differential/storage/DifferentialTransactionComment.php',
@@ -4976,8 +4992,10 @@
'DifferentialAffectedPath' => 'DifferentialDAO',
'DifferentialApplyPatchField' => 'DifferentialCustomField',
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
+ 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
'DifferentialAuthorField' => 'DifferentialCustomField',
+ 'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField',
'DifferentialBlockHeraldAction' => 'HeraldAction',
'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
@@ -5009,10 +5027,12 @@
'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
+ 'DifferentialCommitMessageField' => 'Phobject',
'DifferentialCommitMessageParser' => 'Phobject',
'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase',
'DifferentialCommitsField' => 'DifferentialCustomField',
'DifferentialConduitAPIMethod' => 'ConduitAPIMethod',
+ 'DifferentialConflictsCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialConflictsField' => 'DifferentialCustomField',
'DifferentialController' => 'PhabricatorController',
'DifferentialCoreCustomField' => 'DifferentialCustomField',
@@ -5077,6 +5097,7 @@
'DifferentialGetRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
'DifferentialGetWorkingCopy' => 'Phobject',
'DifferentialGitHubLandingStrategy' => 'DifferentialLandingStrategy',
+ 'DifferentialGitSVNIDCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialGitSVNIDField' => 'DifferentialCustomField',
'DifferentialHarbormasterField' => 'DifferentialCustomField',
'DifferentialHiddenComment' => 'DifferentialDAO',
@@ -5100,6 +5121,7 @@
'DifferentialInlineCommentMailView' => 'DifferentialMailView',
'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
+ 'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener',
'DifferentialLandingStrategy' => 'Phobject',
@@ -5132,7 +5154,9 @@
'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource',
+ 'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
+ 'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
'DifferentialReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialReviewerForRevisionEdgeType' => 'PhabricatorEdgeType',
@@ -5142,6 +5166,7 @@
'DifferentialReviewersAddBlockingSelfHeraldAction' => 'DifferentialReviewersHeraldAction',
'DifferentialReviewersAddReviewersHeraldAction' => 'DifferentialReviewersHeraldAction',
'DifferentialReviewersAddSelfHeraldAction' => 'DifferentialReviewersHeraldAction',
+ 'DifferentialReviewersCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialReviewersField' => 'DifferentialCoreCustomField',
'DifferentialReviewersHeraldAction' => 'HeraldAction',
'DifferentialReviewersView' => 'AphrontView',
@@ -5185,6 +5210,7 @@
'DifferentialRevisionHasTaskRelationship' => 'DifferentialRevisionRelationship',
'DifferentialRevisionHeraldField' => 'HeraldField',
'DifferentialRevisionHeraldFieldGroup' => 'HeraldFieldGroup',
+ 'DifferentialRevisionIDCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialRevisionIDField' => 'DifferentialCustomField',
'DifferentialRevisionLandController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
@@ -5218,9 +5244,15 @@
'DifferentialSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'DifferentialSetDiffPropertyConduitAPIMethod' => 'DifferentialConduitAPIMethod',
'DifferentialStoredCustomField' => 'DifferentialCustomField',
+ 'DifferentialSubscribersCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialSubscribersField' => 'DifferentialCoreCustomField',
+ 'DifferentialSummaryCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialSummaryField' => 'DifferentialCoreCustomField',
+ 'DifferentialTagsCommitMessageField' => 'DifferentialCommitMessageField',
+ 'DifferentialTasksCommitMessageField' => 'DifferentialCommitMessageField',
+ 'DifferentialTestPlanCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialTestPlanField' => 'DifferentialCoreCustomField',
+ 'DifferentialTitleCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialTitleField' => 'DifferentialCoreCustomField',
'DifferentialTransaction' => 'PhabricatorModularTransaction',
'DifferentialTransactionComment' => 'PhabricatorApplicationTransactionComment',
diff --git a/src/applications/differential/field/DifferentialAuditorsCommitMessageField.php b/src/applications/differential/field/DifferentialAuditorsCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialAuditorsCommitMessageField.php
@@ -0,0 +1,21 @@
+<?php
+
+final class DifferentialAuditorsCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'phabricator:auditors';
+
+ public function getFieldName() {
+ return pht('Auditors');
+ }
+
+ public function parseFieldValue($value) {
+ return $this->parseObjectList(
+ $value,
+ array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ ));
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialBlameRevisionCommitMessageField.php b/src/applications/differential/field/DifferentialBlameRevisionCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialBlameRevisionCommitMessageField.php
@@ -0,0 +1,22 @@
+<?php
+
+final class DifferentialBlameRevisionCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'blameRevision';
+
+ public function getFieldName() {
+ return pht('Blame Revision');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'Blame Rev',
+ );
+ }
+
+ public function isFieldEnabled() {
+ return $this->isCustomFieldEnabled('phabricator:blame-revision');
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialCommitMessageField.php b/src/applications/differential/field/DifferentialCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialCommitMessageField.php
@@ -0,0 +1,92 @@
+<?php
+
+abstract class DifferentialCommitMessageField
+ extends Phobject {
+
+ private $viewer;
+
+ final public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ abstract public function getFieldName();
+
+ public function isFieldEnabled() {
+ return true;
+ }
+
+ public function getFieldAliases() {
+ return array();
+ }
+
+ public function validateFieldValue($value) {
+ return;
+ }
+
+ public function parseFieldValue($value) {
+ return $value;
+ }
+
+ final public function getCommitMessageFieldKey() {
+ return $this->getPhobjectClassConstant('FIELDKEY', 64);
+ }
+
+ final public static function newEnabledFields(PhabricatorUser $viewer) {
+ $fields = self::getAllFields();
+
+ $results = array();
+ foreach ($fields as $key => $field) {
+ $field = clone $field;
+ $field->setViewer($viewer);
+ if ($field->isFieldEnabled()) {
+ $results[$key] = $field;
+ }
+ }
+
+ return $results;
+ }
+
+ final public static function getAllFields() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getCommitMessageFieldKey')
+ ->execute();
+ }
+
+ protected function raiseParseException($message) {
+ throw new DifferentialFieldParseException($message);
+ }
+
+ protected function raiseValidationException($message) {
+ throw new DifferentialFieldValidationException($message);
+ }
+
+ protected function parseObjectList(
+ $value,
+ array $types,
+ $allow_partial = false,
+ array $suffixes = array()) {
+ return id(new PhabricatorObjectListQuery())
+ ->setViewer($this->getViewer())
+ ->setAllowedTypes($types)
+ ->setObjectList($value)
+ ->setAllowPartialResults($allow_partial)
+ ->setSuffixes($suffixes)
+ ->execute();
+ }
+
+ protected function isCustomFieldEnabled($key) {
+ $field_list = PhabricatorCustomField::getObjectFields(
+ new DifferentialRevision(),
+ PhabricatorCustomField::ROLE_VIEW);
+
+ $fields = $field_list->getFields();
+ return isset($fields[$key]);
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialConflictsCommitMessageField.php b/src/applications/differential/field/DifferentialConflictsCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialConflictsCommitMessageField.php
@@ -0,0 +1,12 @@
+<?php
+
+final class DifferentialConflictsCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'conflicts';
+
+ public function getFieldName() {
+ return pht('Conflicts');
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialGitSVNIDCommitMessageField.php b/src/applications/differential/field/DifferentialGitSVNIDCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialGitSVNIDCommitMessageField.php
@@ -0,0 +1,12 @@
+<?php
+
+final class DifferentialGitSVNIDCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'gitSVNID';
+
+ public function getFieldName() {
+ return pht('git-svn-id');
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php b/src/applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php
@@ -0,0 +1,27 @@
+<?php
+
+final class DifferentialJIRAIssuesCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'jira.issues';
+
+ public function getFieldName() {
+ return pht('JIRA Issues');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'JIRA',
+ 'JIRA Issue',
+ );
+ }
+
+ public function parseFieldValue($value) {
+ return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY);
+ }
+
+ public function isFieldEnabled() {
+ return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider();
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialRevertPlanCommitMessageField.php b/src/applications/differential/field/DifferentialRevertPlanCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialRevertPlanCommitMessageField.php
@@ -0,0 +1,16 @@
+<?php
+
+final class DifferentialRevertPlanCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'revertPlan';
+
+ public function getFieldName() {
+ return pht('Revert Plan');
+ }
+
+ public function isFieldEnabled() {
+ return $this->isCustomFieldEnabled('phabricator:revert-plan');
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php b/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php
@@ -0,0 +1,22 @@
+<?php
+
+final class DifferentialReviewedByCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'reviewedByPHIDs';
+
+ public function getFieldName() {
+ return pht('Reviewed By');
+ }
+
+ public function parseFieldValue($value) {
+ return $this->parseObjectList(
+ $value,
+ array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ ),
+ $allow_partial = true);
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialReviewersCommitMessageField.php b/src/applications/differential/field/DifferentialReviewersCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialReviewersCommitMessageField.php
@@ -0,0 +1,64 @@
+<?php
+
+final class DifferentialReviewersCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'reviewerPHIDs';
+
+ public function getFieldName() {
+ return pht('Reviewers');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'Reviewer',
+ );
+ }
+
+ public function parseFieldValue($value) {
+ $results = $this->parseObjectList(
+ $value,
+ array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ PhabricatorOwnersPackagePHIDType::TYPECONST,
+ ),
+ false,
+ array('!'));
+
+ return $this->flattenReviewers($results);
+ }
+
+ private function flattenReviewers(array $values) {
+ // NOTE: For now, `arc` relies on this field returning only scalars, so we
+ // need to reduce the results into scalars. See T10981.
+ $result = array();
+
+ foreach ($values as $value) {
+ $result[] = $value['phid'].implode('', array_keys($value['suffixes']));
+ }
+
+ return $result;
+ }
+
+ private function inflateReviewers(array $values) {
+ $result = array();
+
+ foreach ($values as $value) {
+ if (substr($value, -1) == '!') {
+ $value = substr($value, 0, -1);
+ $suffixes = array('!' => '!');
+ } else {
+ $suffixes = array();
+ }
+
+ $result[] = array(
+ 'phid' => $value,
+ 'suffixes' => $suffixes,
+ );
+ }
+
+ return $result;
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialRevisionIDCommitMessageField.php b/src/applications/differential/field/DifferentialRevisionIDCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialRevisionIDCommitMessageField.php
@@ -0,0 +1,52 @@
+<?php
+
+final class DifferentialRevisionIDCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'revisionID';
+
+ public function getFieldName() {
+ return pht('Differential Revision');
+ }
+
+ public function parseFieldValue($value) {
+ // If the value is just "D123" or similar, parse the ID from it directly.
+ $value = trim($value);
+ $matches = null;
+ if (preg_match('/^[dD]([1-9]\d*)\z/', $value, $matches)) {
+ return (int)$matches[1];
+ }
+
+ // Otherwise, try to extract a URI value.
+ return self::parseRevisionIDFromURI($value);
+ }
+
+ private static function parseRevisionIDFromURI($uri_string) {
+ $uri = new PhutilURI($uri_string);
+ $path = $uri->getPath();
+
+ $matches = null;
+ if (preg_match('#^/D(\d+)$#', $path, $matches)) {
+ $id = (int)$matches[1];
+
+ $prod_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/D'.$id));
+
+ // Make sure the URI is the same as our URI. Basically, we want to ignore
+ // commits from other Phabricator installs.
+ if ($uri->getDomain() == $prod_uri->getDomain()) {
+ return $id;
+ }
+
+ $allowed_uris = PhabricatorEnv::getAllowedURIs('/D'.$id);
+
+ foreach ($allowed_uris as $allowed_uri) {
+ if ($uri_string == $allowed_uri) {
+ return $id;
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialSubscribersCommitMessageField.php b/src/applications/differential/field/DifferentialSubscribersCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialSubscribersCommitMessageField.php
@@ -0,0 +1,30 @@
+<?php
+
+final class DifferentialSubscribersCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'ccPHIDs';
+
+ public function getFieldName() {
+ return pht('Subscribers');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'CC',
+ 'CCs',
+ 'Subscriber',
+ );
+ }
+
+ public function parseFieldValue($value) {
+ return $this->parseObjectList(
+ $value,
+ array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ PhabricatorOwnersPackagePHIDType::TYPECONST,
+ ));
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialSummaryCommitMessageField.php b/src/applications/differential/field/DifferentialSummaryCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialSummaryCommitMessageField.php
@@ -0,0 +1,12 @@
+<?php
+
+final class DifferentialSummaryCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'summary';
+
+ public function getFieldName() {
+ return pht('Summary');
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialTagsCommitMessageField.php b/src/applications/differential/field/DifferentialTagsCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialTagsCommitMessageField.php
@@ -0,0 +1,28 @@
+<?php
+
+final class DifferentialTagsCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'phabricator:projects';
+
+ public function getFieldName() {
+ return pht('Tags');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'Tag',
+ 'Project',
+ 'Projects',
+ );
+ }
+
+ public function parseFieldValue($value) {
+ return $this->parseObjectList(
+ $value,
+ array(
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ ));
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialTasksCommitMessageField.php b/src/applications/differential/field/DifferentialTasksCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialTasksCommitMessageField.php
@@ -0,0 +1,28 @@
+<?php
+
+final class DifferentialTasksCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'maniphestTaskPHIDs';
+
+ public function getFieldName() {
+ return pht('Maniphest Tasks');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'Task',
+ 'Tasks',
+ 'Maniphest Task',
+ );
+ }
+
+ public function parseFieldValue($value) {
+ return $this->parseObjectList(
+ $value,
+ array(
+ ManiphestTaskPHIDType::TYPECONST,
+ ));
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialTestPlanCommitMessageField.php b/src/applications/differential/field/DifferentialTestPlanCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialTestPlanCommitMessageField.php
@@ -0,0 +1,36 @@
+<?php
+
+final class DifferentialTestPlanCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'testPlan';
+
+ public function getFieldName() {
+ return pht('Test Plan');
+ }
+
+ public function getFieldAliases() {
+ return array(
+ 'Testplan',
+ 'Tested',
+ 'Tests',
+ );
+ }
+
+ public function isFieldEnabled() {
+ return $this->isCustomFieldEnabled('differential:test-plan');
+ }
+
+ public function validateFieldValue($value) {
+ $is_required = PhabricatorEnv::getEnvConfig(
+ 'differential.require-test-plan-field');
+
+ if ($is_required && !strlen($value)) {
+ $this->raiseValidationException(
+ pht(
+ 'You must provide a test plan. Describe the actions you performed '.
+ 'to verify the behavior of this change.'));
+ }
+ }
+
+}
diff --git a/src/applications/differential/field/DifferentialTitleCommitMessageField.php b/src/applications/differential/field/DifferentialTitleCommitMessageField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/field/DifferentialTitleCommitMessageField.php
@@ -0,0 +1,36 @@
+<?php
+
+final class DifferentialTitleCommitMessageField
+ extends DifferentialCommitMessageField {
+
+ const FIELDKEY = 'title';
+
+ public function getFieldName() {
+ return pht('Title');
+ }
+
+ public static function getDefaultTitle() {
+ return pht('<<Replace this line with your revision title>');
+ }
+
+ public function parseFieldValue($value) {
+ if ($value === self::getDefaultTitle()) {
+ $this->raiseParseException(
+ pht(
+ 'Replace the default title line with a human-readable revision '.
+ 'title which describes the changes you are making.'));
+ }
+
+ return parent::parseFieldValue($value);
+ }
+
+ public function validateFieldValue($value) {
+ if (!strlen($value)) {
+ $this->raiseValidationException(
+ pht(
+ 'You must provide a revision title in the first line '.
+ 'of your commit message.'));
+ }
+ }
+
+}
diff --git a/src/applications/differential/parser/DifferentialCommitMessageParser.php b/src/applications/differential/parser/DifferentialCommitMessageParser.php
--- a/src/applications/differential/parser/DifferentialCommitMessageParser.php
+++ b/src/applications/differential/parser/DifferentialCommitMessageParser.php
@@ -26,43 +26,18 @@
private $titleKey;
private $summaryKey;
private $errors;
+ private $commitMessageFields;
private $raiseMissingFieldErrors = true;
public static function newStandardParser(PhabricatorUser $viewer) {
+ $key_title = DifferentialTitleCommitMessageField::FIELDKEY;
+ $key_summary = DifferentialSummaryCommitMessageField::FIELDKEY;
- $key_title = id(new DifferentialTitleField())->getFieldKeyForConduit();
- $key_summary = id(new DifferentialSummaryField())->getFieldKeyForConduit();
-
- $field_list = PhabricatorCustomField::getObjectFields(
- new DifferentialRevision(),
- DifferentialCustomField::ROLE_COMMITMESSAGE);
- $field_list->setViewer($viewer);
-
- $label_map = array();
-
- foreach ($field_list->getFields() as $field) {
- $labels = $field->getCommitMessageLabels();
- $key = $field->getFieldKeyForConduit();
-
- foreach ($labels as $label) {
- $normal_label = self::normalizeFieldLabel(
- $label);
- if (!empty($label_map[$normal_label])) {
- throw new Exception(
- pht(
- 'Field label "%s" is parsed by two custom fields: "%s" and '.
- '"%s". Each label must be parsed by only one field.',
- $label,
- $key,
- $label_map[$normal_label]));
- }
- $label_map[$normal_label] = $key;
- }
- }
+ $field_list = DifferentialCommitMessageField::newEnabledFields($viewer);
return id(new self())
->setViewer($viewer)
- ->setLabelMap($label_map)
+ ->setCommitMessageFields($field_list)
->setTitleKey($key_title)
->setSummaryKey($key_summary);
}
@@ -91,6 +66,25 @@
/**
* @task config
*/
+ public function setCommitMessageFields($fields) {
+ assert_instances_of($fields, 'DifferentialCommitMessageField');
+ $fields = mpull($fields, null, 'getCommitMessageFieldKey');
+ $this->commitMessageFields = $fields;
+ return $this;
+ }
+
+
+ /**
+ * @task config
+ */
+ public function getCommitMessageFields() {
+ return $this->commitMessageFields;
+ }
+
+
+ /**
+ * @task config
+ */
public function setRaiseMissingFieldErrors($raise) {
$this->raiseMissingFieldErrors = $raise;
return $this;
@@ -141,7 +135,7 @@
public function parseCorpus($corpus) {
$this->errors = array();
- $label_map = $this->labelMap;
+ $label_map = $this->getLabelMap();
$key_title = $this->titleKey;
$key_summary = $this->summaryKey;
@@ -258,13 +252,7 @@
$viewer = $this->getViewer();
$text_map = $this->parseCorpus($corpus);
- $field_list = PhabricatorCustomField::getObjectFields(
- new DifferentialRevision(),
- DifferentialCustomField::ROLE_COMMITMESSAGE);
- $field_list->setViewer($viewer);
-
- $field_map = $field_list->getFields();
- $field_map = mpull($field_map, null, 'getFieldKeyForConduit');
+ $field_map = $this->getCommitMessageFields();
$result_map = array();
foreach ($text_map as $field_key => $text_value) {
@@ -281,7 +269,7 @@
}
try {
- $result = $field->parseValueFromCommitMessage($text_value);
+ $result = $field->parseFieldValue($text_value);
$result_map[$field_key] = $result;
} catch (DifferentialFieldParseException $ex) {
$this->errors[] = pht(
@@ -294,7 +282,7 @@
if ($this->getRaiseMissingFieldErrors()) {
foreach ($field_map as $key => $field) {
try {
- $field->validateCommitMessageValue(idx($result_map, $key));
+ $field->validateFieldValue(idx($result_map, $key));
} catch (DifferentialFieldValidationException $ex) {
$this->errors[] = pht(
'Invalid or missing field "%s": %s',
@@ -330,6 +318,38 @@
/* -( Internals )---------------------------------------------------------- */
+ private function getLabelMap() {
+ if ($this->labelMap === null) {
+ $field_list = $this->getCommitMessageFields();
+
+ $label_map = array();
+ foreach ($field_list as $field_key => $field) {
+ $labels = $field->getFieldAliases();
+ $labels[] = $field->getFieldName();
+
+ foreach ($labels as $label) {
+ $normal_label = self::normalizeFieldLabel($label);
+ if (!empty($label_map[$normal_label])) {
+ throw new Exception(
+ pht(
+ 'Field label "%s" is parsed by two custom fields: "%s" and '.
+ '"%s". Each label must be parsed by only one field.',
+ $label,
+ $field_key,
+ $label_map[$normal_label]));
+ }
+
+ $label_map[$normal_label] = $field_key;
+ }
+ }
+
+ $this->labelMap = $label_map;
+ }
+
+ return $this->labelMap;
+ }
+
+
/**
* @task internal
*/
diff --git a/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php b/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php
--- a/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php
+++ b/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php
@@ -41,6 +41,36 @@
}
}
+
+ public function testDifferentialCommitMessageFieldParser() {
+ $message = <<<EOMESSAGE
+This is the title.
+
+Summary: This is the summary.
+EOMESSAGE;
+
+ $fields = array(
+ new DifferentialTitleCommitMessageField(),
+ new DifferentialSummaryCommitMessageField(),
+ );
+
+ $expect = array(
+ DifferentialTitleCommitMessageField::FIELDKEY =>
+ 'This is the title.',
+ DifferentialSummaryCommitMessageField::FIELDKEY =>
+ 'This is the summary.',
+ );
+
+ $parser = id(new DifferentialCommitMessageParser())
+ ->setCommitMessageFields($fields)
+ ->setTitleKey(DifferentialTitleCommitMessageField::FIELDKEY)
+ ->setSummaryKey(DifferentialSummaryCommitMessageField::FIELDKEY);
+
+ $actual = $parser->parseFields($message);
+
+ $this->assertEqual($expect, $actual);
+ }
+
public function testDifferentialCommitMessageParserNormalization() {
$map = array(
'Test Plan' => 'test plan',

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 23, 4:24 AM (17 h, 58 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6920588
Default Alt Text
D17058.diff (36 KB)

Event Timeline