mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
156b156e77
Summary: Ref T7803. Ref T5873. I want to drive Conduit through more shared infrastructure, but can't currently add parameters automatically. Put a `getX()` around the `defineX()` methods so the parent can provide default behaviors. Also like 60% of methods don't define any special error types; don't require them to implement this method. I want to move away from this in general. Test Plan: - Ran `arc unit --everything`. - Called `conduit.query`. - Browsed Conduit UI. Reviewers: btrahan Reviewed By: btrahan Subscribers: hach-que, epriestley Maniphest Tasks: T5873, T7803 Differential Revision: https://secure.phabricator.com/D12380
142 lines
4 KiB
PHP
142 lines
4 KiB
PHP
<?php
|
|
|
|
final class DifferentialParseCommitMessageConduitAPIMethod
|
|
extends DifferentialConduitAPIMethod {
|
|
|
|
private $errors;
|
|
|
|
public function getAPIMethodName() {
|
|
return 'differential.parsecommitmessage';
|
|
}
|
|
|
|
public function getMethodDescription() {
|
|
return pht('Parse commit messages for Differential fields.');
|
|
}
|
|
|
|
protected function defineParamTypes() {
|
|
return array(
|
|
'corpus' => 'required string',
|
|
'partial' => 'optional bool',
|
|
);
|
|
}
|
|
|
|
protected function defineReturnType() {
|
|
return 'nonempty dict';
|
|
}
|
|
|
|
protected function execute(ConduitAPIRequest $request) {
|
|
$viewer = $request->getUser();
|
|
$corpus = $request->getValue('corpus');
|
|
$is_partial = $request->getValue('partial');
|
|
|
|
$revision = new DifferentialRevision();
|
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
|
$revision,
|
|
DifferentialCustomField::ROLE_COMMITMESSAGE);
|
|
$field_list->setViewer($viewer);
|
|
$field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit');
|
|
|
|
$this->errors = array();
|
|
|
|
$label_map = $this->buildLabelMap($field_list);
|
|
$corpus_map = $this->parseCommitMessage($corpus, $label_map);
|
|
|
|
$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) {
|
|
foreach ($field_map as $key => $field) {
|
|
try {
|
|
$field->validateCommitMessageValue(idx($values, $key));
|
|
} 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...
|
|
$revision_id_field = new DifferentialRevisionIDField();
|
|
$revision_id_value = idx(
|
|
$corpus_map,
|
|
$revision_id_field->getFieldKeyForConduit());
|
|
$revision_id_valid_domain = PhabricatorEnv::getProductionURI('');
|
|
|
|
return array(
|
|
'errors' => $this->errors,
|
|
'fields' => $values,
|
|
'revisionIDFieldInfo' => array(
|
|
'value' => $revision_id_value,
|
|
'validDomain' => $revision_id_valid_domain,
|
|
),
|
|
);
|
|
}
|
|
|
|
private function buildLabelMap(PhabricatorCustomFieldList $field_list) {
|
|
$label_map = array();
|
|
|
|
foreach ($field_list->getFields() as $key => $field) {
|
|
$labels = $field->getCommitMessageLabels();
|
|
$key = $field->getFieldKeyForConduit();
|
|
|
|
foreach ($labels as $label) {
|
|
$normal_label = DifferentialCommitMessageParser::normalizeFieldLabel(
|
|
$label);
|
|
if (!empty($label_map[$normal_label])) {
|
|
throw new Exception(
|
|
pht(
|
|
'Field label "%s" is parsed by two custom fields: "%s" and '.
|
|
'"%s". Each label must be parsed by only one field.',
|
|
$label,
|
|
$key,
|
|
$label_map[$normal_label]));
|
|
}
|
|
$label_map[$normal_label] = $key;
|
|
}
|
|
}
|
|
|
|
return $label_map;
|
|
}
|
|
|
|
|
|
private function parseCommitMessage($corpus, array $label_map) {
|
|
$key_title = id(new DifferentialTitleField())->getFieldKeyForConduit();
|
|
$key_summary = id(new DifferentialSummaryField())->getFieldKeyForConduit();
|
|
|
|
$parser = id(new DifferentialCommitMessageParser())
|
|
->setLabelMap($label_map)
|
|
->setTitleKey($key_title)
|
|
->setSummaryKey($key_summary);
|
|
|
|
$result = $parser->parseCorpus($corpus);
|
|
|
|
foreach ($parser->getErrors() as $error) {
|
|
$this->errors[] = $error;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
}
|