Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14395411
D17058.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
36 KB
Referenced Files
None
Subscribers
None
D17058.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D17058: Separate all commit message field parsing out of Differential custom fields
Attached
Detach File
Event Timeline
Log In to Comment