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 @@ -554,6 +554,7 @@ 'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php', 'DifferentialRevisionSummaryHeraldField' => 'applications/differential/herald/DifferentialRevisionSummaryHeraldField.php', 'DifferentialRevisionSummaryTransaction' => 'applications/differential/xaction/DifferentialRevisionSummaryTransaction.php', + 'DifferentialRevisionTestPlanTransaction' => 'applications/differential/xaction/DifferentialRevisionTestPlanTransaction.php', 'DifferentialRevisionTitleHeraldField' => 'applications/differential/herald/DifferentialRevisionTitleHeraldField.php', 'DifferentialRevisionTitleTransaction' => 'applications/differential/xaction/DifferentialRevisionTitleTransaction.php', 'DifferentialRevisionTransactionType' => 'applications/differential/xaction/DifferentialRevisionTransactionType.php', @@ -5206,6 +5207,7 @@ 'DifferentialRevisionStatus' => 'Phobject', 'DifferentialRevisionSummaryHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionSummaryTransaction' => 'DifferentialRevisionTransactionType', + 'DifferentialRevisionTestPlanTransaction' => 'DifferentialRevisionTransactionType', 'DifferentialRevisionTitleHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionTitleTransaction' => 'DifferentialRevisionTransactionType', 'DifferentialRevisionTransactionType' => 'PhabricatorModularTransactionType', diff --git a/src/applications/differential/editor/DifferentialRevisionEditEngine.php b/src/applications/differential/editor/DifferentialRevisionEditEngine.php --- a/src/applications/differential/editor/DifferentialRevisionEditEngine.php +++ b/src/applications/differential/editor/DifferentialRevisionEditEngine.php @@ -60,37 +60,70 @@ } protected function buildCustomEditFields($object) { - return array( - id(new PhabricatorTextEditField()) - ->setKey('title') - ->setLabel(pht('Title')) - ->setIsRequired(true) - ->setTransactionType( - DifferentialRevisionTitleTransaction::TRANSACTIONTYPE) - ->setDescription(pht('The title of the revision.')) - ->setConduitDescription(pht('Retitle the revision.')) - ->setConduitTypeDescription(pht('New revision title.')) - ->setValue($object->getTitle()), - id(new PhabricatorRemarkupEditField()) - ->setKey('summary') - ->setLabel(pht('Summary')) - ->setTransactionType( - DifferentialRevisionSummaryTransaction::TRANSACTIONTYPE) - ->setDescription(pht('The summary of the revision.')) - ->setConduitDescription(pht('Change the revision summary.')) - ->setConduitTypeDescription(pht('New revision summary.')) - ->setValue($object->getSummary()), - id(new PhabricatorDatasourceEditField()) - ->setKey('repositoryPHID') - ->setLabel(pht('Repository')) - ->setDatasource(new DiffusionRepositoryDatasource()) + + $plan_required = PhabricatorEnv::getEnvConfig( + 'differential.require-test-plan-field'); + $plan_enabled = $this->isCustomFieldEnabled( + $object, + 'differential:test-plan'); + + $fields = array(); + $fields[] = id(new PhabricatorTextEditField()) + ->setKey('title') + ->setLabel(pht('Title')) + ->setIsRequired(true) + ->setTransactionType( + DifferentialRevisionTitleTransaction::TRANSACTIONTYPE) + ->setDescription(pht('The title of the revision.')) + ->setConduitDescription(pht('Retitle the revision.')) + ->setConduitTypeDescription(pht('New revision title.')) + ->setValue($object->getTitle()); + + $fields[] = id(new PhabricatorRemarkupEditField()) + ->setKey('summary') + ->setLabel(pht('Summary')) + ->setTransactionType( + DifferentialRevisionSummaryTransaction::TRANSACTIONTYPE) + ->setDescription(pht('The summary of the revision.')) + ->setConduitDescription(pht('Change the revision summary.')) + ->setConduitTypeDescription(pht('New revision summary.')) + ->setValue($object->getSummary()); + + if ($plan_enabled) { + $fields[] = id(new PhabricatorRemarkupEditField()) + ->setKey('testPlan') + ->setLabel(pht('Test Plan')) + ->setIsRequired($plan_required) ->setTransactionType( - DifferentialRevisionRepositoryTransaction::TRANSACTIONTYPE) - ->setDescription(pht('The repository the revision belongs to.')) - ->setConduitDescription(pht('Change the repository for this revision.')) - ->setConduitTypeDescription(pht('New repository.')) - ->setSingleValue($object->getRepositoryPHID()), - ); + DifferentialRevisionTestPlanTransaction::TRANSACTIONTYPE) + ->setDescription( + pht('Actions performed to verify the behavior of the change.')) + ->setConduitDescription(pht('Update the revision test plan.')) + ->setConduitTypeDescription(pht('New test plan.')) + ->setValue($object->getTestPlan()); + } + + $fields[] = id(new PhabricatorDatasourceEditField()) + ->setKey('repositoryPHID') + ->setLabel(pht('Repository')) + ->setDatasource(new DiffusionRepositoryDatasource()) + ->setTransactionType( + DifferentialRevisionRepositoryTransaction::TRANSACTIONTYPE) + ->setDescription(pht('The repository the revision belongs to.')) + ->setConduitDescription(pht('Change the repository for this revision.')) + ->setConduitTypeDescription(pht('New repository.')) + ->setSingleValue($object->getRepositoryPHID()); + + return $fields; + } + + private function isCustomFieldEnabled(DifferentialRevision $revision, $key) { + $field_list = PhabricatorCustomField::getObjectFields( + $revision, + PhabricatorCustomField::ROLE_EDIT); + + $fields = $field_list->getFields(); + return isset($fields[$key]); } } diff --git a/src/applications/differential/xaction/DifferentialRevisionTestPlanTransaction.php b/src/applications/differential/xaction/DifferentialRevisionTestPlanTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/differential/xaction/DifferentialRevisionTestPlanTransaction.php @@ -0,0 +1,74 @@ +getTestPlan(); + } + + public function applyInternalEffects($object, $value) { + $object->setTestPlan($value); + } + + public function getTitle() { + return pht( + '%s edited the test plan for this revision.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s updated the test plan for %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO TEST PLAN'); + } + + public function newChangeDetailView() { + $viewer = $this->getViewer(); + + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) + ->setViewer($viewer) + ->setOldText($this->getOldValue()) + ->setNewText($this->getNewValue()); + } + + public function newRemarkupChanges() { + $changes = array(); + + $changes[] = $this->newRemarkupChange() + ->setOldValue($this->getOldValue()) + ->setNewValue($this->getNewValue()); + + return $changes; + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $is_required = PhabricatorEnv::getEnvConfig( + 'differential.require-test-plan-field'); + + if ($is_required) { + if ($this->isEmptyTextTransaction($object->getTestPlan(), $xactions)) { + $errors[] = $this->newRequiredError( + pht( + 'You must provide a test plan. Describe the actions you '. + 'performed to verify the behavior of this change.')); + } + } + + return $errors; + } + +}