1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 10:42:41 +01:00

Move most Herald field configuration into dynamic Adapters

Summary: Ref T2769. Herald has a giant hard-coded list of fields. Primarily make these dynamic and adapter-based.

Test Plan: Viewed and edited Herald rules.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2769

Differential Revision: https://secure.phabricator.com/D6657
This commit is contained in:
epriestley 2013-08-02 10:25:45 -07:00
parent 6badb05d64
commit 3490b6dd11
8 changed files with 127 additions and 65 deletions

View file

@ -2,6 +2,20 @@
abstract class HeraldAdapter { abstract class HeraldAdapter {
const FIELD_TITLE = 'title';
const FIELD_BODY = 'body';
const FIELD_AUTHOR = 'author';
const FIELD_REVIEWER = 'reviewer';
const FIELD_REVIEWERS = 'reviewers';
const FIELD_CC = 'cc';
const FIELD_TAGS = 'tags';
const FIELD_DIFF_FILE = 'diff-file';
const FIELD_DIFF_CONTENT = 'diff-content';
const FIELD_REPOSITORY = 'repository';
const FIELD_RULE = 'rule';
const FIELD_AFFECTED_PACKAGE = 'affected-package';
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
abstract public function getPHID(); abstract public function getPHID();
abstract public function getHeraldName(); abstract public function getHeraldName();
abstract public function getHeraldTypeName(); abstract public function getHeraldTypeName();
@ -21,6 +35,26 @@ abstract class HeraldAdapter {
} }
abstract public function getAdapterContentName(); abstract public function getAdapterContentName();
abstract public function getFields();
public function getFieldNameMap() {
return array(
self::FIELD_TITLE => pht('Title'),
self::FIELD_BODY => pht('Body'),
self::FIELD_AUTHOR => pht('Author'),
self::FIELD_REVIEWER => pht('Reviewer'),
self::FIELD_REVIEWERS => pht('Reviewers'),
self::FIELD_CC => pht('CCs'),
self::FIELD_TAGS => pht('Tags'),
self::FIELD_DIFF_FILE => pht('Any changed filename'),
self::FIELD_DIFF_CONTENT => pht('Any changed file content'),
self::FIELD_REPOSITORY => pht('Repository'),
self::FIELD_RULE => pht('Another Herald rule'),
self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
self::FIELD_AFFECTED_PACKAGE_OWNER =>
pht("Any affected package's owner"),
);
}
public static function applyFlagEffect(HeraldEffect $effect, $phid) { public static function applyFlagEffect(HeraldEffect $effect, $phid) {
$color = $effect->getTarget(); $color = $effect->getTarget();
@ -82,6 +116,22 @@ abstract class HeraldAdapter {
return $adapters; return $adapters;
} }
public static function getAdapterForContentType($content_type) {
$adapters = self::getAllAdapters();
foreach ($adapters as $adapter) {
if ($adapter->getAdapterContentType() == $content_type) {
return $adapter;
}
}
throw new Exception(
pht(
'No adapter exists for Herald content type "%s".',
$content_type));
}
} }

View file

@ -2,6 +2,11 @@
final class HeraldCommitAdapter extends HeraldAdapter { final class HeraldCommitAdapter extends HeraldAdapter {
const FIELD_NEED_AUDIT_FOR_PACKAGE = 'need-audit-for-package';
const FIELD_DIFFERENTIAL_REVISION = 'differential-revision';
const FIELD_DIFFERENTIAL_REVIEWERS = 'differential-reviewers';
const FIELD_DIFFERENTIAL_CCS = 'differential-ccs';
protected $diff; protected $diff;
protected $revision; protected $revision;
@ -30,6 +35,34 @@ final class HeraldCommitAdapter extends HeraldAdapter {
return pht('Commits'); return pht('Commits');
} }
public function getFieldNameMap() {
return array(
self::FIELD_NEED_AUDIT_FOR_PACKAGE =>
pht('Affected packages that need audit'),
self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'),
self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'),
self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'),
) + parent::getFieldNameMap();
}
public function getFields() {
return array(
self::FIELD_BODY,
self::FIELD_AUTHOR,
self::FIELD_REVIEWER,
self::FIELD_REPOSITORY,
self::FIELD_DIFF_FILE,
self::FIELD_DIFF_CONTENT,
self::FIELD_RULE,
self::FIELD_AFFECTED_PACKAGE,
self::FIELD_AFFECTED_PACKAGE_OWNER,
self::FIELD_NEED_AUDIT_FOR_PACKAGE,
self::FIELD_DIFFERENTIAL_REVISION,
self::FIELD_DIFFERENTIAL_REVIEWERS,
self::FIELD_DIFFERENTIAL_CCS,
);
}
public static function newLegacyAdapter( public static function newLegacyAdapter(
PhabricatorRepository $repository, PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommit $commit,

View file

@ -30,6 +30,23 @@ final class HeraldDifferentialRevisionAdapter extends HeraldAdapter {
return pht('Differential Revisions'); return pht('Differential Revisions');
} }
public function getFields() {
return array(
self::FIELD_TITLE,
self::FIELD_BODY,
self::FIELD_AUTHOR,
self::FIELD_REVIEWERS,
self::FIELD_CC,
self::FIELD_REPOSITORY,
self::FIELD_DIFF_FILE,
self::FIELD_DIFF_CONTENT,
self::FIELD_RULE,
self::FIELD_AFFECTED_PACKAGE,
self::FIELD_AFFECTED_PACKAGE_OWNER,
);
}
public static function newLegacyAdapter( public static function newLegacyAdapter(
DifferentialRevision $revision, DifferentialRevision $revision,
DifferentialDiff $diff) { DifferentialDiff $diff) {

View file

@ -26,6 +26,10 @@ final class HeraldDryRunAdapter extends HeraldAdapter {
return null; return null;
} }
public function getFields() {
return array();
}
public function applyHeraldEffects(array $effects) { public function applyHeraldEffects(array $effects) {
assert_instances_of($effects, 'HeraldEffect'); assert_instances_of($effects, 'HeraldEffect');
$results = array(); $results = array();

View file

@ -61,7 +61,6 @@ final class HeraldConditionConfig {
case HeraldFieldConfig::FIELD_AUTHOR: case HeraldFieldConfig::FIELD_AUTHOR:
case HeraldFieldConfig::FIELD_REPOSITORY: case HeraldFieldConfig::FIELD_REPOSITORY:
case HeraldFieldConfig::FIELD_REVIEWER: case HeraldFieldConfig::FIELD_REVIEWER:
case HeraldFieldConfig::FIELD_MERGE_REQUESTER:
return array_select_keys( return array_select_keys(
$map, $map,
array( array(

View file

@ -2,6 +2,7 @@
final class HeraldFieldConfig { final class HeraldFieldConfig {
// TODO: Remove; still required by conditions, etc.
const FIELD_TITLE = 'title'; const FIELD_TITLE = 'title';
const FIELD_BODY = 'body'; const FIELD_BODY = 'body';
const FIELD_AUTHOR = 'author'; const FIELD_AUTHOR = 'author';
@ -19,8 +20,8 @@ final class HeraldFieldConfig {
const FIELD_DIFFERENTIAL_REVISION = 'differential-revision'; const FIELD_DIFFERENTIAL_REVISION = 'differential-revision';
const FIELD_DIFFERENTIAL_REVIEWERS = 'differential-reviewers'; const FIELD_DIFFERENTIAL_REVIEWERS = 'differential-reviewers';
const FIELD_DIFFERENTIAL_CCS = 'differential-ccs'; const FIELD_DIFFERENTIAL_CCS = 'differential-ccs';
const FIELD_MERGE_REQUESTER = 'merge-requester';
// TODO: Remove; still required by transcripts.
public static function getFieldMap() { public static function getFieldMap() {
$map = array( $map = array(
self::FIELD_TITLE => pht('Title'), self::FIELD_TITLE => pht('Title'),
@ -42,53 +43,9 @@ final class HeraldFieldConfig {
self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'), self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'),
self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'), self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'),
self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'), self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'),
self::FIELD_MERGE_REQUESTER => pht('Merge requester')
); );
return $map; return $map;
} }
public static function getFieldMapForContentType($type) {
$map = self::getFieldMap();
switch ($type) {
case HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL:
return array_select_keys(
$map,
array(
self::FIELD_TITLE,
self::FIELD_BODY,
self::FIELD_AUTHOR,
self::FIELD_REVIEWERS,
self::FIELD_CC,
self::FIELD_REPOSITORY,
self::FIELD_DIFF_FILE,
self::FIELD_DIFF_CONTENT,
self::FIELD_RULE,
self::FIELD_AFFECTED_PACKAGE,
self::FIELD_AFFECTED_PACKAGE_OWNER,
));
case HeraldContentTypeConfig::CONTENT_TYPE_COMMIT:
return array_select_keys(
$map,
array(
self::FIELD_BODY,
self::FIELD_AUTHOR,
self::FIELD_REVIEWER,
self::FIELD_REPOSITORY,
self::FIELD_DIFF_FILE,
self::FIELD_DIFF_CONTENT,
self::FIELD_RULE,
self::FIELD_AFFECTED_PACKAGE,
self::FIELD_AFFECTED_PACKAGE_OWNER,
self::FIELD_NEED_AUDIT_FOR_PACKAGE,
self::FIELD_DIFFERENTIAL_REVISION,
self::FIELD_DIFFERENTIAL_REVIEWERS,
self::FIELD_DIFFERENTIAL_CCS,
));
default:
throw new Exception("Unknown content type.");
}
}
} }

View file

@ -18,22 +18,24 @@ final class HeraldRuleController extends HeraldController {
$rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap();
if ($this->id) { if ($this->id) {
$rule = id(new HeraldRule())->load($this->id); $rule = id(new HeraldRuleQuery())
->setViewer($user)
->withIDs(array($this->id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$rule) { if (!$rule) {
return new Aphront404Response(); return new Aphront404Response();
} }
if (!$this->canEditRule($rule, $user)) {
throw new Exception("You don't own this rule and can't edit it.");
}
} else { } else {
$rule = new HeraldRule(); $rule = new HeraldRule();
$rule->setAuthorPHID($user->getPHID()); $rule->setAuthorPHID($user->getPHID());
$rule->setMustMatchAll(true); $rule->setMustMatchAll(true);
$content_type = $request->getStr('content_type'); $content_type = $request->getStr('content_type');
if (!isset($content_type_map[$content_type])) {
$content_type = HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL;
}
$rule->setContentType($content_type); $rule->setContentType($content_type);
$rule_type = $request->getStr('rule_type'); $rule_type = $request->getStr('rule_type');
@ -43,6 +45,8 @@ final class HeraldRuleController extends HeraldController {
$rule->setRuleType($rule_type); $rule->setRuleType($rule_type);
} }
$adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType());
$local_version = id(new HeraldRule())->getConfigVersion(); $local_version = id(new HeraldRule())->getConfigVersion();
if ($rule->getConfigVersion() > $local_version) { if ($rule->getConfigVersion() > $local_version) {
throw new Exception( throw new Exception(
@ -169,7 +173,7 @@ final class HeraldRuleController extends HeraldController {
->setValue(pht('Save Rule')) ->setValue(pht('Save Rule'))
->addCancelButton('/herald/view/'.$rule->getContentType().'/')); ->addCancelButton('/herald/view/'.$rule->getContentType().'/'));
$this->setupEditorBehavior($rule, $handles); $this->setupEditorBehavior($rule, $handles, $adapter);
$title = $rule->getID() $title = $rule->getID()
? pht('Edit Herald Rule') ? pht('Edit Herald Rule')
@ -194,13 +198,6 @@ final class HeraldRuleController extends HeraldController {
)); ));
} }
private function canEditRule($rule, $user) {
return
($user->getIsAdmin()) ||
($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) ||
($rule->getAuthorPHID() == $user->getPHID());
}
private function saveRule($rule, $request) { private function saveRule($rule, $request) {
$rule->setName($request->getStr('name')); $rule->setName($request->getStr('name'));
$rule->setMustMatchAll(($request->getStr('must_match') == 'all')); $rule->setMustMatchAll(($request->getStr('must_match') == 'all'));
@ -329,7 +326,11 @@ final class HeraldRuleController extends HeraldController {
return array($e_name, $errors); return array($e_name, $errors);
} }
private function setupEditorBehavior($rule, $handles) { private function setupEditorBehavior(
HeraldRule $rule,
array $handles,
HeraldAdapter $adapter) {
$serial_conditions = array( $serial_conditions = array(
array('default', 'default', ''), array('default', 'default', ''),
); );
@ -386,9 +387,11 @@ final class HeraldRuleController extends HeraldController {
$all_rules = mpull($all_rules, 'getName', 'getID'); $all_rules = mpull($all_rules, 'getName', 'getID');
asort($all_rules); asort($all_rules);
$fields = $adapter->getFields();
$field_map = array_select_keys($adapter->getFieldNameMap(), $fields);
$config_info = array(); $config_info = array();
$config_info['fields'] $config_info['fields'] = $field_map;
= HeraldFieldConfig::getFieldMapForContentType($rule->getContentType());
$config_info['conditions'] = HeraldConditionConfig::getConditionMap(); $config_info['conditions'] = HeraldConditionConfig::getConditionMap();
foreach ($config_info['fields'] as $field => $name) { foreach ($config_info['fields'] as $field => $name) {
$config_info['conditionMap'][$field] = array_keys( $config_info['conditionMap'][$field] = array_keys(

View file

@ -446,7 +446,6 @@ final class HeraldEngine {
break; break;
case HeraldFieldConfig::FIELD_AUTHOR: case HeraldFieldConfig::FIELD_AUTHOR:
case HeraldFieldConfig::FIELD_REPOSITORY: case HeraldFieldConfig::FIELD_REPOSITORY:
case HeraldFieldConfig::FIELD_MERGE_REQUESTER:
// TODO: Type should be PHID. // TODO: Type should be PHID.
$result = $this->object->getHeraldField($field); $result = $this->object->getHeraldField($field);
break; break;