mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 05:12:41 +01:00
Separate commit message parsing and validation from Conduit
Summary: Ref T11114. I want to move this step away from custom fields. To start with, isolate all the parsing in one class with a clearer API boundary. Next, I'll make this class use new field objects to perform parsing, without CustomField interactions. Test Plan: Created and edited revisions from the CLI, using valid and invalid commit messages. Reviewers: chad Reviewed By: chad Maniphest Tasks: T11114 Differential Revision: https://secure.phabricator.com/D17055
This commit is contained in:
parent
3d8d98bd8d
commit
552c546689
2 changed files with 107 additions and 62 deletions
|
@ -3,8 +3,6 @@
|
||||||
final class DifferentialParseCommitMessageConduitAPIMethod
|
final class DifferentialParseCommitMessageConduitAPIMethod
|
||||||
extends DifferentialConduitAPIMethod {
|
extends DifferentialConduitAPIMethod {
|
||||||
|
|
||||||
private $errors;
|
|
||||||
|
|
||||||
public function getAPIMethodName() {
|
public function getAPIMethodName() {
|
||||||
return 'differential.parsecommitmessage';
|
return 'differential.parsecommitmessage';
|
||||||
}
|
}
|
||||||
|
@ -25,63 +23,30 @@ final class DifferentialParseCommitMessageConduitAPIMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(ConduitAPIRequest $request) {
|
protected function execute(ConduitAPIRequest $request) {
|
||||||
$viewer = $request->getUser();
|
$viewer = $this->getViewer();
|
||||||
$corpus = $request->getValue('corpus');
|
|
||||||
|
$parser = DifferentialCommitMessageParser::newStandardParser($viewer);
|
||||||
|
|
||||||
$is_partial = $request->getValue('partial');
|
$is_partial = $request->getValue('partial');
|
||||||
|
if ($is_partial) {
|
||||||
$field_list = PhabricatorCustomField::getObjectFields(
|
$parser->setRaiseMissingFieldErrors(false);
|
||||||
new DifferentialRevision(),
|
|
||||||
DifferentialCustomField::ROLE_COMMITMESSAGE);
|
|
||||||
$field_list->setViewer($viewer);
|
|
||||||
$field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
|
|
||||||
|
|
||||||
$corpus_map = $this->parseCommitMessage($corpus);
|
|
||||||
|
|
||||||
$values = array();
|
|
||||||
foreach ($corpus_map as $field_key => $text_value) {
|
|
||||||
$field = idx($field_map, $field_key);
|
|
||||||
|
|
||||||
if (!$field) {
|
|
||||||
throw new Exception(
|
|
||||||
pht(
|
|
||||||
'Parser emitted text value for field key "%s", but no such '.
|
|
||||||
'field exists.',
|
|
||||||
$field_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$values[$field_key] = $field->parseValueFromCommitMessage($text_value);
|
|
||||||
} catch (DifferentialFieldParseException $ex) {
|
|
||||||
$this->errors[] = pht(
|
|
||||||
'Error parsing field "%s": %s',
|
|
||||||
$field->renderCommitMessageLabel(),
|
|
||||||
$ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$is_partial) {
|
$corpus = $request->getValue('corpus');
|
||||||
foreach ($field_map as $key => $field) {
|
$field_map = $parser->parseFields($corpus);
|
||||||
try {
|
|
||||||
$field->validateCommitMessageValue(idx($values, $key));
|
$errors = $parser->getErrors();
|
||||||
} catch (DifferentialFieldValidationException $ex) {
|
|
||||||
$this->errors[] = pht(
|
|
||||||
'Invalid or missing field "%s": %s',
|
|
||||||
$field->renderCommitMessageLabel(),
|
|
||||||
$ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// grab some extra information about the Differential Revision: field...
|
// grab some extra information about the Differential Revision: field...
|
||||||
$revision_id_field = new DifferentialRevisionIDField();
|
$revision_id_field = new DifferentialRevisionIDField();
|
||||||
$revision_id_value = idx(
|
$revision_id_value = idx(
|
||||||
$corpus_map,
|
$field_map,
|
||||||
$revision_id_field->getFieldKeyForConduit());
|
$revision_id_field->getFieldKeyForConduit());
|
||||||
$revision_id_valid_domain = PhabricatorEnv::getProductionURI('');
|
$revision_id_valid_domain = PhabricatorEnv::getProductionURI('');
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'errors' => $this->errors,
|
'errors' => $errors,
|
||||||
'fields' => $values,
|
'fields' => $field_map,
|
||||||
'revisionIDFieldInfo' => array(
|
'revisionIDFieldInfo' => array(
|
||||||
'value' => $revision_id_value,
|
'value' => $revision_id_value,
|
||||||
'validDomain' => $revision_id_valid_domain,
|
'validDomain' => $revision_id_valid_domain,
|
||||||
|
@ -89,17 +54,4 @@ final class DifferentialParseCommitMessageConduitAPIMethod
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseCommitMessage($corpus) {
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$parser = DifferentialCommitMessageParser::newStandardParser($viewer);
|
|
||||||
$result = $parser->parseCorpus($corpus);
|
|
||||||
|
|
||||||
$this->errors = array();
|
|
||||||
foreach ($parser->getErrors() as $error) {
|
|
||||||
$this->errors[] = $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,12 @@
|
||||||
*/
|
*/
|
||||||
final class DifferentialCommitMessageParser extends Phobject {
|
final class DifferentialCommitMessageParser extends Phobject {
|
||||||
|
|
||||||
|
private $viewer;
|
||||||
private $labelMap;
|
private $labelMap;
|
||||||
private $titleKey;
|
private $titleKey;
|
||||||
private $summaryKey;
|
private $summaryKey;
|
||||||
private $errors;
|
private $errors;
|
||||||
|
private $raiseMissingFieldErrors = true;
|
||||||
|
|
||||||
public static function newStandardParser(PhabricatorUser $viewer) {
|
public static function newStandardParser(PhabricatorUser $viewer) {
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ final class DifferentialCommitMessageParser extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
return id(new self())
|
return id(new self())
|
||||||
|
->setViewer($viewer)
|
||||||
->setLabelMap($label_map)
|
->setLabelMap($label_map)
|
||||||
->setTitleKey($key_title)
|
->setTitleKey($key_title)
|
||||||
->setSummaryKey($key_summary);
|
->setSummaryKey($key_summary);
|
||||||
|
@ -69,6 +71,40 @@ final class DifferentialCommitMessageParser extends Phobject {
|
||||||
/* -( Configuring the Parser )--------------------------------------------- */
|
/* -( Configuring the Parser )--------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->viewer = $viewer;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function getViewer() {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function setRaiseMissingFieldErrors($raise) {
|
||||||
|
$this->raiseMissingFieldErrors = $raise;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function getRaiseMissingFieldErrors() {
|
||||||
|
return $this->raiseMissingFieldErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @task config
|
* @task config
|
||||||
*/
|
*/
|
||||||
|
@ -215,6 +251,63 @@ final class DifferentialCommitMessageParser extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task parse
|
||||||
|
*/
|
||||||
|
public function parseFields($corpus) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$text_map = $this->parseCorpus($corpus);
|
||||||
|
|
||||||
|
$field_list = PhabricatorCustomField::getObjectFields(
|
||||||
|
new DifferentialRevision(),
|
||||||
|
DifferentialCustomField::ROLE_COMMITMESSAGE);
|
||||||
|
$field_list->setViewer($viewer);
|
||||||
|
|
||||||
|
$field_map = $field_list->getFields();
|
||||||
|
$field_map = mpull($field_map, null, 'getFieldKeyForConduit');
|
||||||
|
|
||||||
|
$result_map = array();
|
||||||
|
foreach ($text_map as $field_key => $text_value) {
|
||||||
|
$field = idx($field_map, $field_key);
|
||||||
|
if (!$field) {
|
||||||
|
// This is a strict error, since we only parse fields which we have
|
||||||
|
// been told are valid. The caller probably handed us an invalid label
|
||||||
|
// map.
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Parser emitted a field with key "%s", but no corresponding '.
|
||||||
|
'field definition exists.',
|
||||||
|
$field_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $field->parseValueFromCommitMessage($text_value);
|
||||||
|
$result_map[$field_key] = $result;
|
||||||
|
} catch (DifferentialFieldParseException $ex) {
|
||||||
|
$this->errors[] = pht(
|
||||||
|
'Error parsing field "%s": %s',
|
||||||
|
$field->renderCommitMessageLabel(),
|
||||||
|
$ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getRaiseMissingFieldErrors()) {
|
||||||
|
foreach ($field_map as $key => $field) {
|
||||||
|
try {
|
||||||
|
$field->validateCommitMessageValue(idx($result_map, $key));
|
||||||
|
} catch (DifferentialFieldValidationException $ex) {
|
||||||
|
$this->errors[] = pht(
|
||||||
|
'Invalid or missing field "%s": %s',
|
||||||
|
$field->renderCommitMessageLabel(),
|
||||||
|
$ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @task parse
|
* @task parse
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue