diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ae8760090d..a70eb1d5ae 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -353,8 +353,10 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( 'DifferentialAffectedPath' => 'DifferentialDAO', 'DifferentialApplyPatchField' => 'DifferentialCustomField', 'DifferentialAsanaRepresentationField' => 'DifferentialCustomField', + 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialAuditorsField' => 'DifferentialStoredCustomField', 'DifferentialAuthorField' => 'DifferentialCustomField', + 'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', 'DifferentialBlockHeraldAction' => 'HeraldAction', 'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', @@ -5009,10 +5027,12 @@ phutil_register_library_map(array( '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 @@ phutil_register_library_map(array( 'DifferentialGetRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialGetWorkingCopy' => 'Phobject', 'DifferentialGitHubLandingStrategy' => 'DifferentialLandingStrategy', + 'DifferentialGitSVNIDCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialGitSVNIDField' => 'DifferentialCustomField', 'DifferentialHarbormasterField' => 'DifferentialCustomField', 'DifferentialHiddenComment' => 'DifferentialDAO', @@ -5100,6 +5121,7 @@ phutil_register_library_map(array( 'DifferentialInlineCommentMailView' => 'DifferentialMailView', 'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', 'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', + 'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', 'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener', 'DifferentialLandingStrategy' => 'Phobject', @@ -5132,7 +5154,9 @@ phutil_register_library_map(array( 'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource', + 'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialRevertPlanField' => 'DifferentialStoredCustomField', + 'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialReviewedByField' => 'DifferentialCoreCustomField', 'DifferentialReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialReviewerForRevisionEdgeType' => 'PhabricatorEdgeType', @@ -5142,6 +5166,7 @@ phutil_register_library_map(array( 'DifferentialReviewersAddBlockingSelfHeraldAction' => 'DifferentialReviewersHeraldAction', 'DifferentialReviewersAddReviewersHeraldAction' => 'DifferentialReviewersHeraldAction', 'DifferentialReviewersAddSelfHeraldAction' => 'DifferentialReviewersHeraldAction', + 'DifferentialReviewersCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialReviewersField' => 'DifferentialCoreCustomField', 'DifferentialReviewersHeraldAction' => 'HeraldAction', 'DifferentialReviewersView' => 'AphrontView', @@ -5185,6 +5210,7 @@ phutil_register_library_map(array( 'DifferentialRevisionHasTaskRelationship' => 'DifferentialRevisionRelationship', 'DifferentialRevisionHeraldField' => 'HeraldField', 'DifferentialRevisionHeraldFieldGroup' => 'HeraldFieldGroup', + 'DifferentialRevisionIDCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialRevisionIDField' => 'DifferentialCustomField', 'DifferentialRevisionLandController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController', @@ -5218,9 +5244,15 @@ phutil_register_library_map(array( '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 index 0000000000..fc3bc95fd3 --- /dev/null +++ b/src/applications/differential/field/DifferentialAuditorsCommitMessageField.php @@ -0,0 +1,21 @@ +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 index 0000000000..d48088c68f --- /dev/null +++ b/src/applications/differential/field/DifferentialBlameRevisionCommitMessageField.php @@ -0,0 +1,22 @@ +isCustomFieldEnabled('phabricator:blame-revision'); + } + +} diff --git a/src/applications/differential/field/DifferentialCommitMessageField.php b/src/applications/differential/field/DifferentialCommitMessageField.php new file mode 100644 index 0000000000..ddf5cc5b28 --- /dev/null +++ b/src/applications/differential/field/DifferentialCommitMessageField.php @@ -0,0 +1,92 @@ +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 index 0000000000..334a7a060f --- /dev/null +++ b/src/applications/differential/field/DifferentialConflictsCommitMessageField.php @@ -0,0 +1,12 @@ +isCustomFieldEnabled('phabricator:revert-plan'); + } + +} diff --git a/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php b/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php new file mode 100644 index 0000000000..ea222b28aa --- /dev/null +++ b/src/applications/differential/field/DifferentialReviewedByCommitMessageField.php @@ -0,0 +1,22 @@ +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 index 0000000000..e3c275b471 --- /dev/null +++ b/src/applications/differential/field/DifferentialReviewersCommitMessageField.php @@ -0,0 +1,64 @@ +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 index 0000000000..5e2b378e12 --- /dev/null +++ b/src/applications/differential/field/DifferentialRevisionIDCommitMessageField.php @@ -0,0 +1,52 @@ +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 index 0000000000..ba693a3493 --- /dev/null +++ b/src/applications/differential/field/DifferentialSubscribersCommitMessageField.php @@ -0,0 +1,30 @@ +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 index 0000000000..531d542633 --- /dev/null +++ b/src/applications/differential/field/DifferentialSummaryCommitMessageField.php @@ -0,0 +1,12 @@ +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 index 0000000000..652de0ffe6 --- /dev/null +++ b/src/applications/differential/field/DifferentialTasksCommitMessageField.php @@ -0,0 +1,28 @@ +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 index 0000000000..d9f1a3e3b6 --- /dev/null +++ b/src/applications/differential/field/DifferentialTestPlanCommitMessageField.php @@ -0,0 +1,36 @@ +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 index 0000000000..af5ed58545 --- /dev/null +++ b/src/applications/differential/field/DifferentialTitleCommitMessageField.php @@ -0,0 +1,36 @@ +'); + } + + 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 index 8cd508ef5f..6cf126bd0f 100644 --- a/src/applications/differential/parser/DifferentialCommitMessageParser.php +++ b/src/applications/differential/parser/DifferentialCommitMessageParser.php @@ -26,43 +26,18 @@ final class DifferentialCommitMessageParser extends Phobject { 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); } @@ -88,6 +63,25 @@ final class DifferentialCommitMessageParser extends Phobject { } + /** + * @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 */ @@ -141,7 +135,7 @@ final class DifferentialCommitMessageParser extends Phobject { 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 @@ final class DifferentialCommitMessageParser extends Phobject { $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 @@ final class DifferentialCommitMessageParser extends Phobject { } 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 @@ final class DifferentialCommitMessageParser extends Phobject { 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 @@ final class DifferentialCommitMessageParser extends Phobject { /* -( 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 index 669cfed220..320445fd0d 100644 --- a/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php +++ b/src/applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php @@ -41,6 +41,36 @@ final class DifferentialCommitMessageParserTestCase } } + + public function testDifferentialCommitMessageFieldParser() { + $message = << + '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',