mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-19 03:01:11 +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:
parent
0387d62632
commit
24926f9453
20 changed files with 499 additions and 112 deletions
|
@ -385,6 +385,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php',
|
||||
'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
|
||||
'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
|
||||
'DifferentialCommitMessageCustomField' => 'applications/differential/field/DifferentialCommitMessageCustomField.php',
|
||||
'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php',
|
||||
'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php',
|
||||
'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php',
|
||||
|
@ -4996,10 +4997,10 @@ phutil_register_library_map(array(
|
|||
'DifferentialAffectedPath' => 'DifferentialDAO',
|
||||
'DifferentialApplyPatchField' => 'DifferentialCustomField',
|
||||
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
|
||||
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialAuthorField' => 'DifferentialCustomField',
|
||||
'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialBlockHeraldAction' => 'HeraldAction',
|
||||
'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
|
@ -5031,6 +5032,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
'DifferentialCommentPreviewController' => 'DifferentialController',
|
||||
'DifferentialCommentSaveController' => 'DifferentialController',
|
||||
'DifferentialCommitMessageCustomField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialCommitMessageField' => 'Phobject',
|
||||
'DifferentialCommitMessageParser' => 'Phobject',
|
||||
'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase',
|
||||
|
@ -5125,7 +5127,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialInlineCommentMailView' => 'DifferentialMailView',
|
||||
'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
||||
'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener',
|
||||
'DifferentialLandingStrategy' => 'Phobject',
|
||||
|
@ -5158,7 +5160,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
|
||||
|
|
|
@ -47,94 +47,71 @@ final class DifferentialGetCommitMessageConduitAPIMethod
|
|||
}
|
||||
} else {
|
||||
$revision = DifferentialRevision::initializeNewRevision($viewer);
|
||||
$revision->attachReviewerStatus(array());
|
||||
$revision->attachActiveDiff(null);
|
||||
}
|
||||
|
||||
$is_edit = $request->getValue('edit');
|
||||
$is_create = ($is_edit == 'create');
|
||||
$edit_mode = $request->getValue('edit');
|
||||
$is_create = ($edit_mode == 'create');
|
||||
$is_edit = ($edit_mode && !$is_create);
|
||||
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
$revision,
|
||||
($is_edit
|
||||
? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT
|
||||
: DifferentialCustomField::ROLE_COMMITMESSAGE));
|
||||
$field_list = DifferentialCommitMessageField::newEnabledFields($viewer);
|
||||
|
||||
$field_list
|
||||
->setViewer($viewer)
|
||||
->readFieldsFromStorage($revision);
|
||||
|
||||
$field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
|
||||
$custom_storage = $this->loadCustomFieldStorage($viewer, $revision);
|
||||
foreach ($field_list as $field) {
|
||||
$field->setCustomFieldStorage($custom_storage);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
$fields = $request->getValue('fields', array());
|
||||
foreach ($fields as $field => $value) {
|
||||
$custom_field = idx($field_map, $field);
|
||||
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);
|
||||
foreach ($field_list as $field_key => $field) {
|
||||
if (!$field->isFieldEditable()) {
|
||||
unset($field_list[$field_key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$phids = array();
|
||||
foreach ($field_list->getFields() as $key => $field) {
|
||||
$field_phids = $field->getRequiredHandlePHIDsForCommitMessage();
|
||||
if (!is_array($field_phids)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Custom field "%s" was expected to return an array of handle '.
|
||||
'PHIDs required for commit message rendering, but returned "%s" '.
|
||||
'instead.',
|
||||
$field->getFieldKey(),
|
||||
gettype($field_phids)));
|
||||
$overrides = $request->getValue('fields', array());
|
||||
|
||||
$value_map = array();
|
||||
foreach ($field_list as $field_key => $field) {
|
||||
if (array_key_exists($field_key, $overrides)) {
|
||||
$field_value = $overrides[$field_key];
|
||||
} else {
|
||||
$field_value = $field->readFieldValueFromObject($revision);
|
||||
}
|
||||
$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);
|
||||
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();
|
||||
$key_title = DifferentialTitleCommitMessageField::FIELDKEY;
|
||||
|
||||
$commit_message = array();
|
||||
foreach ($field_list->getFields() as $key => $field) {
|
||||
$handles = array_select_keys($all_handles, $phids[$key]);
|
||||
foreach ($field_list as $field_key => $field) {
|
||||
$label = $field->getFieldName();
|
||||
$wire_value = $value_map[$field_key];
|
||||
$value = $field->renderFieldValue($wire_value);
|
||||
|
||||
$label = $field->renderCommitMessageLabel();
|
||||
$value = $field->renderCommitMessageValue($handles);
|
||||
$is_template = ($is_edit && $field->isTemplateField());
|
||||
|
||||
if (!is_string($value) && !is_null($value)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Custom field "%s" was expected to render a string or null value, '.
|
||||
'but rendered a "%s" instead.',
|
||||
'Commit message field "%s" was expected to render a string or '.
|
||||
'null value, but rendered a "%s" instead.',
|
||||
$field->getFieldKey(),
|
||||
gettype($value)));
|
||||
}
|
||||
|
||||
$is_title = ($key == $key_title);
|
||||
$is_title = ($field_key == $key_title);
|
||||
|
||||
if (!strlen($value)) {
|
||||
if ($is_title) {
|
||||
$commit_message[] = $default_title;
|
||||
} else {
|
||||
if ($is_edit && $field->shouldAppearInCommitMessageTemplate()) {
|
||||
$commit_message[] = $label.': ';
|
||||
}
|
||||
if ($is_template) {
|
||||
$commit_message[] = $label.': ';
|
||||
}
|
||||
} else {
|
||||
if ($is_title) {
|
||||
|
@ -153,46 +130,31 @@ final class DifferentialGetCommitMessageConduitAPIMethod
|
|||
}
|
||||
}
|
||||
|
||||
if ($is_edit) {
|
||||
$tip = $this->getProTip($field_list);
|
||||
if ($tip !== null) {
|
||||
$commit_message[] = "\n".$tip;
|
||||
return implode("\n\n", $commit_message);
|
||||
}
|
||||
|
||||
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 $commit_message;
|
||||
return $custom_field_map;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialAuditorsCommitMessageField
|
||||
extends DifferentialCommitMessageField {
|
||||
extends DifferentialCommitMessageCustomField {
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialBlameRevisionCommitMessageField
|
||||
extends DifferentialCommitMessageField {
|
||||
extends DifferentialCommitMessageCustomField {
|
||||
|
||||
const FIELDKEY = 'blameRevision';
|
||||
|
||||
|
@ -15,8 +15,8 @@ final class DifferentialBlameRevisionCommitMessageField
|
|||
);
|
||||
}
|
||||
|
||||
public function isFieldEnabled() {
|
||||
return $this->isCustomFieldEnabled('phabricator:blame-revision');
|
||||
public function getCustomFieldKey() {
|
||||
return 'phabricator:blame-revision';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ abstract class DifferentialCommitMessageField
|
|||
extends Phobject {
|
||||
|
||||
private $viewer;
|
||||
private $customFieldStorage;
|
||||
|
||||
final public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
|
@ -14,7 +15,17 @@ abstract class DifferentialCommitMessageField
|
|||
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 getFieldOrder();
|
||||
|
||||
public function isFieldEnabled() {
|
||||
return true;
|
||||
|
@ -32,6 +43,30 @@ abstract class DifferentialCommitMessageField
|
|||
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() {
|
||||
return $this->getPhobjectClassConstant('FIELDKEY', 64);
|
||||
}
|
||||
|
@ -55,6 +90,7 @@ abstract class DifferentialCommitMessageField
|
|||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
->setUniqueMethod('getCommitMessageFieldKey')
|
||||
->setSortMethod('getFieldOrder')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
@ -80,6 +116,62 @@ abstract class DifferentialCommitMessageField
|
|||
->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) {
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
new DifferentialRevision(),
|
||||
|
|
|
@ -9,4 +9,12 @@ final class DifferentialConflictsCommitMessageField
|
|||
return pht('Conflicts');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 900000;
|
||||
}
|
||||
|
||||
public function isFieldEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,4 +9,12 @@ final class DifferentialGitSVNIDCommitMessageField
|
|||
return pht('git-svn-id');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 900001;
|
||||
}
|
||||
|
||||
public function isFieldEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialJIRAIssuesCommitMessageField
|
||||
extends DifferentialCommitMessageField {
|
||||
extends DifferentialCommitMessageCustomField {
|
||||
|
||||
const FIELDKEY = 'jira.issues';
|
||||
|
||||
|
@ -16,12 +16,28 @@ final class DifferentialJIRAIssuesCommitMessageField
|
|||
);
|
||||
}
|
||||
|
||||
public function getCustomFieldKey() {
|
||||
return 'phabricator:jira-issues';
|
||||
}
|
||||
|
||||
public function parseFieldValue($value) {
|
||||
return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
|
||||
public function isFieldEnabled() {
|
||||
return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider();
|
||||
protected function readFieldValueFromCustomFieldStorage($value) {
|
||||
return $this->readJSONFieldValueFromCustomFieldStorage($value, array());
|
||||
}
|
||||
|
||||
public function readFieldValueFromConduit($value) {
|
||||
return $this->readStringListFieldValueFromConduit($value);
|
||||
}
|
||||
|
||||
public function renderFieldValue($value) {
|
||||
if (!$value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return implode(', ', $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialRevertPlanCommitMessageField
|
||||
extends DifferentialCommitMessageField {
|
||||
extends DifferentialCommitMessageCustomField {
|
||||
|
||||
const FIELDKEY = 'revertPlan';
|
||||
|
||||
|
@ -9,8 +9,8 @@ final class DifferentialRevertPlanCommitMessageField
|
|||
return pht('Revert Plan');
|
||||
}
|
||||
|
||||
public function isFieldEnabled() {
|
||||
return $this->isCustomFieldEnabled('phabricator:revert-plan');
|
||||
public function getCustomFieldKey() {
|
||||
return 'phabricator:revert-plan';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialReviewedByCommitMessageField
|
|||
return pht('Reviewed By');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 5000;
|
||||
}
|
||||
|
||||
public function parseFieldValue($value) {
|
||||
return $this->parseObjectList(
|
||||
$value,
|
||||
|
@ -19,4 +23,34 @@ final class DifferentialReviewedByCommitMessageField
|
|||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialReviewersCommitMessageField
|
|||
return pht('Reviewers');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 4000;
|
||||
}
|
||||
|
||||
public function getFieldAliases() {
|
||||
return array(
|
||||
'Reviewer',
|
||||
|
@ -29,6 +33,50 @@ final class DifferentialReviewersCommitMessageField
|
|||
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) {
|
||||
// NOTE: For now, `arc` relies on this field returning only scalars, so we
|
||||
// need to reduce the results into scalars. See T10981.
|
||||
|
|
|
@ -9,6 +9,14 @@ final class DifferentialRevisionIDCommitMessageField
|
|||
return pht('Differential Revision');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 200000;
|
||||
}
|
||||
|
||||
public function isTemplateField() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseFieldValue($value) {
|
||||
// If the value is just "D123" or similar, parse the ID from it directly.
|
||||
$value = trim($value);
|
||||
|
@ -49,4 +57,23 @@ final class DifferentialRevisionIDCommitMessageField
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialSubscribersCommitMessageField
|
|||
return pht('Subscribers');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getFieldAliases() {
|
||||
return array(
|
||||
'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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,4 +9,12 @@ final class DifferentialSummaryCommitMessageField
|
|||
return pht('Summary');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
public function readFieldValueFromObject(DifferentialRevision $revision) {
|
||||
return $revision->getSummary();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialTagsCommitMessageField
|
|||
return pht('Tags');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 7000;
|
||||
}
|
||||
|
||||
public function getFieldAliases() {
|
||||
return array(
|
||||
'Tag',
|
||||
|
@ -17,6 +21,10 @@ final class DifferentialTagsCommitMessageField
|
|||
);
|
||||
}
|
||||
|
||||
public function isTemplateField() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseFieldValue($value) {
|
||||
return $this->parseObjectList(
|
||||
$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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialTasksCommitMessageField
|
|||
return pht('Maniphest Tasks');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 8000;
|
||||
}
|
||||
|
||||
public function getFieldAliases() {
|
||||
return array(
|
||||
'Task',
|
||||
|
@ -17,6 +21,10 @@ final class DifferentialTasksCommitMessageField
|
|||
);
|
||||
}
|
||||
|
||||
public function isTemplateField() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseFieldValue($value) {
|
||||
return $this->parseObjectList(
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialTestPlanCommitMessageField
|
|||
return pht('Test Plan');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 3000;
|
||||
}
|
||||
|
||||
public function getFieldAliases() {
|
||||
return array(
|
||||
'Testplan',
|
||||
|
@ -33,4 +37,8 @@ final class DifferentialTestPlanCommitMessageField
|
|||
}
|
||||
}
|
||||
|
||||
public function readFieldValueFromObject(DifferentialRevision $revision) {
|
||||
return $revision->getTestPlan();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class DifferentialTitleCommitMessageField
|
|||
return pht('Title');
|
||||
}
|
||||
|
||||
public function getFieldOrder() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public static function getDefaultTitle() {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ final class DifferentialRevision extends DifferentialDAO
|
|||
->setAuthorPHID($actor->getPHID())
|
||||
->attachRelationships(array())
|
||||
->attachRepository(null)
|
||||
->attachActiveDiff(null)
|
||||
->attachReviewerStatus(array())
|
||||
->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue