mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Partially move Releeph custom fields to PhabricatorCustomField
Summary: Fixes T3661. Ref T3718. This makes Releeph custom fields extend PhabricatorCustomField so we can start moving over other pieces of infrastructure (rendering, storage, etc) to run through the same pathways. It's roughly the minimum amount of work required to be able to move forward. NOTE: This removes per-project custom field selectors. Fields are now configured for an entire install. My understanding is that Facebook does not use this feature, and modern field infrastructure has moved away from selectors. Test Plan: Viewed and edited projects, branches, and requests in Releeph. Grepped for removed config. Grepped for `field_selector`. Reviewers: btrahan Reviewed By: btrahan CC: LegNeato, aran Maniphest Tasks: T3661, T3718 Differential Revision: https://secure.phabricator.com/D6750
This commit is contained in:
parent
ca0115b361
commit
74de24909b
24 changed files with 121 additions and 63 deletions
|
@ -4141,7 +4141,11 @@ phutil_register_library_map(array(
|
|||
'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
|
||||
'ReleephEvent' => 'ReleephDAO',
|
||||
'ReleephFieldParseException' => 'Exception',
|
||||
'ReleephFieldSpecification' => 'PhabricatorMarkupInterface',
|
||||
'ReleephFieldSpecification' =>
|
||||
array(
|
||||
0 => 'PhabricatorCustomField',
|
||||
1 => 'PhabricatorMarkupInterface',
|
||||
),
|
||||
'ReleephFieldSpecificationIncompleteException' => 'Exception',
|
||||
'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
|
||||
'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
|
||||
|
|
|
@ -12,6 +12,37 @@ final class PhabricatorApplicationReleephConfigOptions
|
|||
}
|
||||
|
||||
public function getOptions() {
|
||||
|
||||
$default_fields = array(
|
||||
new ReleephCommitMessageFieldSpecification(),
|
||||
new ReleephSummaryFieldSpecification(),
|
||||
new ReleephReasonFieldSpecification(),
|
||||
new ReleephAuthorFieldSpecification(),
|
||||
new ReleephRevisionFieldSpecification(),
|
||||
new ReleephRequestorFieldSpecification(),
|
||||
new ReleephSeverityFieldSpecification(),
|
||||
new ReleephOriginalCommitFieldSpecification(),
|
||||
new ReleephDiffMessageFieldSpecification(),
|
||||
new ReleephStatusFieldSpecification(),
|
||||
new ReleephIntentFieldSpecification(),
|
||||
new ReleephBranchCommitFieldSpecification(),
|
||||
new ReleephDiffSizeFieldSpecification(),
|
||||
new ReleephDiffChurnFieldSpecification(),
|
||||
);
|
||||
|
||||
$default = array();
|
||||
foreach ($default_fields as $default_field) {
|
||||
$default[$default_field->getFieldKey()] = true;
|
||||
}
|
||||
|
||||
foreach ($default as $key => $enabled) {
|
||||
$default[$key] = array(
|
||||
'disabled' => !$enabled,
|
||||
);
|
||||
}
|
||||
|
||||
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
||||
|
||||
return array(
|
||||
$this->newOption('releeph.installed', 'bool', false)
|
||||
->setSummary(pht('Enable the Releeph application.'))
|
||||
|
@ -26,16 +57,8 @@ final class PhabricatorApplicationReleephConfigOptions
|
|||
"set of alpha testers at Facebook. For the time being you are ".
|
||||
"strongly discouraged from relying on Releeph being at all ".
|
||||
"stable.")),
|
||||
$this->newOption(
|
||||
'releeph.field-selector',
|
||||
'class',
|
||||
'ReleephDefaultFieldSelector')
|
||||
->setBaseClass('ReleephFieldSelector')
|
||||
->setSummary(pht('Field selector class'))
|
||||
->setDescription(
|
||||
pht(
|
||||
"Control which fields are available when making a new Releeph ".
|
||||
"request, and which are then shown in the Releeph UI.")),
|
||||
$this->newOption('releeph.fields', $custom_field_type, $default)
|
||||
->setCustomData('ReleephFieldSpecification'),
|
||||
$this->newOption(
|
||||
'releeph.user-view',
|
||||
'class',
|
||||
|
|
|
@ -31,9 +31,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
|||
$test_paths = $this->getReleephProject()->getDetail('testPaths', array());
|
||||
}
|
||||
|
||||
$field_selector = $request->getStr('fieldSelector',
|
||||
get_class($this->getReleephProject()->getReleephFieldSelector()));
|
||||
|
||||
$release_counter = $request->getInt(
|
||||
'releaseCounter',
|
||||
$this->getReleephProject()->getCurrentReleaseNumber());
|
||||
|
@ -82,7 +79,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
|||
->setTrunkBranch($trunk_branch)
|
||||
->setDetail('pushers', $pusher_phids)
|
||||
->setDetail('pick_failure_instructions', $pick_failure_instructions)
|
||||
->setDetail('field_selector', $field_selector)
|
||||
->setDetail('branchTemplate', $branch_template)
|
||||
->setDetail('commitWithAuthor', $commit_author)
|
||||
->setDetail('testPaths', $test_paths);
|
||||
|
@ -214,32 +210,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
|||
->setDatasource('/typeahead/common/users/')
|
||||
->setValue($pusher_tokens));
|
||||
|
||||
$field_selector_options = array();
|
||||
$field_selector_symbols = id(new PhutilSymbolLoader())
|
||||
->setType('class')
|
||||
->setConcreteOnly(true)
|
||||
->setAncestorClass('ReleephFieldSelector')
|
||||
->selectAndLoadSymbols();
|
||||
foreach ($field_selector_symbols as $symbol) {
|
||||
$selector_name = $symbol['name'];
|
||||
$field_selector_options[$selector_name] = $selector_name;
|
||||
}
|
||||
|
||||
$field_selector_blurb = pht(
|
||||
"If you you have additional information to render about Releeph ".
|
||||
"requests, or want to re-arrange the UI, implement a ".
|
||||
"<tt>ReleephFieldSelector</tt> and select it here.");
|
||||
|
||||
$fields_inset = id(new AphrontFormInsetView())
|
||||
->setTitle(pht('Fields'))
|
||||
->appendChild($field_selector_blurb)
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Selector'))
|
||||
->setName('fieldSelector')
|
||||
->setValue($field_selector)
|
||||
->setOptions($field_selector_options));
|
||||
|
||||
$commit_author_inset = $this->buildCommitAuthorInset($commit_author);
|
||||
|
||||
// Build the Template inset
|
||||
|
@ -276,7 +246,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
|||
->setUser($request->getUser())
|
||||
->appendChild($basic_inset)
|
||||
->appendChild($pushers_inset)
|
||||
->appendChild($fields_inset)
|
||||
->appendChild($commit_author_inset)
|
||||
->appendChild($template_inset);
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ final class ReleephRequestEditController extends ReleephProjectController {
|
|||
// Fields
|
||||
foreach ($fields as $field) {
|
||||
if ($field->isEditable()) {
|
||||
$control = $field->renderEditControl($request);
|
||||
$control = $field->renderReleephEditControl($request);
|
||||
$form->appendChild($control);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ final class ReleephAuthorFieldSpecification
|
|||
|
||||
private static $authorMap = array();
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'author';
|
||||
}
|
||||
|
||||
public function bulkLoad(array $releeph_requests) {
|
||||
foreach ($releeph_requests as $releeph_request) {
|
||||
$commit = $releeph_request->loadPhabricatorRepositoryCommit();
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephBranchCommitFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'commit';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Commit';
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephCommitMessageFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'commit:apply';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return '__only_for_commit_message!';
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ final class ReleephDiffChurnFieldSpecification
|
|||
const UPDATES_WEIGHT = 10;
|
||||
const MAX_POINTS = 100;
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'churn';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Churn';
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephDiffMessageFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'commit:message';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Message';
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@ final class ReleephDiffSizeFieldSpecification
|
|||
const PATHS_WEIGHT = 30;
|
||||
const MAX_POINTS = 1000;
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'commit:size';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Size';
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
abstract class ReleephFieldSpecification
|
||||
extends PhabricatorCustomField
|
||||
implements PhabricatorMarkupInterface {
|
||||
|
||||
abstract public function getName();
|
||||
|
@ -83,7 +84,7 @@ abstract class ReleephFieldSpecification
|
|||
|
||||
/* -( Edit View )---------------------------------------------------------- */
|
||||
|
||||
public function renderEditControl(AphrontRequest $request) {
|
||||
public function renderReleephEditControl(AphrontRequest $request) {
|
||||
throw new ReleephFieldSpecificationIncompleteException($this);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephIntentFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'intent';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Intent';
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ abstract class ReleephLevelFieldSpecification
|
|||
return $this->getNameForLevel($level);
|
||||
}
|
||||
|
||||
public function renderEditControl(AphrontRequest $request) {
|
||||
public function renderReleephEditControl(AphrontRequest $request) {
|
||||
$control_name = $this->getRequiredStorageKey();
|
||||
$all_levels = $this->getLevels();
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephOriginalCommitFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'commit:name';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Commit';
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephReasonFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'reason';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Reason';
|
||||
}
|
||||
|
@ -31,7 +35,7 @@ final class ReleephReasonFieldSpecification
|
|||
|
||||
private $error = true;
|
||||
|
||||
public function renderEditControl(AphrontRequest $request) {
|
||||
public function renderReleephEditControl(AphrontRequest $request) {
|
||||
$reason = $request->getStr('reason', $this->getValue());
|
||||
return id(new AphrontFormTextAreaControl())
|
||||
->setLabel('Reason')
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephRequestorFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'requestor';
|
||||
}
|
||||
|
||||
public function bulkLoad(array $releeph_requests) {
|
||||
$phids = mpull($releeph_requests, 'getRequestUserPHID');
|
||||
ReleephUserView::getNewInstance()
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephRevisionFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'revision';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Revision';
|
||||
}
|
||||
|
|
|
@ -9,6 +9,10 @@ final class ReleephRiskFieldSpecification
|
|||
'HIGH' => 'This is pretty risky, but is also very important.',
|
||||
);
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'risk';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Riskiness';
|
||||
}
|
||||
|
@ -23,7 +27,7 @@ final class ReleephRiskFieldSpecification
|
|||
|
||||
private $error = true;
|
||||
|
||||
public function renderEditControl(AphrontRequest $request) {
|
||||
public function renderReleephEditControl(AphrontRequest $request) {
|
||||
$value = $request->getStr('risk', $this->getValue());
|
||||
$buttons = id(new AphrontFormRadioButtonControl())
|
||||
->setLabel('Riskiness')
|
||||
|
|
|
@ -6,6 +6,10 @@ final class ReleephSeverityFieldSpecification
|
|||
const HOTFIX = 'HOTFIX';
|
||||
const RELEASE = 'RELEASE';
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'severity';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Severity';
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class ReleephStatusFieldSpecification
|
||||
extends ReleephFieldSpecification {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'status';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Status';
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ final class ReleephSummaryFieldSpecification
|
|||
|
||||
const MAX_SUMMARY_LENGTH = 60;
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'summary';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Summary';
|
||||
}
|
||||
|
@ -15,7 +19,7 @@ final class ReleephSummaryFieldSpecification
|
|||
|
||||
private $error = false;
|
||||
|
||||
public function renderEditControl(AphrontRequest $request) {
|
||||
public function renderReleephEditControl(AphrontRequest $request) {
|
||||
$summary = $request->getStr('summary', $this->getValue());
|
||||
return id(new AphrontFormTextControl())
|
||||
->setLabel('Summary')
|
||||
|
|
|
@ -141,17 +141,7 @@ final class ReleephProject extends ReleephDAO
|
|||
}
|
||||
|
||||
public function getReleephFieldSelector() {
|
||||
$class = $this->getDetail('field_selector');
|
||||
if (!$class) {
|
||||
$key = 'releeph.field-selector';
|
||||
$class = PhabricatorEnv::getEnvConfig($key);
|
||||
}
|
||||
|
||||
if ($class) {
|
||||
return newv($class, array());
|
||||
} else {
|
||||
return new ReleephDefaultFieldSelector();
|
||||
}
|
||||
return new ReleephDefaultFieldSelector();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,9 +3,18 @@
|
|||
final class PhabricatorCustomFieldImplementationIncompleteException
|
||||
extends Exception {
|
||||
|
||||
public function __construct(PhabricatorCustomField $field) {
|
||||
$key = $field->getFieldKey();
|
||||
$name = $field->getFieldName();
|
||||
public function __construct(
|
||||
PhabricatorCustomField $field,
|
||||
$field_key_is_incomplete = false) {
|
||||
|
||||
if ($field_key_is_incomplete) {
|
||||
$key = pht('<incomplete key>');
|
||||
$name = pht('<incomplete name>');
|
||||
} else {
|
||||
$key = $field->getFieldKey();
|
||||
$name = $field->getFieldName();
|
||||
}
|
||||
|
||||
$class = get_class($field);
|
||||
|
||||
parent::__construct(
|
||||
|
|
|
@ -154,7 +154,9 @@ abstract class PhabricatorCustomField {
|
|||
if ($this->proxy) {
|
||||
return $this->proxy->getFieldKey();
|
||||
}
|
||||
throw new PhabricatorCustomFieldImplementationIncompleteException($this);
|
||||
throw new PhabricatorCustomFieldImplementationIncompleteException(
|
||||
$this,
|
||||
$field_key_is_incomplete = true);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue