1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-31 17:08:22 +01:00

Move Differential commit message rendering to dedicated classes

Summary:
Ref T11114. This probably still has some bugs, but survives basic sanity checks.

Continue pulling commit message logic out of CustomField so we can reduce the amount of responsibility/bloat in the classtree and send more code through EditEngine.

Test Plan:
  - Called `differential.getcommitmessage` via API console for various revisions/parameters (edit and create mode, with and without fields, with and without revisions).
  - Used `--create`, `--edit` and `--update` modes of `arc diff` from the CLI.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11114

Differential Revision: https://secure.phabricator.com/D17066
This commit is contained in:
epriestley 2016-12-15 10:11:58 -08:00
parent 0387d62632
commit 24926f9453
20 changed files with 499 additions and 112 deletions

View file

@ -385,6 +385,7 @@ phutil_register_library_map(array(
'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php', 'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php',
'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php', 'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php', 'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
'DifferentialCommitMessageCustomField' => 'applications/differential/field/DifferentialCommitMessageCustomField.php',
'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php', 'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php',
'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php', 'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php',
'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php', 'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php',
@ -4996,10 +4997,10 @@ phutil_register_library_map(array(
'DifferentialAffectedPath' => 'DifferentialDAO', 'DifferentialAffectedPath' => 'DifferentialDAO',
'DifferentialApplyPatchField' => 'DifferentialCustomField', 'DifferentialApplyPatchField' => 'DifferentialCustomField',
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField', 'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField',
'DifferentialAuditorsField' => 'DifferentialStoredCustomField', 'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
'DifferentialAuthorField' => 'DifferentialCustomField', 'DifferentialAuthorField' => 'DifferentialCustomField',
'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageCustomField',
'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', 'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField',
'DifferentialBlockHeraldAction' => 'HeraldAction', 'DifferentialBlockHeraldAction' => 'HeraldAction',
'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
@ -5031,6 +5032,7 @@ phutil_register_library_map(array(
'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod',
'DifferentialCommentPreviewController' => 'DifferentialController', 'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController', 'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialCommitMessageCustomField' => 'DifferentialCommitMessageField',
'DifferentialCommitMessageField' => 'Phobject', 'DifferentialCommitMessageField' => 'Phobject',
'DifferentialCommitMessageParser' => 'Phobject', 'DifferentialCommitMessageParser' => 'Phobject',
'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase', 'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase',
@ -5125,7 +5127,7 @@ phutil_register_library_map(array(
'DifferentialInlineCommentMailView' => 'DifferentialMailView', 'DifferentialInlineCommentMailView' => 'DifferentialMailView',
'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', 'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', 'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField',
'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', 'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener', 'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener',
'DifferentialLandingStrategy' => 'Phobject', 'DifferentialLandingStrategy' => 'Phobject',
@ -5158,7 +5160,7 @@ phutil_register_library_map(array(
'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource', 'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource',
'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageCustomField',
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField', 'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField',
'DifferentialReviewedByField' => 'DifferentialCoreCustomField', 'DifferentialReviewedByField' => 'DifferentialCoreCustomField',

View file

@ -47,94 +47,71 @@ final class DifferentialGetCommitMessageConduitAPIMethod
} }
} else { } else {
$revision = DifferentialRevision::initializeNewRevision($viewer); $revision = DifferentialRevision::initializeNewRevision($viewer);
$revision->attachReviewerStatus(array());
$revision->attachActiveDiff(null);
} }
$is_edit = $request->getValue('edit'); $edit_mode = $request->getValue('edit');
$is_create = ($is_edit == 'create'); $is_create = ($edit_mode == 'create');
$is_edit = ($edit_mode && !$is_create);
$field_list = PhabricatorCustomField::getObjectFields( $field_list = DifferentialCommitMessageField::newEnabledFields($viewer);
$revision,
($is_edit
? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT
: DifferentialCustomField::ROLE_COMMITMESSAGE));
$field_list $custom_storage = $this->loadCustomFieldStorage($viewer, $revision);
->setViewer($viewer) foreach ($field_list as $field) {
->readFieldsFromStorage($revision); $field->setCustomFieldStorage($custom_storage);
}
$field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
// If we're editing the message, remove fields like "Conflicts" and
// "git-svn-id" which should not be presented to the user for editing.
if ($is_edit) { if ($is_edit) {
$fields = $request->getValue('fields', array()); foreach ($field_list as $field_key => $field) {
foreach ($fields as $field => $value) { if (!$field->isFieldEditable()) {
$custom_field = idx($field_map, $field); unset($field_list[$field_key]);
if (!$custom_field) {
// Just ignore this, these workflows don't make strong distictions
// about field editability on the client side.
continue;
}
if ($is_create ||
$custom_field->shouldOverwriteWhenCommitMessageIsEdited()) {
$custom_field->readValueFromCommitMessage($value);
} }
} }
} }
$phids = array(); $overrides = $request->getValue('fields', array());
foreach ($field_list->getFields() as $key => $field) {
$field_phids = $field->getRequiredHandlePHIDsForCommitMessage(); $value_map = array();
if (!is_array($field_phids)) { foreach ($field_list as $field_key => $field) {
throw new Exception( if (array_key_exists($field_key, $overrides)) {
pht( $field_value = $overrides[$field_key];
'Custom field "%s" was expected to return an array of handle '. } else {
'PHIDs required for commit message rendering, but returned "%s" '. $field_value = $field->readFieldValueFromObject($revision);
'instead.',
$field->getFieldKey(),
gettype($field_phids)));
} }
$phids[$key] = $field_phids;
// We're calling this method on the value no matter where we got it
// from, so we hit the same validation logic for values which came over
// the wire and which we generated.
$field_value = $field->readFieldValueFromConduit($field_value);
$value_map[$field_key] = $field_value;
} }
$all_phids = array_mergev($phids); $key_title = DifferentialTitleCommitMessageField::FIELDKEY;
if ($all_phids) {
$all_handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs($all_phids)
->execute();
} else {
$all_handles = array();
}
$key_title = id(new DifferentialTitleField())->getFieldKey();
$default_title = DifferentialTitleField::getDefaultTitle();
$commit_message = array(); $commit_message = array();
foreach ($field_list->getFields() as $key => $field) { foreach ($field_list as $field_key => $field) {
$handles = array_select_keys($all_handles, $phids[$key]); $label = $field->getFieldName();
$wire_value = $value_map[$field_key];
$value = $field->renderFieldValue($wire_value);
$label = $field->renderCommitMessageLabel(); $is_template = ($is_edit && $field->isTemplateField());
$value = $field->renderCommitMessageValue($handles);
if (!is_string($value) && !is_null($value)) { if (!is_string($value) && !is_null($value)) {
throw new Exception( throw new Exception(
pht( pht(
'Custom field "%s" was expected to render a string or null value, '. 'Commit message field "%s" was expected to render a string or '.
'but rendered a "%s" instead.', 'null value, but rendered a "%s" instead.',
$field->getFieldKey(), $field->getFieldKey(),
gettype($value))); gettype($value)));
} }
$is_title = ($key == $key_title); $is_title = ($field_key == $key_title);
if (!strlen($value)) { if (!strlen($value)) {
if ($is_title) { if ($is_template) {
$commit_message[] = $default_title; $commit_message[] = $label.': ';
} else {
if ($is_edit && $field->shouldAppearInCommitMessageTemplate()) {
$commit_message[] = $label.': ';
}
} }
} else { } else {
if ($is_title) { if ($is_title) {
@ -153,46 +130,31 @@ final class DifferentialGetCommitMessageConduitAPIMethod
} }
} }
if ($is_edit) { return implode("\n\n", $commit_message);
$tip = $this->getProTip($field_list); }
if ($tip !== null) {
$commit_message[] = "\n".$tip; private function loadCustomFieldStorage(
PhabricatorUser $viewer,
DifferentialRevision $revision) {
$custom_field_list = PhabricatorCustomField::getObjectFields(
$revision,
DifferentialCustomField::ROLE_COMMITMESSAGE);
$custom_field_list
->setViewer($viewer)
->readFieldsFromStorage($revision);
$custom_field_map = array();
foreach ($custom_field_list->getFields() as $custom_field) {
if (!$custom_field->shouldUseStorage()) {
continue;
} }
$custom_field_key = $custom_field->getFieldKey();
$custom_field_value = $custom_field->getValueForStorage();
$custom_field_map[$custom_field_key] = $custom_field_value;
} }
$commit_message = implode("\n\n", $commit_message); return $custom_field_map;
return $commit_message;
} }
private function getProTip() {
// Any field can provide tips, whether it normally appears on commit
// messages or not.
$field_list = PhabricatorCustomField::getObjectFields(
new DifferentialRevision(),
PhabricatorCustomField::ROLE_DEFAULT);
$tips = array();
foreach ($field_list->getFields() as $key => $field) {
$tips[] = $field->getProTips();
}
$tips = array_mergev($tips);
if (!$tips) {
return null;
}
shuffle($tips);
$tip = pht('Tip: %s', head($tips));
$tip = wordwrap($tip, 78, "\n", true);
$lines = explode("\n", $tip);
foreach ($lines as $key => $line) {
$lines[$key] = '# '.$line;
}
return implode("\n", $lines);
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
final class DifferentialAuditorsCommitMessageField final class DifferentialAuditorsCommitMessageField
extends DifferentialCommitMessageField { extends DifferentialCommitMessageCustomField {
const FIELDKEY = 'phabricator:auditors'; const FIELDKEY = 'phabricator:auditors';
@ -18,4 +18,20 @@ final class DifferentialAuditorsCommitMessageField
)); ));
} }
public function getCustomFieldKey() {
return 'phabricator:auditors';
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
return $this->renderHandleList($value);
}
protected function readFieldValueFromCustomFieldStorage($value) {
return $this->readJSONFieldValueFromCustomFieldStorage($value, array());
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
final class DifferentialBlameRevisionCommitMessageField final class DifferentialBlameRevisionCommitMessageField
extends DifferentialCommitMessageField { extends DifferentialCommitMessageCustomField {
const FIELDKEY = 'blameRevision'; const FIELDKEY = 'blameRevision';
@ -15,8 +15,8 @@ final class DifferentialBlameRevisionCommitMessageField
); );
} }
public function isFieldEnabled() { public function getCustomFieldKey() {
return $this->isCustomFieldEnabled('phabricator:blame-revision'); return 'phabricator:blame-revision';
} }
} }

View file

@ -0,0 +1,63 @@
<?php
abstract class DifferentialCommitMessageCustomField
extends DifferentialCommitMessageField {
abstract public function getCustomFieldKey();
public function getFieldOrder() {
$custom_key = $this->getCustomFieldKey();
return 100000 + $this->getCustomFieldOrder($custom_key);
}
public function isFieldEnabled() {
$custom_key = $this->getCustomFieldKey();
return $this->isCustomFieldEnabled($custom_key);
}
public function readFieldValueFromObject(DifferentialRevision $revision) {
$custom_key = $this->getCustomFieldKey();
$value = $this->readCustomFieldValue($revision, $custom_key);
return $value;
}
protected function readFieldValueFromCustomFieldStorage($value) {
return $value;
}
protected function readJSONFieldValueFromCustomFieldStorage(
$value,
$default) {
try {
return phutil_json_decode($value);
} catch (PhutilJSONParserException $ex) {
return $default;
}
}
protected function readCustomFieldValue(
DifferentialRevision $revision,
$key) {
$value = idx($this->getCustomFieldStorage(), $key);
return $this->readFieldValueFromCustomFieldStorage($value);
}
protected function getCustomFieldOrder($key) {
$field_list = PhabricatorCustomField::getObjectFields(
new DifferentialRevision(),
DifferentialCustomField::ROLE_COMMITMESSAGE);
$fields = $field_list->getFields();
$idx = 0;
foreach ($fields as $field_key => $value) {
if ($key === $field_key) {
return $idx;
}
$idx++;
}
return $idx;
}
}

View file

@ -4,6 +4,7 @@ abstract class DifferentialCommitMessageField
extends Phobject { extends Phobject {
private $viewer; private $viewer;
private $customFieldStorage;
final public function setViewer(PhabricatorUser $viewer) { final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer; $this->viewer = $viewer;
@ -14,7 +15,17 @@ abstract class DifferentialCommitMessageField
return $this->viewer; return $this->viewer;
} }
final public function setCustomFieldStorage(array $custom_field_storage) {
$this->customFieldStorage = $custom_field_storage;
return $this;
}
final public function getCustomFieldStorage() {
return $this->customFieldStorage;
}
abstract public function getFieldName(); abstract public function getFieldName();
abstract public function getFieldOrder();
public function isFieldEnabled() { public function isFieldEnabled() {
return true; return true;
@ -32,6 +43,30 @@ abstract class DifferentialCommitMessageField
return $value; return $value;
} }
public function isFieldEditable() {
return true;
}
public function isTemplateField() {
return true;
}
public function readFieldValueFromConduit($value) {
return $this->readStringFieldValueFromConduit($value);
}
public function readFieldValueFromObject(DifferentialRevision $revision) {
return null;
}
public function renderFieldValue($value) {
if (!strlen($value)) {
return null;
}
return $value;
}
final public function getCommitMessageFieldKey() { final public function getCommitMessageFieldKey() {
return $this->getPhobjectClassConstant('FIELDKEY', 64); return $this->getPhobjectClassConstant('FIELDKEY', 64);
} }
@ -55,6 +90,7 @@ abstract class DifferentialCommitMessageField
return id(new PhutilClassMapQuery()) return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__) ->setAncestorClass(__CLASS__)
->setUniqueMethod('getCommitMessageFieldKey') ->setUniqueMethod('getCommitMessageFieldKey')
->setSortMethod('getFieldOrder')
->execute(); ->execute();
} }
@ -80,6 +116,62 @@ abstract class DifferentialCommitMessageField
->execute(); ->execute();
} }
protected function renderHandleList(array $phids, array $suffixes = array()) {
if (!$phids) {
return null;
}
$handles = $this->getViewer()->loadHandles($phids);
$out = array();
foreach ($handles as $handle) {
$phid = $handle->getPHID();
if ($handle->getPolicyFiltered()) {
$token = $phid;
} else if ($handle->isComplete()) {
$token = $handle->getCommandLineObjectName();
}
$suffix = idx($suffixes, $phid);
$token = $token.$suffix;
$out[] = $token;
}
return implode(', ', $out);
}
protected function readStringFieldValueFromConduit($value) {
if ($value === null) {
return $value;
}
if (!is_string($value)) {
throw new Exception(
pht(
'Field "%s" expects a string value, but received a value of type '.
'"%s".',
$this->getCommitMessageFieldKey(),
gettype($value)));
}
return $value;
}
protected function readStringListFieldValueFromConduit($value) {
if (!is_array($value)) {
throw new Exception(
pht(
'Field "%s" expects a list of strings, but received a value of type '.
'"%s".',
$this->getCommitMessageFieldKey(),
gettype($value)));
}
return $value;
}
protected function isCustomFieldEnabled($key) { protected function isCustomFieldEnabled($key) {
$field_list = PhabricatorCustomField::getObjectFields( $field_list = PhabricatorCustomField::getObjectFields(
new DifferentialRevision(), new DifferentialRevision(),

View file

@ -9,4 +9,12 @@ final class DifferentialConflictsCommitMessageField
return pht('Conflicts'); return pht('Conflicts');
} }
public function getFieldOrder() {
return 900000;
}
public function isFieldEditable() {
return false;
}
} }

View file

@ -9,4 +9,12 @@ final class DifferentialGitSVNIDCommitMessageField
return pht('git-svn-id'); return pht('git-svn-id');
} }
public function getFieldOrder() {
return 900001;
}
public function isFieldEditable() {
return false;
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
final class DifferentialJIRAIssuesCommitMessageField final class DifferentialJIRAIssuesCommitMessageField
extends DifferentialCommitMessageField { extends DifferentialCommitMessageCustomField {
const FIELDKEY = 'jira.issues'; const FIELDKEY = 'jira.issues';
@ -16,12 +16,28 @@ final class DifferentialJIRAIssuesCommitMessageField
); );
} }
public function getCustomFieldKey() {
return 'phabricator:jira-issues';
}
public function parseFieldValue($value) { public function parseFieldValue($value) {
return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY); return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY);
} }
public function isFieldEnabled() { protected function readFieldValueFromCustomFieldStorage($value) {
return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider(); return $this->readJSONFieldValueFromCustomFieldStorage($value, array());
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
if (!$value) {
return null;
}
return implode(', ', $value);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
final class DifferentialRevertPlanCommitMessageField final class DifferentialRevertPlanCommitMessageField
extends DifferentialCommitMessageField { extends DifferentialCommitMessageCustomField {
const FIELDKEY = 'revertPlan'; const FIELDKEY = 'revertPlan';
@ -9,8 +9,8 @@ final class DifferentialRevertPlanCommitMessageField
return pht('Revert Plan'); return pht('Revert Plan');
} }
public function isFieldEnabled() { public function getCustomFieldKey() {
return $this->isCustomFieldEnabled('phabricator:revert-plan'); return 'phabricator:revert-plan';
} }
} }

View file

@ -9,6 +9,10 @@ final class DifferentialReviewedByCommitMessageField
return pht('Reviewed By'); return pht('Reviewed By');
} }
public function getFieldOrder() {
return 5000;
}
public function parseFieldValue($value) { public function parseFieldValue($value) {
return $this->parseObjectList( return $this->parseObjectList(
$value, $value,
@ -19,4 +23,34 @@ final class DifferentialReviewedByCommitMessageField
$allow_partial = true); $allow_partial = true);
} }
public function isFieldEditable() {
return false;
}
public function readFieldValueFromObject(DifferentialRevision $revision) {
if (!$revision->getPHID()) {
return array();
}
$phids = array();
foreach ($revision->getReviewerStatus() as $reviewer) {
switch ($reviewer->getStatus()) {
case DifferentialReviewerStatus::STATUS_ACCEPTED:
case DifferentialReviewerStatus::STATUS_ACCEPTED_OLDER:
$phids[] = $reviewer->getReviewerPHID();
break;
}
}
return $phids;
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
return $this->renderHandleList($value);
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialReviewersCommitMessageField
return pht('Reviewers'); return pht('Reviewers');
} }
public function getFieldOrder() {
return 4000;
}
public function getFieldAliases() { public function getFieldAliases() {
return array( return array(
'Reviewer', 'Reviewer',
@ -29,6 +33,50 @@ final class DifferentialReviewersCommitMessageField
return $this->flattenReviewers($results); return $this->flattenReviewers($results);
} }
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function readFieldValueFromObject(DifferentialRevision $revision) {
if (!$revision->getPHID()) {
return array();
}
$status_blocking = DifferentialReviewerStatus::STATUS_BLOCKING;
$results = array();
foreach ($revision->getReviewerStatus() as $reviewer) {
if ($reviewer->getStatus() == $status_blocking) {
$suffixes = array('!' => '!');
} else {
$suffixes = array();
}
$results[] = array(
'phid' => $reviewer->getReviewerPHID(),
'suffixes' => $suffixes,
);
}
return $this->flattenReviewers($results);
}
public function renderFieldValue($value) {
$value = $this->inflateReviewers($value);
$phid_list = array();
$suffix_map = array();
foreach ($value as $reviewer) {
$phid = $reviewer['phid'];
$phid_list[] = $phid;
if (isset($reviewer['suffixes']['!'])) {
$suffix_map[$phid] = '!';
}
}
return $this->renderHandleList($phid_list, $suffix_map);
}
private function flattenReviewers(array $values) { private function flattenReviewers(array $values) {
// NOTE: For now, `arc` relies on this field returning only scalars, so we // NOTE: For now, `arc` relies on this field returning only scalars, so we
// need to reduce the results into scalars. See T10981. // need to reduce the results into scalars. See T10981.

View file

@ -9,6 +9,14 @@ final class DifferentialRevisionIDCommitMessageField
return pht('Differential Revision'); return pht('Differential Revision');
} }
public function getFieldOrder() {
return 200000;
}
public function isTemplateField() {
return false;
}
public function parseFieldValue($value) { public function parseFieldValue($value) {
// If the value is just "D123" or similar, parse the ID from it directly. // If the value is just "D123" or similar, parse the ID from it directly.
$value = trim($value); $value = trim($value);
@ -49,4 +57,23 @@ final class DifferentialRevisionIDCommitMessageField
return null; return null;
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
return $revision->getID();
}
public function readFieldValueFromConduit($value) {
if (is_int($value)) {
$value = (string)$value;
}
return $this->readStringFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
if (!strlen($value)) {
return null;
}
return PhabricatorEnv::getProductionURI('/D'.$value);
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialSubscribersCommitMessageField
return pht('Subscribers'); return pht('Subscribers');
} }
public function getFieldOrder() {
return 6000;
}
public function getFieldAliases() { public function getFieldAliases() {
return array( return array(
'CC', 'CC',
@ -27,4 +31,21 @@ final class DifferentialSubscribersCommitMessageField
)); ));
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
if (!$revision->getPHID()) {
return array();
}
return PhabricatorSubscribersQuery::loadSubscribersForPHID(
$revision->getPHID());
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
return $this->renderHandleList($value);
}
} }

View file

@ -9,4 +9,12 @@ final class DifferentialSummaryCommitMessageField
return pht('Summary'); return pht('Summary');
} }
public function getFieldOrder() {
return 2000;
}
public function readFieldValueFromObject(DifferentialRevision $revision) {
return $revision->getSummary();
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialTagsCommitMessageField
return pht('Tags'); return pht('Tags');
} }
public function getFieldOrder() {
return 7000;
}
public function getFieldAliases() { public function getFieldAliases() {
return array( return array(
'Tag', 'Tag',
@ -17,6 +21,10 @@ final class DifferentialTagsCommitMessageField
); );
} }
public function isTemplateField() {
return false;
}
public function parseFieldValue($value) { public function parseFieldValue($value) {
return $this->parseObjectList( return $this->parseObjectList(
$value, $value,
@ -25,4 +33,26 @@ final class DifferentialTagsCommitMessageField
)); ));
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
if (!$revision->getPHID()) {
return array();
}
$projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$revision->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
$projects = array_reverse($projects);
return $projects;
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
return $this->renderHandleList($value);
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialTasksCommitMessageField
return pht('Maniphest Tasks'); return pht('Maniphest Tasks');
} }
public function getFieldOrder() {
return 8000;
}
public function getFieldAliases() { public function getFieldAliases() {
return array( return array(
'Task', 'Task',
@ -17,6 +21,10 @@ final class DifferentialTasksCommitMessageField
); );
} }
public function isTemplateField() {
return false;
}
public function parseFieldValue($value) { public function parseFieldValue($value) {
return $this->parseObjectList( return $this->parseObjectList(
$value, $value,
@ -25,4 +33,25 @@ final class DifferentialTasksCommitMessageField
)); ));
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
if (!$revision->getPHID()) {
return array();
}
$projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$revision->getPHID(),
DifferentialRevisionHasTaskEdgeType::EDGECONST);
$projects = array_reverse($projects);
return $projects;
}
public function readFieldValueFromConduit($value) {
return $this->readStringListFieldValueFromConduit($value);
}
public function renderFieldValue($value) {
return $this->renderHandleList($value);
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialTestPlanCommitMessageField
return pht('Test Plan'); return pht('Test Plan');
} }
public function getFieldOrder() {
return 3000;
}
public function getFieldAliases() { public function getFieldAliases() {
return array( return array(
'Testplan', 'Testplan',
@ -33,4 +37,8 @@ final class DifferentialTestPlanCommitMessageField
} }
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
return $revision->getTestPlan();
}
} }

View file

@ -9,6 +9,10 @@ final class DifferentialTitleCommitMessageField
return pht('Title'); return pht('Title');
} }
public function getFieldOrder() {
return 1000;
}
public static function getDefaultTitle() { public static function getDefaultTitle() {
return pht('<<Replace this line with your revision title>'); return pht('<<Replace this line with your revision title>');
} }
@ -33,4 +37,14 @@ final class DifferentialTitleCommitMessageField
} }
} }
public function readFieldValueFromObject(DifferentialRevision $revision) {
$value = $revision->getTitle();
if (!strlen($value)) {
return self::getDefaultTitle();
}
return $value;
}
} }

View file

@ -70,6 +70,7 @@ final class DifferentialRevision extends DifferentialDAO
->setAuthorPHID($actor->getPHID()) ->setAuthorPHID($actor->getPHID())
->attachRelationships(array()) ->attachRelationships(array())
->attachRepository(null) ->attachRepository(null)
->attachActiveDiff(null)
->attachReviewerStatus(array()) ->attachReviewerStatus(array())
->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
} }